Closed xiaoiver closed 3 years ago
渲染多个场景是常见的需求。然而 WebGL 上下文个数是有限制的,超过 8 个再创建就会触发 context lost 事件(目前我们也还没针对该事件进行处理)。 来自:https://threejsfundamentals.org/threejs/lessons/threejs-multiple-scenes.html
因此相比创建多个 canvas 以及 WebGL 上下文,在单个 canvas 中分别渲染多个场景是更好的做法。
最直接的思路是分别渲染每个场景到纹理中,最后在指定位置渲染纹理。显然这样需要渲染两次: https://webglfundamentals.org/webgl/lessons/webgl-multiple-views.html
更好的做法是使用 viewport + scissor。在 Three.js 中是这样实现的:
首先关闭 scissor test 完成清屏:
function render(time) { renderer.setScissorTest(false); renderer.clear(true, true); renderer.setScissorTest(true); renderSceneInfo(sceneInfo1); renderSceneInfo(sceneInfo2); requestAnimationFrame(render); }
然后在渲染每个场景前:
function renderSceneInfo(sceneInfo) { const {scene, camera, elem} = sceneInfo; const {left, right, top, bottom, width, height} = elem.getBoundingClientRect(); const isOffscreen = bottom < 0 || top > renderer.domElement.clientHeight || right < 0 || left > renderer.domElement.clientWidth; if (isOffscreen) { return; } camera.aspect = width / height; camera.updateProjectionMatrix(); const positiveYUpBottom = canvasRect.height - bottom; renderer.setScissor(left, positiveYUpBottom, width, height); renderer.setViewport(left, positiveYUpBottom, width, height); renderer.render(scene, camera); }
每个 Viewport 可以有独立的相机和交互。
效果如下:
问题背景
渲染多个场景是常见的需求。然而 WebGL 上下文个数是有限制的,超过 8 个再创建就会触发 context lost 事件(目前我们也还没针对该事件进行处理)。 来自:https://threejsfundamentals.org/threejs/lessons/threejs-multiple-scenes.html
因此相比创建多个 canvas 以及 WebGL 上下文,在单个 canvas 中分别渲染多个场景是更好的做法。
实现思路
最直接的思路是分别渲染每个场景到纹理中,最后在指定位置渲染纹理。显然这样需要渲染两次: https://webglfundamentals.org/webgl/lessons/webgl-multiple-views.html
更好的做法是使用 viewport + scissor。在 Three.js 中是这样实现的:
首先关闭 scissor test 完成清屏:
然后在渲染每个场景前:
具体实现
每个 Viewport 可以有独立的相机和交互。
效果如下: