<!DOCTYPE html>
<html lang='en' class='h-100'>
<head>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="smS7ZMADAEokgBW1sVPKXXjg7X68V2OV_gVynEzvxGY54zj3juox_xhln9Ol-SiRB6Ms5SFT4lZGI4wz4yEnuQ" />
  <meta name="csp-nonce" />
  <title>3D Vision and Surround Technology | NVIDIA Developer</title>
<link rel="canonical" href="https://developer.nvidia.com/3d-vision-and-surround-technology">
<link rel="alternate" href="https://developer.nvidia.com/3d-vision-and-surround-technology" hreflang="x-default">
<link rel="alternate" href="https://developer.nvidia.com/3d-vision-and-surround-technology" hreflang="en-us">
<meta property="og:site_name" content="NVIDIA Developer">
<meta property="og:title" content="3D Vision and Surround Technology">
<meta property="og:type" content="website">
<meta property="og:image" content="https://developer.download.nvidia.com/images/og-default.jpg">
<meta property="og:url" content="https://developer.nvidia.com/3d-vision-and-surround-technology">
<meta name="twitter:title" content="3D Vision and Surround Technology">
<meta name="twitter:image" content="https://developer.download.nvidia.com/images/og-default.jpg">
<meta name="twitter:site" content="@NVIDIA">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:creator" content="@NVIDIA">

  <link rel="stylesheet" href="https://developer.nvidia.com/assets/application-d32c2ddd91a26a408b2c591a1c07f9f6cbaf157e18ac95c2c37ceeabc61c60a1.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/shared/modal-b27162ea9a12461a0b0076440408cdd94ddf4273a6a89539e4b81f4641416436.css" media="all" />
  
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/one-trust-bea625cf16a072ce5fdb0707a19f2645daf63c05eb1a016db72773eba008fc07.css" />
  <script src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js" charset="UTF-8" data-document-language="true" data-domain-script="3e2b62ff-7ae7-4ac5-87c8-d5949ecafff5"></script>

<script src="https://images.nvidia.com/aem-dam/Solutions/ot-js/ot-custom.js"></script>

<script>
  function OptanonWrapper() {
    let event = new Event('bannerLoaded');
    window.dispatchEvent(event);

      if (window.OnetrustActiveGroups && window.OnetrustActiveGroups.includes("C0002")) {
        window.DD_RUM && window.DD_RUM.init({
          clientToken: 'pub0430c74fae5d2b467bcb8d48b13e5b32',
          applicationId: '9fc963c7-14e6-403d-bdec-ee671550bb7f',
          site: 'datadoghq.com',
          service: 'devzone',
          env: 'prod',
          version: 'v2.60.0',
          sessionSampleRate: 10,
          sessionReplaySampleRate: 5,
          trackUserInteractions: true,
          trackResources: true,
          trackLongTasks: true,
          defaultPrivacyLevel: 'mask-user-input',
        });
      }
  }
</script>


  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "NVIDIA Developer",
    "url": "https://developer.nvidia.com",
    "logo": "https://www.nvidia.com/en-us/about-nvidia/legal-info/logo-brand-usage/_jcr_content/root/responsivegrid/nv_container_392921705/nv_container_412055486/nv_image.coreimg.100.630.png/1703060329095/nvidia-logo-horz.png",
    "sameAs": [
      "https://github.com/nvidia",
      "https://www.linkedin.com/company/nvidia/",
      "https://x.com/nvidiadeveloper"
    ]
  }
</script>

    <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/vars-cd3a0769a3c2f2d9ea6b83ac53ce86bceef4c719e4dbd22ed41d48d01f200901.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/fonts-910bdb814ac830981904d69eea803431bc3a5b00aac30ffc85d12983c6511741.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/ballistiq-twitterfeed-61a757e5494e5598582c3610822f4cc0d00c0f1c3d70d478b0004dcebebf2368.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/application-a780279f5932e2d3fe01da14ba98d5c320956ec365747dfca2719798ce778ae6.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/embedded/embedded-bde5659f6ab1dd4f9edcf851e8c12fb3c44ed2de1542a3bd9131d207afdb0d7d.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/overrides-cbc02aeca05448d7c77b2b63dc1faa3f5e58c17afd5afe4a5122591949c5d734.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/new-styles-858f40f346fa03922adaed5fa12e81a783dff52699f02bed72f561c6642b1987.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/feed-aggregator/feed-aggregator-9ace7521871242143cb35fa86d5be702c4dacb409600041fa6a5b14fa2a71dde.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/devzone3/old/bootstrap-glyphicons-fe132ea5867b21620f37b392a53d872fb240e34ad8b477db370b6f867ccd102f.css" media="all" />

  <script src="https://developer.nvidia.com/assets/horizontal-chart/d3.v4.min-41cfecdf7c41476e805de7afacf4aacdd1a4be6947fbecf95217e947ebc2faf5.js"></script>
  <script src="https://developer.nvidia.com/assets/horizontal-chart/visualize-d-16cf14d4b63d6031e6c18983e91ac6d2b1b1f8140d15e351a9c847f8610b7e5b.js"></script>
  <script src="https://developer.nvidia.com/assets/devzone3/old/js.cookie.min-bd09df6e81cb21935c4e92d9631a162285611f17c6eaee720cafcc6ddef3f7dc.js"></script>
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/sf-validation/sf-validation-805362e079494cd052f713be5f91a44eb602f545c342f794abbd4a8050c0acb3.css" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/tablefilter/tablefilter-ad35ad42b6d4f1068765cf691a0dcb4214ba7925ea4e28b9a1ce48a0ddb3d489.css" media="all" />
  <link rel="stylesheet" href="https://developer.nvidia.com/assets/tablefilter/filtered-table-891467932064f1f3e379852c0697e014d6c0f99a6d423b4468e55ae59d159adf.css" media="all" />

  <script src="https://assets.adobedtm.com/5d4962a43b79/c1061d2c5e7b/launch-191c2462b890.min.js" data-ot-ignore="true"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    <script src="https://api-prod.nvidia.com/search/nvidia-gallery-widget.js"></script>

<script src="https://developer.nvidia.com/assets/devzone3/modules/nvidia_editor/nod_widgets-8c38a7d04ed3c3acd9117aa126bf76d7902d3c57c72b76dbf3c281c96ed09975.js"></script>


  <link rel="icon" type="image/x-icon" href="https://developer.nvidia.com/assets/favicon-81bff16cada05fcff11e5711f7e6212bdc2e0a32ee57cd640a8cf66c87a6cbe6.ico" />
</head>

<body class='d-flex flex-column h-100' data-theme='devzone3_old'>

<div id='header'></div>







  

<div id="wrapper" class="page-3d-vision-and-surround-technology" data-id="281">
  <div id="content-background" class="">
    <div class="separator"></div>
    <div id="content" class="container">
      <div class="row">
        <section class="dz3-main-section dz-old-theme node field-name-body">
          <a id="main-content"></a>
          <div class='page-header'><h1 class='title'>3D Vision and Surround Technology</h1></div> <b><i>Note: This is a legacy SDK. Developers may download and continue to use, but it is no longer supported.</i></b>
<br>
<br>
<p class="lead">
Imagine immersing yourself in the world of 3D content like never before. Monsters, bullets, and landscapes jump out of your flat monitor and into your imagination, making you part of the game. With <a href="http://www.nvidia.com/object/3D_Vision_Main.html">NVIDIA® 3D Vision</a>, gaming will never be the same.
</p>

<p>
2011 is a big year for 3D entertainment, with blockbuster 3D film releases, brand new 3D HDTVs, and expanding the 3D Vision technologies that make stereoscopic 3D for home users an inexpensive and high-quality option.
</p>

<p>
What surprises most game developers is just how little they may have to do to fully 3D in the games they are making.   In fact, many shipping games that were never originally written for stereo <em>already look great in 3D</em> with 3D Vision.  Just check out <a href="http://www.nvidia.com/object/GeForce_3D_Vision_3D_Games.html">our latest list of supported games</a>!
</p>

<p>
Lots of games need no modification, but there are simple things that developers can do to make the experience really fantastic  -  and a few stumbling blocks that developers can avoid to ensure that their game plays well.
</p>

<h3>How Does It Work?</h3>

<p>
The NVIDIA 3D Vision products supports the leading 3D products available on the market, including 120Hz desktop LCD monitors, 3D projectors, and DLP HDTVs (<a href="http://www.nvidia.com/object/3D_Vision_Requirements.html">complete list of supported displays</a>).  The NVIDIA 3D Vision driver can process any game to support all of these displays, so specifics of the display are isolated from the application and game developers don't need to worry about the details. <strong>The 3D Vision driver architecture even supports HDMI 1.4 3D TVs using NVIDIA 3DTV Play software.</strong>
</p>


<p>
Inside the driver, each 3D scene gets rendered twice  -  once for the left eye, and once for the right eye. The driver is able to automatically modify typical 3D game vertex shaders “in flight” so that it can generate the correct images at run time. User options allow players to adjust settings like inter-ocular distance (that is, the amount of “depth”) to their own preference. Developers can explicitly control the stereo aspects of the experience, or just let the driver do its job.
</p>


<p>
For the best experience, of course, there are a few simple steps that a developer can take to ensure that their game plays its best with 3D Vision, including making sure that player HUD elements are displayed at screen depth, that UI's like crosshair reticules show in depth correctly (screen reticules can be confusing, but laser sights look *incredible* in 3D, as do projectile ballistics!), and that render-to-texture passes follow a few simple rules (that most developers already follow without realizing it).
</p>


<p>
With a little more effort, developers can take the reins to control their own 3D stereo experiences, altering subtle player-attention controls like dynamic convergence or adding startling out-of-the-screen special effects.
</p>

<h3>Developer Resources for NVIDIA 3D Vision Technology</h3>

<ul>
  <li>
<a href="http://developer.download.nvidia.com/whitepapers/2010/3D_Vision_Best_Practices_Guide.pdf">NVIDIA 3D Vision Automatic Best Practices</a>. (Updated, Sept 2011)</li>
  <li>
<a href="http://developer.download.nvidia.com/whitepapers/2011/StereoUnproject.pdf">Stereo Unprojection</a> *New*</li>
      This document exposes the technical problems faced in stereo with NVIDIA driver automatic mode when the fragment position must be unprojected in mono space in the pixel shader.
    <ul>
      <li>
