Is there anyone who can clarify the operations happening within this Three.js StereoEffect code?

Is there anyone knowledgeable in stereo rendering who can provide an explanation of how these functions work together to achieve the VR stereo effect? Information on functions like

StereoCamera(), setScissor(), setViewPort()
in the three.js library seems scarce.

I would be grateful for explanations at either a high or low level.

One issue I'm encountering is that adjusting the eyeSep value doesn't seem to have any impact on the final render.

/**
 * @author alteredq / http://alteredqualia.com/
 * @authod mrdoob / http://mrdoob.com/
 * @authod arodic / http://aleksandarrodic.com/
 * @authod fonserbc / http://fonserbc.github.io/
*/

THREE.StereoEffect = function ( renderer ) {

    var _stereo = new THREE.StereoCamera();
    _stereo.aspect = 0.5;
    var size = new THREE.Vector2();

    this.setEyeSeparation = function ( eyeSep ) {

        _stereo.eyeSep = eyeSep;

    };

    this.setSize = function ( width, height ) {

        renderer.setSize( width, height );

    };

    this.render = function ( scene, camera ) {

        scene.updateMatrixWorld();

        if ( camera.parent === null ) camera.updateMatrixWorld();

        _stereo.update( camera );

        renderer.getSize( size );

        if ( renderer.autoClear ) renderer.clear();
        renderer.setScissorTest( true );

        renderer.setScissor( 0, 0, size.width / 2, size.height );
        renderer.setViewport( 0, 0, size.width / 2, size.height );
        renderer.render( scene, _stereo.cameraL );

        renderer.setScissor( size.width / 2, 0, size.width / 2, size.height );
        renderer.setViewport( size.width / 2, 0, size.width / 2, size.height );
        renderer.render( scene, _stereo.cameraR );

        renderer.setScissorTest( false );

    };

};

module.exports = THREE.StereoEffect;

Answer â„–1

setScissor and setViewport

To define the rendering area of the canvas, you can use setViewport to specify how a shader's clip space is converted to a portion of the canvas's pixel space. Additionally, setScissor sets a rectangular region outside of which no rendering will occur.

For more details, refer to this link.

In contrast, StereoCamera offers two cameras separated by an eyeSep distance, allowing manipulation of a single camera (the

PerspectiveCamera</code). By updating the <code>StereoCamera
, both eye cameras are automatically adjusted for rendering purposes.

body { margin: 0; }
#c { width: 100vw; height: 100vh; display: block; }
#ui { position: absolute; left: 1em; top: 1em; }
<canvas id="c"></canvas>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
import {GUI} from 'https://threejsfundamentals.org/threejs/../3rdparty/dat.gui.module.js';

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;
  
  const stereo = new THREE.StereoCamera();

  const gui = new GUI();
  gui.add(stereo, 'eyeSep', 0, 2, 0.001);

  const scene = new THREE.Scene();

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }

  const geometry = new THREE.SphereBufferGeometry(0.5, 6, 3);

  function makeInstance(geometry, color, x) {
    const material = new THREE.MeshPhongMaterial({color, flatShading: true});

    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    cube.position.x = x;

    return cube;
  }

  const cubes = [
    makeInstance(geometry, 0x44aa88,  0),
    makeInstance(geometry, 0x8844aa, -1),
    makeInstance(geometry, 0xaa8844,  1),
  ];

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    time *= 0.001;

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight / 2;  
      camera.updateProjectionMatrix();
    }

    cubes.forEach((cube, ndx) => {
      const speed = 1 + ndx * .1;
      const rot = time * speed;
      cube.rotation.x = rot;
      cube.rotation.y = rot;
    });

    {
        // we need to manually update camera matrix
        // because it will not be passed directly to
        // renderer.render were it would normally be
        // updated

        camera.updateWorldMatrix();
        stereo.update(camera);

        const size = new THREE.Vector2();
        renderer.getSize(size);

        renderer.setScissorTest(true);

        renderer.setScissor(0, 0, size.width / 2, size.height);
        renderer.setViewport(0, 0, size.width / 2, size.height);
        renderer.render(scene, stereo.cameraL);

        renderer.setScissor(size.width / 2, 0, size.width / 2, size.height);
        renderer.setViewport(size.width / 2, 0, size.width / 2, size.height);
        renderer.render(scene, stereo.cameraR);

        renderer.setScissorTest(false);
    }

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Conflicting Angular controller names within different modules

I'm facing an issue where two modules (A and B) with controllers of the same name are conflicting when imported into module C. Is there a recommended solution to prevent this conflict, such as using a naming convention like "module.controller" for ea ...

Ways to extract the value from a jQuery object

How can I retrieve the selected time value using a jQuery plugin and save it on a specific input element within the page? Refer to the plugin and code provided below: http://jsfiddle.net/weareoutman/YkvK9/ var input = $('#input-a'); input.cloc ...

The functionality of TypeScript's .entries() method is not available for the type 'DOMTokenList'

