three.js - Trying to include a subwindow into main

2019-08-11 23:11发布

问题:

I try to include, into a main window (representing sphere), a subwindow representing a zoomed view of this sphere.

For this moment, I can display a right-bottom subwindow containing the three axes of main scene. These axes are rotating the same way I make rotate the sphere with mouse.

Now, I would like to display, into this subwindow, a zoomed view of the sphere instead of having the subwindow with 3D axes.

From Can multiple WebGLRenderers render the same scene?, we can't use a second time the THREE.WebGLRenderer() for the subwindow.

From How to render the same scene with different cameras in three.js? ,a solution may be to use setViewport function but I don't know if I can display the zoom of sphere in this subwindow.

I tried to do in render() function :

function render() {
    controls.update();
    requestAnimationFrame(render);

    zoomCamera.position.copy(camera.position);
    zoomCamera.position.sub(controls.target);
    zoomCamera.position.setLength(500);
    zoomCamera.lookAt(zoomScene.position );

    // Add Viewport for zoomScene
    renderer.setViewport(0, 0, width, height);
    renderer.render(scene, camera);

    zoomRenderer.setViewport(0, 0, 200 , 200);
    zoomRenderer.render(zoomScene, zoomCamera);

  }

From your advices, is it possible technically to have 2 object in the same time (one on main window and the other on right-bottom subwindow) ?

Can I solve my issue with setViewport ?

And if someone could give documentation on setViewport, this would be great.

Thanks in advance.

UPDATE :

@WestLangley , thanks, I did your modifications (with a unique scene) but the content of inset does not appear.

I think that issue comes from the fact that I don't know how to make the link between the container of inset and the drawing of this inset.

For example, into the link above, I tried :

...
 // Add sphere to main scene
  scene.add(sphere);

  camera.position.z = 10;

  var controls = new THREE.TrackballControls(camera);

  // If I include these two lines below, nothing appears 
  // zoomContainer = document.getElementById('zoomContainer');
  // zoomContainer.appendChild(renderer.domElement);

  // Zoom camera
  zoomCamera = new THREE.PerspectiveCamera(50, zoomWidth, zoomHeight, 1, 1000);
  zoomCamera.position.z = 20;
  zoomCamera.up = camera.up; // important!

  // Call rendering function
  render();

  function render() {

  controls.update();
  requestAnimationFrame(render);

  zoomCamera.position.copy(camera.position);
  zoomCamera.position.sub(controls.target); 
  zoomCamera.position.setLength(camDistance);
  zoomCamera.lookAt(scene.position);

  // Add zoomCamera to main scene
  scene.add(zoomCamera);

  // render scene
  renderer.clear();
  renderer.setViewport(0, 0, width, height);
  renderer.render(scene, camera);

  // render inset
  renderer.clearDepth(); // important!
  renderer.setViewport(10, height - zoomHeight - 10, zoomWidth, zoomHeight);
  renderer.render(scene, zoomCamera);

}

Given that I have only one renderer, I don't knwo how to assign the "inset" container to the renderer of Viewport (i.e with the good renderer.setViewport)

Would you have got a workaround ?

回答1:

You want to render another view of your scene in an inset window.

Create one scene, and two cameras.

Make sure you set autoClear to false when you instantiate the renderer.

renderer.autoClear = false;

Then, in your render loop, use this pattern

// render scene
renderer.clear();
renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight );
renderer.render( scene, camera );

// render inset
renderer.clearDepth(); // important!
renderer.setViewport( 10, window.innerHeight - insetHeight - 10, insetWidth, insetHeight );
renderer.render( scene, camera2 );

three.js r.75