<a href="http://developer.download.nvidia.com/whitepapers/2011/StereoUnproject.zip">Stereo Unprojection Sample</a>. *New*</li>
    </ul>

  <li>Developer Conferences Presentations
    <ul>
      <li>GDC 2008 - <a href="http://developer.download.nvidia.com/presentations/2008/GDC/slides-nvidia_fluid_sim_198.mov">Video</a> (second half of this twin-talk) and <a href="http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_stereo-web.pdf">Presentation</a>
</li>
      <li>GDC 2009 - <a href="http://developer.download.nvidia.com/presentations/2009/GDC/GDC09-3DVision-The_In_and_Out.pdf">Presentation</a>
</li>
      <li>GTC 2010 - <a href="http://www.nvidia.com/content/GTC-2010/pdfs/2010_GTC2010.pdf">Implementing Stereoscopic 3D in Your Applications</a>
</li>
    </ul>
</li>
</ul>


<h3>NVIDIA Surround Technology</h3>


<p>
Imagine expanding your gaming real estate across three displays in Full HD 3D for a completely immersive gaming experience with <a href="http://www.nvidia.com/object/3d-vision-surround-technology.html">NVIDIA Surround technology</a>. With the introduction of NVIDIA GeForce GTX 400 GPUs, you can now use the award winning NVIDIA 3D Vision to build the world's first multi-display 3D gaming experience on your PC.
</p>



<p>
NVIDIA Surround technology supports both 2D and <a href="http://www.nvidia.com/object/3D_Vision_Main.html">3D Vision</a> modes, allowing end users to take advantage of wider field of views.
</p>

<h3>Developer Resources for NVIDIA Surround Technology</h3>

<ul>
  <li><a href="http://www.nvidia.com/object/3dv-system-requirements-surround-technology.html">Surround System Information</a></li>
  <li><a href="http://developer.download.nvidia.com/whitepapers/2010/SurroundBestPracticesGuide.pdf">Surround Best Practices</a></li>
  <li><a href="http://nvidia.custhelp.com/cgi-bin/nvidia.cfg/php/enduser/std_alp.php?p_sid=732*Y43k&amp;p_lva=&amp;p_li=&amp;p_accessibility=0&amp;p_redirect=&amp;p_page=1&amp;p_cv=&amp;p_pv=1.132&amp;p_prods=132&amp;p_cats=0&amp;p_hidden_prods=&amp;prod_lvl1=132&amp;cat_lvl1=0&amp;p_search_text=surround&amp;srch_btn_submit=%C2%A0%C2%A0%C2%A0Search%C2%A0%C2%A0%C2%A0&amp;p_new_search=1&amp;p_search_type=answers.search_nl">Frequently Asked Questions</a></li>
</ul>

        </section>
        <aside id="right" class="" role="complementary">
        </aside>  <!-- /#sidebar-second -->
      </div>
    </div>
    <div class="separator"></div>
  </div>

  <div class="white-background">
    <div class="separator"></div>
    <div class="container">
      <div class="row">
        <div id="pre_footer_left" class="col-xs-12 col-sm-12 col-lg-6">
        </div>
        <div id="pre_footer_right" class="col-xs-12 col-sm-12 col-lg-6">
        </div>
      </div>
      <div class="separator"></div>
    </div>
  </div>
</div>




<div id='footer' class='mt-auto'></div>

  <script src="https://developer.nvidia.com/assets/feed-aggregator/feed-aggregator-7f147443abc2d1300a239c29e4ba3ca0d0d2eb0dc66b608765e2b3be50e18e10.js"></script>

    <script src="https://developer.nvidia.com/assets/devzone3/old/dist/dz3-old-bundle-ed61b6a81d7c675ba7c54a1fe5dcfb2a960f17c5509388a7300f48a98f8dc751.js"></script>

  <script>
  const template = document.createElement('template');
  template.innerHTML = `
<style>
@import "https://developer.nvidia.com/assets/feed-aggregator/feed-aggregator-9ace7521871242143cb35fa86d5be702c4dacb409600041fa6a5b14fa2a71dde.css";
.feed-aggregator-component .card {
  box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.3) !important;
}
.feed-aggregator-component .card:hover {
  box-shadow: 0 0 8px 0 rgba(0,0,0,0.13), 0 14px 32px 5px rgba(0,0,0,0.13) !important;
}
</style>
<div class="feed-aggregator-component"></div>
`;
  const hosts = {
    'en': 'https://developer.nvidia.com/blog',
    'cn': 'https://developer.nvidia.com/zh-cn/blog',
  }

  class FeedAggregatorElement extends HTMLElement {
    constructor() {
      super();
      this._shadowRoot = this.attachShadow({ 'mode': 'open' });
      this._shadowRoot.appendChild(template.content.cloneNode(true));
    }

    connectedCallback() {
      const categories = this.getAttribute('categories');
      const tags = this.getAttribute('tags');
      const perPage = this.getAttribute('per-page');
      const excludedTags = this.getAttribute('excluded-tags');

      let locale = this.getAttribute('locale');
      if (!locale) {
        locale = 'en';
      }
      let targetElement = this._shadowRoot.querySelector(".feed-aggregator-component");
      let feed = {
        id: 'blog',
        host: hosts[locale],
        type: 'json',
        minCount: 2,
      };
      if (categories && categories !== 'all') {
        feed['category_ids'] = categories.split(',');
      }
      if (tags && tags !== 'all') {
        feed['tag_ids'] = tags.split(',');
      }
      if(excludedTags && excludedTags !== 'null'){
        feed['excluded_tag_ids'] = excludedTags.split(',');
      }
      document.addEventListener("DOMContentLoaded", function () {
        new FeedAggregator({
          target: targetElement,
          props: {
            count: perPage,
            openInNewTab: true,
            showExcerpts: true,
            feeds: [feed]
          }
        });
      })
    }
  }

  window.customElements.define('feed-aggregator', FeedAggregatorElement);