I'm currently working with a stack that includes Vue3, Vite, and TypeScript. I've encountered an issue related to DOMTokenList where I'm trying to utilize the .entries() method but TypeScript throws an error saying Property 'entries&apo ...

Emphasize entries in an index that match the currently visible content as you scroll

I have a table of contents in my HTML page with the CSS attribute position: fixed;. I want to emphasize the current reading position by highlighting it (bold or italics) as I scroll down the page. | yada yada yada ... 1. Secti ...

Having difficulty installing the yarn package from GitHub

I'm attempting to install a GitHub package using yarn. I've tried this process many times before, but I have not been successful with this particular repository: https://github.com/coolwanglu/pdf2htmlEX I have already attempted the following w ...

Supertest and Jest do not allow for sending JSON payloads between requests

Below is the test function I have written: describe("Test to Create a Problem", () => { describe("Create a problem with valid input data", () => { it("Should successfully create a problem", async () => { const ProblemData = { ...

What is the best way to retrieve a Promise from a store.dispatch within Redux-saga in order to wait for it to resolve before rendering in SSR?

I have been experimenting with React SSR using Redux and Redux-saga. While I have managed to get the Client Rendering to work, the server store does not seem to receive the data or wait for the data before rendering the HTML. server.js ...

Integrate the dForm plugin with a convenient time picker widget

Currently, I am attempting to integrate a time picker widget into a jQuery plugin called dForm. The specific timepicker widget can be found at the following link: https://github.com/jonthornton/jquery-timepicker Despite reviewing the dForm documentation, ...

How can I stop a user from navigating through links or submitting forms using jQuery?

I'm exploring the idea of converting my website into a Single Page Application. One challenge I am facing is capturing the navigation process, for example: <a href="myData.php">Change My Data</a> When a user clicks on the "Change My Data ...

What could be causing these transformed canvases to not display fully in Chrome at specific resolutions?

fiddle: https://jsfiddle.net/f8hscrd0/66/ html: <body> <div id="canvas_div"> </div> </body> js: let colors = [ ['#000','#00F','#0F0'], ['#0FF','#F00','#F0F&a ...

Angular UI-Router: Difficulty in Child State Accessing Parent Controller

I am currently using ui.router's nested views feature in my Angular application. Here is the relevant part of my .config: $urlRouterProvider.otherwise('/'); $stateProvider .state('home', { url: '/', templateUrl: ...

Looking to extract the full page source with Selenium and Node.js? Having trouble getting the complete source using driver.page_source as it

Having trouble fetching the full page source with Selenium web driver in Node.js I attempted using driver.page_source but it returns undefined in the console if(this.driver.findElement(By.id("ap_error_page_message")).isDisplayed()){ console.log(t ...

Issues with method invocation in jQuery's .ajax requestI am having

After reading this Stack Overflow post, I now understand how to retrieve a return value from an AJAX call: function GetIsDataReady(input) { $.ajax({ url: "http://www.blah.com/services/TestsService.svc/IsDataReady", ...

Limiting ng-repeat in AngularJS when the last item on the object is reached

I have a large object being repeated using ng-repeat, and it runs smoothly on Chrome and Opera. However, when it comes to browsers like Mozilla and IE, the performance is very slow. I tried implementing pagination, which helped speed things up, but ideally ...

Personalize the appearance of your stackLabels in Highcharts with dynamic customization options

I recently created a bar graph using Highcharts. You can check it out here: http://jsfiddle.net/v1rbz41q/3/ Here's the code snippet I used: chartw.yAxis [0] .options.stackLabels.formatter = function () {              return "werfdc";   ...

Designing a user interface that consists of numerous distinct components

Challenge I'm faced with a dilemma regarding site A, which is built using React. Specifically, I need to find a way to integrate smaller React components into site A whenever a user navigates to a specific page within the site. Each of these smalle ...

"What is the best way to display an image from a table and then enlarge it to full size when a button is clicked, all

1. Understanding the Concept In my page, I have a table listing various images with unique names that are successfully displayed in the table. My goal is to display the selected image in full screen within a popup window when a button is clicked. 2. Que ...

Difficulty with Pomodoro clock's canvas ring function not working as expected

Hey everyone, good evening. I've been struggling with a particular section of code for quite some time now and could really use some help. When you check out the constructor at this.drawArc and then look into the prototype, I've printed a couple ...

Ways to prevent users from manually inputting dates in date fields

I am currently developing an application and I need to prevent users from manually entering a date in the type=date field on the HTML page. I want to restrict users to only be able to select a date from the calendar display, which is in the format MM/DD/YY ...

Learn about generating PDF files with React Native Expo using the react-native-html-to-pdf library!

I'm currently attempting to execute a 'Hello World' code utilizing the react-native-html-to-pdf library in order to generate a PDF, but I am encountering difficulties setting it up in Expo. Would you be able to provide assistance? I have tri ...