I want to display two camera views of a single scene, with text label overlays shown in both views.
I use renderer.setScissor to render 2 separate views on the page, using html elements to define viewport bounds, i.e.
<div class="view1-container"></div>
<div class="view2-container"></div>
Now I’d like to use CSS2DRenderer to overlay text labels for each view. However, the way CSS2DRenderer works, it seems to use the scene graph as a way to track what labels have been displayed or not. The result is that rendering multiple instances of CSS2DRenderer using the same scene doesn’t seem possible. Am I missing something?
Pseudo code below:
let view1Container = document.querySelector('.view1-container');
let view2Container = document.querySelector('.view2-container');
let view1Labels = new CSS2DRenderer();
let view2Labels = new CSS2DRenderer();
view1Container.appendChild(view1Labels.domElement);
view2Container.appendChild(view2Labels.domElement);
// Inside the animate() loop...
// ...After rendering the canvas using renderer.setScissor, render the labels
view1Labels.render(scene, view1Camera);
view2Labels.render(scene, view2Camera);
The expected result is that each view would get it’s own div with labels, but the actual result is only the last view shows the labels. This feels like a bug or limitation with CSS2DRenderer. Is there another way to approach this? Any help is appreciated, thanks.
@kpachinger Thank you. I had a hard time understanding all of your suggestions, but it did highlight the underlying cause that the memory is being overwritten. If I clone the scene, that avoids the memory being cleared but then creates lots of duplicate child labels. The workaround I found was to first clear the CSS2DRenderer’s domElement before the next render. I don’t know if cloning the scene each time in this way causes a memory/performance penalty, but for now it works.
let view1Container = document.querySelector('.view1-container');
let view2Container = document.querySelector('.view2-container');
let view1Labels = new CSS2DRenderer();
let view2Labels = new CSS2DRenderer();
view1Container.appendChild(view1Labels.domElement);
view2Container.appendChild(view2Labels.domElement);
// Inside the animate() loop...
// ...After rendering the canvas using renderer.setScissor, clear the render label domElement and render the labels with a cloned scene
view1Labels.domElement.replaceChildren(); // Empty the domElement to prevent duplicate child nodes
view1Labels.render(scene.clone(), view1Camera); // Clone the scene to prevent memory being cleared
view2Labels.domElement.replaceChildren();
view2Labels.render(scene.clone(), view2Camera);
Tru, in production 60fps clones may not be maintainable. For example, querySelector(id) could return any number of dirty things. The worst side-effect is synchronizing the “live-ness” of the value… Such as error handling if nodes don’t exist, so your app doesn’t break. In the context of 3d graphics it may leak falsy bugs up the chain, depending on what attributes you extend.
XHTML is an opinionated abstrcat <🐱/>