2017-09-09 698 views
1

已经我已经正确地实现了屏幕空间环境光遮蔽在我three.js所项目,并运行完美,像这样:three.js所:应用SSAO(屏幕空间环境光遮蔽),以置换贴图

//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); 
    } 

这是作曲家的渲染循环

如果(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); 
} 

如何存档应用于位移贴图网格的正确Screen Screen Ambient Occlusion?谢谢。

[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

您正在使用SSAO和位移图。在实例化深度材质时,您需要指定位移贴图。

depthMaterial = new THREE.MeshDepthMaterial({ 

    depthPacking: THREE.RGBADepthPacking, 

    displacementMap: displacementMap, 
    displacementScale: displacementScale, 
    displacementBias: displacementBias 

}); 

three.js所r.87

+0

HI,我很困惑遗憾。 因此,我需要为场景中实现位移贴图的每种材质创建一个depthMaterial? – DuffDan

+0

好吧,这有点棘手。然后,对于多个网格物体,_maybe_可以通过mesh.onBeforeRender = function(渲染器,场景,相机,几何体,材质,组)来重置“scene.overrideMaterial” ){scene.overrideMaterial = this.overrideMaterial; };'只是一个假设... – WestLangley

+0

我会试试看,谢谢! – DuffDan