WebGLRenderTarget: Null texture in shader texture Uniform

Viewed 277

While using THREE.WebGLRenderTarget to render a scene to a texture and pass that texture to a second shader, the value received in the Shader texture uniform variable is always null.

Flow of code:

  1. Shader1 is used for renderingDepthMap(Working fine while being rendered on screen)
  2. The rendered depthMap is passed as texture uniform to shader2 that is finally rendered on screen.

Relevant Code Snippet:

//Initialize the renderTarget
var options = {

                minFilter : THREE.LinearFilter,
                magFilter : THREE.LinearFilter,
                format : THREE.RGBAFormat,
                type : /(iPad|iPhone|iPod)/g.test(navigator.userAgent) ? THREE.HalfFloatType : 
                        THREE.FloatType
            };

    renderTarget1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, 
                                   options);
    renderTarget1.stencilBuffer = false;
    renderTarget1.texture.needsUpdate = true;
    renderTarget1.texture.generateMipmaps = false;

    //Define the Shader2 uniforms
        uniforms = {
                     depthMap : { type: "t", value: renderTarget1.texture},
                     O_SIZE : { type: "float", value: 0.000375},
                   };

        //Creating Material for Shader2
        materialShader2 = new THREE.ShaderMaterial({
                            uniforms: uniforms,
                            vertexShader : document.getElementById('vertex2_Shader').textContent,
                            fragmentShader : document.getElementById('fragment2_Shader').textContent
                          });


    materialShader2.needsUpdate = true;


    //Animate function
    function animate()
    {
        // render depth map in renderTarget1
        renderer.setRenderTarget(renderTarget1); //setting render target
        renderer.render(sceneDepthMap, shadowCamera); // rendering depthmap to framebuffer
        renderer.setRenderTarget(null);
        renderer.render(scene2, shadowCamera);
        requestAnimationFrame( animate );
    }
1 Answers

I don't have access to your GLSL shader code, but are you sure that the uniform names are identical? It should be uniform sampler2D depthMap;, keep an eye on capitalization. Also, you no longer need to declare type: "t" in the uniform, the engine detects it automatically from its value.

Secondly, if you want to get the depth buffer of a render pass, you need to set WebGLRenderTarget.depthTexture to a new texture, because .texture stores the color buffer, not the depth buffer. You can then use that as your uniform value:

var renderTarget1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
renderTarget1.depthTexture = new THREE.DepthTexture(
    window.innerWidth,
    window.innerHeight
);


var materialShader2 = new THREE.ShaderMaterial({
    uniforms: {
        // Notice uniform name, depthTexture and no type
        depthMap : { value: renderTarget1.depthTexture},
        O_SIZE : { value: 0.000375},
    },
    vertexShader : document.getElementById('vertex2_Shader').textContent,
    fragmentShader : document.getElementById('fragment2_Shader').textContent
});
Related