</script>


<template id='application-button-template'>
  <style>
      @import "https://developer.nvidia.com/assets/application-button/application-button-68ca7e1e3aa49ec79169d49226e34ee0c341d27a15a38b28ce975cb2467e123e.css";
  </style>
  <a href='' class='nvidia-application-button'>Join now</a>
</template>

<script>
  async function fetchMembershipState () {
    const userInfo = await fetch('/api/user');
    const {status} = userInfo;
    if (status === 401) {
      let error = new Error('Unauthorized');
      error.statusCode = status;
      throw error;
    }

    // TODO: Figure out how to get DZ4 program

    // Fetch page info.
    const {pathname} = location;
    const pageInfo = await fetch(`${pathname}.json`);
    const pageData = await pageInfo.json();

    // Fetch membership info
    return pageData;
  }

  const initApplicationButton = (element) => {
    const linkElement = element.querySelector('a');
    fetchMembershipState()
      .then(data => {
        console.log(data);
      })
      .catch(error => {
        switch (error.statusCode) {
          default:
            linkElement.innerHTML = 'Login';
            linkElement.href = '/login';
        }
      });
  };

  class NvidiaApplicationButton extends HTMLElement {
    constructor() {
      const template = document.getElementById('application-button-template');
      super();
      this._shadowRoot = this.attachShadow({ 'mode': 'open' });
      this._shadowRoot.appendChild(template.content.cloneNode(true));
    }
    connectedCallback() {
      const element = this._shadowRoot;
      document.addEventListener('DOMContentLoaded', () => {
        initApplicationButton(element);
      });
    }
  }
  window.customElements.define('nv-application-button', NvidiaApplicationButton);
</script>

<template id='application-text-template'>
  <p></p>
</template>

<script>
  class NvidiaApplicationText extends HTMLElement {
    constructor() {
      const template = document.getElementById('application-text-template');
      super();
      this._shadowRoot = this.attachShadow({ 'mode': 'open' });
      this._shadowRoot.appendChild(template.content.cloneNode(true));
    }
    connectedCallback() {

    }
  }
  window.customElements.define('nv-application-text', NvidiaApplicationText);
</script>




<template id='nv-sf-form-validator-template'>
  <script src="https://developer.nvidia.com/assets/sf-validation/moment-620a5949fff0ad37198f07464b91d7b7c110ecdb6f94ca90ca7d2e1b471f1da8.js"></script>
  <script src="https://developer.nvidia.com/assets/sf-validation/validate.min-2160a65c1b5d4a5966544ad25af8fe99f11c636a99c516fee6c7afd3b1f21409.js"></script>
  <p></p>
</template>

<script>
  class NvidiaSalesforceValidator extends HTMLElement {
    constructor() {
      const template = document.getElementById('nv-sf-form-validator-template');
      super();
      this._shadowRoot = this.attachShadow({'mode': 'open'});
      this._shadowRoot.appendChild(template.content.cloneNode(true));
    }

    initComponent() {
      if (!window.sfv) {
        return;
      }
      validate.extend(validate.validators.datetime, {
        parse: function (value, options) {
          if (moment(value, options.format, true).isValid()) {
            return +moment.utc(value);
          }
        },
        format: function (value, options) {
          var format = options.dateOnly ? "MM/DD/YYYY" : "MM/DD/YYYY hh:mm";
          return moment.utc(value).format(format);
        }
      });

      function showErrors(errors) {
        $.each(errors, function (index, element) {
          $('input[name="' + errors[index]['attribute'] + '"]').each(function (i, e) {
            var errorMessage = errors[index]['options']['message'];
            $('<div class="js-validation-errors">' + errorMessage + '</div>').insertAfter(e);
          }).focus();
        });
      }

      function isValidForm(form, constraints) {
        var errors = validate(form, constraints, {format: "detailed"});
        if (errors) {
          showErrors(errors);
          return false;
        }
        return true;
      }

      $.each(window.sfv, function (index, element) {
        $(element.target).on('click', function (event) {
          $('.js-validation-errors').remove();
          if (!isValidForm(element.form, element.constraints)) {
            event.preventDefault();
          }
        });
      });
    }

    connectedCallback() {
      document.addEventListener('DOMContentLoaded', () => {
        this.initComponent();
      });
    }
  }

  window.customElements.define('nv-sf-form-validator', NvidiaSalesforceValidator);
</script>


<script src="https://developer.nvidia.com/assets/horizontal-chart/d3.v4.min-41cfecdf7c41476e805de7afacf4aacdd1a4be6947fbecf95217e947ebc2faf5.js"></script>
<script src="https://developer.nvidia.com/assets/horizontal-chart/visualize-d-16cf14d4b63d6031e6c18983e91ac6d2b1b1f8140d15e351a9c847f8610b7e5b.js"></script>

