Three.js:将SSAO(屏幕空间环境遮挡)应用于置换贴图

时间:2017-09-09 16:19:23

标签: three.js webgl texture-mapping pbr

我是否正确地在我的Three.js项目中实现了屏幕空间环境遮挡,并运行完美,如下所示:

//Setup SSAO pass   
depthMaterial = new THREE.MeshDepthMaterial();
depthMaterial.depthPacking = THREE.RGBADepthPacking;
depthMaterial.blending = THREE.NoBlending;

var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: true }; //Stancilbuffer true because not effect transparent object
depthRenderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, pars);
depthRenderTarget.texture.name = "SSAOShader.rt";
ssaoPass = new THREE.ShaderPass(THREE.SSAOShader);
///////ssaoPass.uniforms[ "tDiffuse" ].value will be set by ShaderPass
ssaoPass.uniforms["tDepth"].value = depthRenderTarget.texture;
ssaoPass.uniforms['size'].value.set(window.innerWidth, window.innerHeight);
ssaoPass.uniforms['cameraNear'].value = camera.near;
ssaoPass.uniforms['cameraFar'].value = camera.far;
ssaoPass.uniforms['radius'].value = radius;
ssaoPass.uniforms['aoClamp'].value = aoClamp;
ssaoPass.uniforms['lumInfluence'].value = lumInfluence;

但是,当我使用displacementMap设置一个材质(没有启用SSAO时正确运行),这就是结果。请注意,SSAO“正确”应用于原始球体(具有奇怪的trasparent-artificat),但我需要将其应用于球体的“移位顶点”)

Incorrect SSAO

这是我的作曲家传递:

   //Main render scene pass
    postprocessingComposer.addPass(renderScene);

    //Post processing pass
    if (ssaoPass) {
        postprocessingComposer.addPass(ssaoPass);
    }

这是带作曲家的渲染循环

if(postprocessingComposer){

    if (ssaoPass) {

        //Render depth into depthRenderTarget
        scene.overrideMaterial = depthMaterial;
        renderer.render(scene, camera, depthRenderTarget, true);

        //Render composer
        scene.overrideMaterial = null;
        postprocessingComposer.render();

        renderer.clearDepth();
        renderer.render(sceneOrtho, cameraOrtho);
    }
    else {
        //Render loop with post processing (no SSAO, becasue need more checks, see above)
        renderer.clear();
        postprocessingComposer.render();        
        renderer.clearDepth();
        renderer.render(sceneOrtho, cameraOrtho);
    }
}
else {
    //Simple render loop (no post-processing)
    renderer.clear();
    renderer.render(scene, camera);
    renderer.clearDepth();
    renderer.render(sceneOrtho, cameraOrtho);
}

如何使用置换贴图存档应用于网格的正确屏幕空间环境光遮挡?感谢。

[UPDATE]: 经过一些工作后,我尝试使用置换贴图为场景中的每个孩子设置此过程,以定义一个新的场景的overrideMaterial,其等于具有子材质的置换贴图参数的depthMaterial。

                    var myDepthMaterial = new THREE.MeshDepthMaterial({
                        depthPacking: THREE.RGBADepthPacking,
                        displacementMap: child.material.displacementMap,
                        displacementScale: child.material.displacementScale,
                        displacementBias: child.material.displacementBias
                    });
                    child.onBeforeRender = function (renderer, scene, camera, geometry, material, group) {
                        scene.overrideMaterial = myDepthMaterial;     
                    };

这个解决方案听起来不错,但不起作用。

1 个答案:

答案 0 :(得分:1)

您正在使用带有置换贴图的SSAO。实例化深度材质时,需要指定置换贴图。

depthMaterial = new THREE.MeshDepthMaterial( {

    depthPacking: THREE.RGBADepthPacking,

    displacementMap: displacementMap,
    displacementScale: displacementScale,
    displacementBias: displacementBias

} );

three.js r.87