1

I am trying to make multiple WebGLRenderer render on the same canvas, it works for the very first frame, but if it does the work in the animation loop - it can't render things properly. I wonder if there are some limitations in that approach?

Here is the sample code i can't make working properly if requestAnimationFrame is called inside the update function.

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, WIDTH / HEIGHT, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
// + scene filler

const scene2 = new THREE.Scene();
const camera2 = new THREE.OrthographicCamera(-WIDTH / 2, WIDTH / 2, HEIGHT / 2, -HEIGHT / 2, 0, 30);
const renderer2 = new THREE.WebGLRenderer({ canvas: renderer.domElement });
renderer2.autoClear = false;
// + scene2 filler

function update() {
  renderer.render(scene, camera);
  renderer2.render(scene2, camera2);
  requestAnimationFrame(update);
}

https://codesandbox.io/s/l75w6qyw2m?module=%2Fsrc%2Findex.js

I am not sure what to expect though, but i would really want to make that working, i need to have a separate renderer to render several scenes with different cameras, and i was looking for opportunity to do that in separate renderer to provide a nicer public interface to work with for my plugin.

Kova
  • 13
  • 3
  • Please read https://stackoverflow.com/help/mcve > Thank you for providing a link to codesandbox, but for us to help you specifically, we need a Minimal, Complete and Verifiable Example. – wlh Jan 22 '19 at 18:58

1 Answers1

2

It's not possible to have 2 WebGLRenderers in one canvas. The reason is that each canvas has ONE WebGLContext as a native limitation, it cannot create a second context.

However, it looks like you're just trying to render two scenes, one on top of the other. You could do that with a single renderer. You just have to turn off its auto-clear property, then use it to render the two scenes, one on top of the other like this:

renderer.autoClear = false;

function update() {
  renderer.render(scene, camera);
  renderer.render(hudScene, hudCamera);
  requestAnimationFrame(update);
}
M -
  • 26,908
  • 11
  • 49
  • 81
  • Yeah, but in fact, as i stated, i will end up having multiple scenes with multiple cameras on top of what there is already, hence i would love to get that isolated from the main code - for the sake of simplified interface, but i guess it's not crucial though if it won't work. Funny though, if you disable the `requestAnimationFrame` it will render everything correctly the first frame! – Kova Jan 22 '19 at 18:52
  • But i was thinking about your start words, could you actually init new renderer with the preset `WebGLContext`, instead of passing canvas element? – Kova Jan 22 '19 at 18:54
  • When you initialize a second WebGLRenderer with `({ canvas: renderer.domElement });` it hijacks the context of the first one, so the first one no longer has anything to render to after the first frame. – M - Jan 22 '19 at 19:02
  • I have tried to pass `{ context: renderer.context }` into the second renderer, but it also didn't work, so i guess they can't share contexts either. – Kova Jan 22 '19 at 19:06
  • It's also not recommended to use multiple renderers because your app could take a big performance hit. You're running tons of code with who knows how many dependencies each time you initiate a renderer, so it's much more efficient to simply re-use one renderer. https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L1 – M - Jan 22 '19 at 19:12
  • Yeah, the reason i was asking is that in my previous solution i was actually using the separate canvas which would lay on top of the main canvas, so it felt using multiple renderers would be much better solution... But all this is just to provide a simple plugin interface, i would be able to just accept canvas element or its context and then inside the plugin prepare the scenes and do rendering. but i guess i am left with either having an external method to accept main renderer and do the work, or just export all scene + camera pairs that should be rendered. – Kova Jan 22 '19 at 19:26