<template id="chart-template">
  <style>
      @import "https://developer.nvidia.com/assets/devzone3/modules/nvidia_tokens/nvidia-charts-6cd359a7ee3970fbfc15904a87ff96d214c208297870d8db7f6a5fa2c449bea7.css";
  </style>
  <div class="horizontal-chart-component">
    <div class="chart-container">
      <h4 class="chart-title"></h4>
      <p class="chart-subtitle"></p>
      <div class="legend"></div>
      <svg data-nvidia-chart="true" data-chart-legend=""></svg>
      <p class="chart-footnote"></p>
    </div>
  </div>
</template>

<script>
  function chartInit(element) {
    const chart = element.querySelector('svg[data-nvidia-chart]');
    const isRendered = chart.getAttribute("data-rendered");
    if (isRendered) {
      return;
    }

    const svgChart = d3.select(chart);
    const bars = JSON.parse(chart.dataset['chartBars']);
    const ticks = JSON.parse(chart.dataset['chartTicks']);
    const xAxisLabel = chart.dataset['xAxisLabel'];
    const yAxisLabel = chart.dataset['yAxisLabel'];
    const barPadding = chart.dataset['barPadding'];
    const milestone = null;

    const isGrouped = chart.dataset['isGrouped'] === 'true';
    if (isGrouped) {
      const legend = JSON.parse(chart.dataset['chartLegend']);
      createGroupedHorizontalBarChart(svgChart, bars, barPadding, legend, ticks, milestone, xAxisLabel, yAxisLabel, false);
    } else {
      createHorizontalBarChart(svgChart, bars, barPadding, ticks, xAxisLabel, yAxisLabel, "", false);
    }

    chart.dataset['rendered'] = 'true';
  }

  $('a[data-toggle="tab"]').on("click", function (event) {
    setTimeout(() => {
      // Triggering 'resize' event to redraw charts.
      window.dispatchEvent(new Event('resize'));

      const target = jQuery(event.target).parents('.nav.nav-tabs').siblings('.tab-content').find('.tab-pane.active');
      if (target.length > 0) {
        const svg = jQuery(target).find('horizontal-chart');
        if (svg.length) {
          svg.each((idx, el) => {
            setTimeout(function () {
              const chartContainer = el._shadowRoot.querySelector('.chart-container');
              chartInit(chartContainer);
            }, 300);
          });
        }
      }
    }, 50);
  });

  async function loadFileSource(url) {
    try{
      const response = await fetch(url);
      return response.json();
    }catch (e) {
      console.warn(`Failed to load chart data. URL: ${url}`);
    }
    return {};
  }

  class HorizontalChartElement extends HTMLElement {
    constructor() {
      const horizontalCharTemplate = document.getElementById('chart-template');
      super();
      this._shadowRoot = this.attachShadow({ 'mode': 'open' });
      this._shadowRoot.appendChild(horizontalCharTemplate.content.cloneNode(true));
    }
    connectedCallback() {
      const url = this.getAttribute('source');
      const element = this._shadowRoot;
      document.addEventListener("DOMContentLoaded", function () {
        loadFileSource(url).then(data => {
          const {
            chartTitle: title,
            chartSubtitle: subTitle,
            chartFootnote: footNote,
            chartId: id,
            isGrouped: isGrouped,
            legendData,
            barPadding,
            xAxisLabel,
            yAxisLabel,
            bars,
            ticks
          } = data;
          element.querySelector('.chart-title').innerHTML = title;

          // Subtitle
          if (subTitle) {
            element.querySelector('.chart-subtitle').innerHTML = subTitle;
          } else {
            element.querySelector('.chart-subtitle').remove();
          }

          // Chart
          const svgElement = element.querySelector('.chart-container svg');
          svgElement.id = id;

          const dataAttributes = [
            ['isGrouped', isGrouped ? 'true' : 'false', ''],
            ['chartLegend', JSON.stringify(legendData), ''],
            ['xAxisLabel', xAxisLabel, ''],
            ['yAxisLabel', yAxisLabel, ''],
            ['barPadding', barPadding, 5],
            ['chartBars', bars, ''],
            ['chartTicks', ticks, ''],
          ];
          dataAttributes.forEach(dataAttribute => {
            if (dataAttribute[0] === 'chartBars' && dataAttribute[1]) {
              dataAttribute[1] = JSON.stringify(dataAttribute[1]);
            }
            if (dataAttribute[0] === 'chartTicks' && dataAttribute[1]) {
              dataAttribute[1] = JSON.stringify(dataAttribute[1]);
            }

            svgElement.dataset[dataAttribute[0]] = dataAttribute[1] ? dataAttribute[1] : dataAttribute[2];
          });

          // Caption
          if (footNote) {
            element.querySelector('.chart-footnote').innerHTML = footNote;
          } else {
            element.querySelector('.chart-footnote').remove();
          }

          // Init chart
          const chartContainer = element.querySelector('.chart-container');
          setTimeout(function () {
            if (jQuery(chartContainer).is(':visible')) {
              chartInit(chartContainer);
            }
          }, 300);
        });
      })
    }
  }

  window.customElements.define('horizontal-chart', HorizontalChartElement);
