SAOPass: Wrong behavior when using two canvases

Description of the problem

When using SAOPass in several canvas it won’t work, see jsfiddle.

https://jsfiddle.net/ptgwhemb/6/ (I just copied the initializing code so its rather nasty but does its job 😉 )

What I expect:
A green cube with SAO on the first canvas and a red cube with SAO on the second canvas.

What I get:
Only a red cube with SAO on the second canvas.

Possible reasons:
After some debugging I found out, that, for both canvases, in the SAOPass render function the texture uniforms of the materials are pointing to the same texture even though their member renderTargets and their textures are fine.
So in this case the first WebGLRenderer tries to access a texture which isn’t in its context but in the other WebGL Context.
With spector.js I could verify that, on the first canvas, the texture uniforms tDepth and tNormal of the saomaterial referencing to an empty texture with width=height=1 and the uuid of them is the same as the textures from the second canvas…
I don’t know three.js internally good enough to know why this is happening, but probably some of you guys know where this bug comes from?

Three.js version
  • Dev
Browser
  • All of them
OS
  • All of them

Author: Fantashit

1 thought on “SAOPass: Wrong behavior when using two canvases

  1. The problem is that the shader material in SAOPass is not setup correctly. Uniforms are not cloned so more than one instance of SAOPass will lead to invalidation of uniforms of other passes. The following code fixes the issue.

    this.saoMaterial = new THREE.ShaderMaterial( {
       defines: THREE.SAOShader.defines,
       fragmentShader: THREE.SAOShader.fragmentShader,
       vertexShader: THREE.SAOShader.vertexShader,
       uniforms: THREE.UniformsUtils.clone( THREE.SAOShader.uniforms ) // fix
    } );

    Demo: https://jsfiddle.net/ptgwhemb/25/

    It’s also necessary to clone the defines object since these values can differ, too.

Comments are closed.