2017-09-09 9 views
1

ai-je ai mis en place l'espace écran Ambient Occlusion dans mon projet Three.js correctement et course parfaite, comme ceci:Three.js: Appliquer SSAO (écran Espace Ambient Occlusion) à la carte Déplacement

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

Mais, quand je mets un matériau avec displacementMap (qui fonctionne correctement sans SSAO activé), c'est le résultat. Notez que le SSAO est appliqué « correctement » à la sphère d'origine (avec un étrange trasparent-artificat), mais je dois l'appliquer au « sommet déplacé » de la sphère)

Incorrect SSAO

C'est mon compositeur passe:

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

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

Et ceci est la boucle de rendu avec le compositeur

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

Comment puis-je archiver une occlusion ambiante de l'espace d'écran correcte appliquée à un maillage avec la carte de déplacement? Merci. Après un peu de travail, j'ai essayé cette procédure pour chaque enfant de la scène, avec une carte de déplacement, pour définir un nouveau overrideMatériel de la scène égal à un depthMaterial avec des paramètres de déplacement de la carte du matériel enfant .

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

Cette solution semble bonne, mais ne fonctionne pas.

Répondre

1

Vous utilisez SSAO avec une carte de déplacement. Vous devez spécifier la carte de déplacement lorsque vous instanciez le matériau de profondeur.

depthMaterial = new THREE.MeshDepthMaterial({ 

    depthPacking: THREE.RGBADepthPacking, 

    displacementMap: displacementMap, 
    displacementScale: displacementScale, 
    displacementBias: displacementBias 

}); 

Three.js R.87

+0

HI, je suis confus désolé. Donc, je dois créer un depthMaterial pour chaque matériau de la scène qui implémente displacementMap? – DuffDan

+0

Eh bien, c'est un peu difficile. Voyez si vous pouvez démontrer que cette réponse est correcte pour un seul maillage ... Ensuite, pour plusieurs maillages, _maybe_ vous pouvez réinitialiser 'scene.overrideMaterial' via' mesh.onBeforeRender = fonction (rendu, scène, caméra, géométrie, matériau, groupe) {scene.overrideMaterial = this.overrideMaterial; }; 'Juste une hypothèse ... – WestLangley

+0

Je vais essayer, merci! – DuffDan