</script>



  <script src="https://developer.nvidia.com/assets/tablefilter/tablefilter-e8295498b8f34d53fbb98264abcc88fb72c57915ee6a13b15361d5df0127ebbb.js"></script>


<template id="nv-filtered-table-template">
  <div class="nvidia-filtered-table-wrapper"></div>
</template>

<script>
  const buildTableIdentity = (function (str) {
    let counter = 0;
    return function (str) {counter += 1; return `${str}-${counter}`}
  })();

  function slugify(str) {
    return String(str)
      .normalize('NFKD') // split accented characters into their base characters and diacritical marks
      .replace(/[\u0300-\u036f]/g, '') // remove all the accents, which happen to be all in the \u03xx UNICODE block.
      .trim() // trim leading or trailing whitespace
      .toLowerCase() // convert to lowercase
      .replace(/[^a-z0-9 -]/g, '') // remove non-alphanumeric characters
      .replace(/\s+/g, '-') // replace spaces with hyphens
      .replace(/-+/g, '-'); // remove consecutive hyphens
  }

  /**
   * Returns URL params.
   *
   * @returns {any|{[p: string]: string}}
   */
  function getUrlParams() {
    try {
      return Object.fromEntries(new URLSearchParams(location.search));
    } catch (e) {
      // Fallback for IE11.
      let search = location.search.substring(1)
        .replace(/&/g, '","')
        .replace(/=/g, '":"');
      return JSON.parse('{"' + search + '"}', function (key, value) {
        return key === "" ? value : decodeURIComponent(value);
      });
    }
  }

  /**
   * Query string extension for TableFilter.
   *
   * @see http://www.tablefilter.com/extension-run-time.html
   *
   * @param {Object} tf
   *   TableFilter instance.
   * @constructor
   */
  function QueryStringExtension(tf) {
    this.tf = tf;
  }
  QueryStringExtension.prototype.init = function () {
    let tf = this.tf;
    tf.emitter.on(['after-filtering'], this.afterFiltering.bind(this));
  };
  QueryStringExtension.prototype.afterFiltering = function (tf, terms) {
    const config = tf.cfg;
    // Get query string.
    let existingParams = getUrlParams();
    // Remove values related to current table.
    $.each(terms, function (index, element) {
      let key = config.qs_filters[index];
      delete existingParams[config.table_identity + "_" + key];
    });
    $.each(terms, function (index, element) {
      if (element.length) {
        existingParams[config.table_identity + "_" + config.qs_filters[index]] = element;
      }
    });
    const paramsKeys = Object.keys(existingParams).sort();
    let sortedParams = {};
    $.each(paramsKeys, function (i, e) {
      sortedParams[e] = existingParams[e];
    });
    const params = $.param(sortedParams);
    const url = window.location.pathname + '?' + decodeURI(params);
    window.history.replaceState({}, '', url);
  };

  function addQueryStringExtension(tf) {
    let queryStringExtension = new QueryStringExtension(tf);
    try {
      tf.registerExtension(queryStringExtension, 'queryStringExtension');
      queryStringExtension.init();
    } catch (e) {
      console.log('Failed to init URL params handler.');
    }
  }

  /**
   * Filtered table web component.
   */
  class NvFilteredTableWebComponent extends HTMLElement {
    constructor() {
      super();
      const elementTemplate = document.getElementById('nv-filtered-table-template');
      this._shadowRoot = this.attachShadow({'mode': 'open'});
      this._shadowRoot.appendChild(elementTemplate.content.cloneNode(true));
    }

    async loadSourceFile(url) {
      try {
        const response = await fetch(url);
        return response.json();
      } catch (e) {
        console.warn(`Failed to load table data. URL: ${url}`);
      }
      return {};
    }

    fetchComponentData = (url, el, hash) => this.loadSourceFile(url).then((data) => this.instantiateComponent(data, el, hash));

    getColumnTypes(config) {
      return Array.from(config).map((col) => {
        const {columnType} = col;
        return columnType ? columnType : 'string';
      });
    }

    addFilterWidgets(config, headerData) {
      headerData.forEach((col, idx) => {
        const {filterWidget} = col;
        if (filterWidget) {
          config[`col_${idx}`] = filterWidget;
        }
      });
      return config;
    }

    instantiateComponent(data, element, hash) {
      const {tableIndex: headerData, tableItems: rowsData, tableIdentity} = data;

      let filterConfig = {
        base_path: '/',
        sticky_headers: true,
        alternate_rows: true,
        mark_active_columns: {
          highlight_column: true,
        },
        loader: true,
        highlight_keywords: true,
        no_results_message: true,
        toolbar: false,
        help_instructions: false,
        paging: {
          results_per_page: ['Records: ', [25, 50, 100]]
        },
        auto_filter: true,
        responsive: true,
        grid_layout: {
          width: '100%',
          tbl_cont_css_class: 'nvidia-filtered-table'
        },
        clear_filter_text: 'All',
        col_types: this.getColumnTypes(headerData),
        extensions: [
          {name: ''}
        ],
        flt_css_class: 'filter-control',
        on_filters_loaded: (e) => {
          const {cfg} = e;
          if (!cfg) {
            return;
          }
          const {defaultValues} = cfg;
          if(!Array.isArray(defaultValues)) {
            return;
          }
          if (defaultValues.length === 0) {
            return;
          }

          defaultValues.forEach((defaultValue) => {
            const {index, value} = defaultValue;
            let headerCell = document.querySelector('.header-row th[data-idx="' + index + '"]');
            if (!headerCell) {
              return;
            }
            const filterIndex = headerCell.dataset['fidx'];
            e.setFilterValue(filterIndex, value);
          });
          e.filter();
        },
        qs_filters: headerData.map((item) => {
          return slugify(item?.columnName);
        }),
      };

      filterConfig = this.addFilterWidgets(filterConfig, headerData);

      const id = tableIdentity ? tableIdentity : buildTableIdentity('t');
      filterConfig.table_identity = id;

      const defaultValues = headerData
        .filter(item => item?.defaultValue !== undefined)
        .map(item => {
          return {index: item['column'], value: item['defaultValue']};
        });

      const filtersMap = headerData.map(item => {
        const {columnName, column} = item;
        return { index: column, key: `${id}_${slugify(columnName)}`}
      });

      const sp = new URLSearchParams(location.search);
      filtersMap.forEach(filter => {
        if (!sp.has(filter.key)) {
          return;
        }
        defaultValues.push({index: filter.index, value: sp.get(filter.key)});
      });

      const detail = {
        hash,
        headerData,
        rowsData,
        defaultValues,
        filterConfig: {
          table_identity: id,
          config: filterConfig,
          predefined_selects: JSON.stringify([]),
          labels_width: [],
        },
      };
      const event = new CustomEvent('nv.filterTable.build', {detail});
      document.dispatchEvent(event);
    }

    connectedCallback() {
      const url = this.getAttribute('source');
      const hash = this.getAttribute('data-hash');
      const element = this._shadowRoot;
      document.addEventListener('DOMContentLoaded', () => this.fetchComponentData(url, element, hash));
    }
  }

  // Register web component.
  window.customElements.define('nv-filtered-table', NvFilteredTableWebComponent);

  /**
   * Builds table header.
   *
   * @param {Array} data
   * @param {HTMLElement} parentElement
   */
  const buildHeader = (data, parentElement) => {
    data.forEach((item, idx) => {
      const {column, columnName} = item;
      const cell = document.createElement('th')
      cell.dataset['idx'] = column;
      cell.dataset['fidx'] = idx;
      cell.innerHTML = columnName;

      const {labelWidth, columnWidth} = item;
      if (labelWidth) {
        cell.dataset['label_width'] = labelWidth;
      }

      if (columnWidth && Number.isInteger(columnWidth) && columnWidth > 0) {
        cell.width = columnWidth + '%';
      } else if (columnWidth && (columnWidth.endsWith('em') || columnWidth.endsWith('px') || columnWidth.endsWith('%'))) {
        cell.width = columnWidth;
      }

      parentElement.appendChild(cell);
    });
  }

  /**
   * Builds table rows.
   *
   * @param {Object} headerData
   * @param {Array} data
   * @param {HTMLElement} parentElement
   */
  const buildRows = (headerData, data, parentElement) => {
    data.forEach(partner => {
      const {name, logo, URL: partnerUrl, cameras} = partner;

      const logoCellContent = `
<a href="${partnerUrl}">
  <img src="${logo}" alt="${name}" title="${name}" loading="lazy">
</a>
<span class="element-invisible">${name}</span>
`;
      cameras.forEach(camera => {
        const row = document.createElement('tr');

        const logoCell = document.createElement('td');
        logoCell.innerHTML = logoCellContent;
        row.appendChild(logoCell);

        for (const [key, value] of Object.entries(headerData)) {
          if (!camera[value.column]) {
            continue;
          }
          const cell = document.createElement('td');
          let cameraValue = camera[value.column];
          let cellHTML = '';
          if (typeof cameraValue === 'object') {
            const {type, product_url, product_img, td_text} = cameraValue
            let img = '';
            if(product_img !== "—") {
              img = `<img src="${product_img}" alt="${td_text}" title="${td_text}">`;
            }
            let html = `
<div class="product-link">
  <a href="${product_url}" target="_blank">
${img}
  <div class="product-title">${td_text}</div>
  </a>
</div>`
            cellHTML = html.trim();
          } else if (typeof cameraValue === 'string') {
            cellHTML = cameraValue
          }
          cell.innerHTML = cellHTML;
          row.appendChild(cell);
        }

        parentElement.appendChild(row);
      })
    });
  }

  const initTable = (table, filtersConfig, defaultValues) => {
    filtersConfig.config.defaultValues = defaultValues;
    const nvidiaFilteredTable = new TableFilter(table, filtersConfig.config);

    nvidiaFilteredTable.emitter.on(['before-loading-extensions'], addQueryStringExtension);

    nvidiaFilteredTable.init();
  };

  document.addEventListener('nv.filterTable.build', (event) => {
    const {detail} = event;
    const {headerData, rowsData, filterConfig, hash, defaultValues} = detail;

    const component = document.querySelector('nv-filtered-table[data-hash="' + hash + '"]');
    const element = document.createElement('div');
    element.classList.add('nvidia-filtered-table-wrapper');
    element.innerHTML = `<div class="table-responsive"><table class="table table-hover table-striped sticky-enabled"><thead></thead><tbody></tbody></table></div>`;
    component.after(element);

    const table = element.querySelector('table');
    const tableHeader = element.querySelector('table thead');
    const tableHeaderRow = document.createElement('tr');
    tableHeaderRow.classList.add('header-row');
    tableHeader.appendChild(tableHeaderRow);
    buildHeader(headerData, tableHeaderRow);

    const tableBody = element.querySelector('table tbody');
    buildRows(headerData, rowsData, tableBody);

    initTable(table, filterConfig, defaultValues);
  });
</script>



  

  

<script src="https://developer.nvidia.com/assets/nv-developer-menu-ef2e8cd32bfeebbc37cfbe7bd384dfd2a655652b52091a12d1177e5c6ac9542b.js"></script>
  <div id='footer' class='mt-auto'></div>
<script>
  let menuLocale = 'en';

  if (menuLocale == 'en') {
    menuLocale = 'en-US';
  }

  function mountHeader(data = false) {
    const headerTarget = document.getElementById('header');
    if (!headerTarget) {
      return;
    }
    let options = {
      baseURL: window.location.origin,
      signedIn: false,
      locale: menuLocale
    };

    if (data) {
      options.secondaryMenu = data;
    }


    options.showMembershipCardLink = true;

    new NVDeveloperHeader({
      target: headerTarget,
      props: options
    });
  }

  function mountFooter(data = false) {
    const footerTarget = document.getElementById('footer');
    if (!footerTarget) {
      return;
    }
    let options = {
      menu: data,
      locale: menuLocale
    };

    new NVDeveloperFooter({
      target: document.getElementById('footer'),
      props: options
    });
  }

  let url = 'd29g4g2dyqv443.cloudfront.net';
  let headerMenuURL = "https://d29g4g2dyqv443.cloudfront.net/menu/en-US/gameworks.json";

  if (headerMenuURL) {
    fetch(headerMenuURL)
      .then(response => response.json())
      .then(data => {
        mountHeader(data);
      })
      .catch((error) => {
        mountHeader();
        window.nv.tracing.addError('menu', error);
      });
  } else {
    mountHeader();
  }

  fetch(`https://${url}/menu/${menuLocale}/footer.json`)
    .then(response => response.json())
    .then(data => {
      mountFooter(data);
    })
    .catch((error) => {
      mountFooter();
      window.nv.tracing.addError('menu', error);
    });
</script>

  <script src="https://www.datadoghq-browser-agent.com/us1/v5/datadog-rum.js"></script>



<script>
  let silentAuthHost = 'www.nvidia.com';
  let crossOriginPageUrl = `https://${silentAuthHost}/auth/hints/`;

  function readHint() {
    return new Promise((resolve) => {
      const { origin: targetOrigin } = new URL(crossOriginPageUrl);

      const iframe = document.createElement('iframe');
      iframe.hidden = true;
      iframe.src = crossOriginPageUrl;

      function responseHandler(event) {
        if (event.origin === targetOrigin) {
          iframe.parentNode.removeChild(iframe);
          return resolve(event.data);
        }
      }

      window.addEventListener('message', responseHandler, { once: true });

      iframe.onload = () => {
        iframe.contentWindow.postMessage({ type: 'read' }, targetOrigin);
      }

      document.body.appendChild(iframe);
    });
  }

  function writeHint(login_hint, idp_id, timestamp, sub) {
    const { origin: targetOrigin } = new URL(crossOriginPageUrl);

    const iframe = document.createElement('iframe');
    iframe.hidden = true;
    iframe.src = crossOriginPageUrl;

    iframe.onload = () => {
      const message = { type: 'write', login_hint, idp_id, timestamp, sub };
      iframe.contentWindow.postMessage(message, targetOrigin);
    }

    document.body.appendChild(iframe);
  }

  function deleteHint() {
    const { origin: targetOrigin } = new URL(crossOriginPageUrl);

    const iframe = document.createElement('iframe');
    iframe.hidden = true;
    iframe.src = crossOriginPageUrl;

    iframe.onload = () => {
      iframe.contentWindow.postMessage({ type: 'delete' }, targetOrigin);
    }

    document.body.appendChild(iframe);
  }


</script>

<script>_satellite.pageBottom();</script>
<script src="https://developer.nvidia.com/assets/nv-alert/nv-alert-2fcf4faf418bd05dbbfc6d06c67713fd512ff67b25b6059be61edd35a7bcc0ed.js"></script>
<script src="https://developer.nvidia.com/packs/js/runtime-69f8104525d1541ca92d.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/4692-a478c93816dbe985b4fa.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/9878-ace6038de3dd10e07189.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/4386-b410797d0fa3c9b7f8c0.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/8465-34d1ba762d9cdeef15fb.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/7053-c0e77a70a9c58bb0dffc.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/486-c00befd7eac0423845ca.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/8311-bc04e55c282e625862a2.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/1252-e6af78d36c708e01c2a6.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/8823-1bca151f7e292c3ba6e8.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/2104-77b6eb5de26cd8b539a2.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/6900-0acbde47be25c259e5ed.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/application-6e70f8dfbe2c5db1a624.js" defer="defer"></script>
<script src="https://developer.nvidia.com/packs/js/ls_track-b3d3055e95f0b20901db.js" defer="defer"></script>
</body>
</html>
