【问题标题】:Getting SSAO shader working with SkinnedMesh让 SSAO 着色器与 SkinnedMesh 一起工作
【发布时间】:2016-10-03 13:54:42
【问题描述】:

我一直在尝试让 SSAO 后处理着色器与最新 (r77) 版本的 three.js 一起工作。我一直在使用 EffectComposer,代码完全复制自此处的示例页面:

http://threejs.org/examples/webgl_postprocessing_ssao.html

相关代码为:

var renderPass = new THREE.RenderPass( Engine.scene, Engine.camera );
ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
ssaoPass.renderToScreen = true;
// ...various ShaderPass setup parameters

Engine.effectComposer = new THREE.EffectComposer( Engine.renderer );

Engine.effectComposer.addPass(renderPass);
Engine.effectComposer.addPass(ssaoPass);

我遇到的问题是 SSAO 似乎不适用于 SkinnedMeshes。它似乎在执行蒙皮计算之前考虑了网格的位置

看起来像这样:

Problem with SSAO on SkinnedMesh

有人在最新版本上对此有任何经验吗?我找遍了所有地方,但根本找不到任何有关如何开始修复此问题的文档。

我发现在另一个 SO 帖子 (ThreeJS SSAO Shader w/ Skinned/Animated Models) 中提到了解决此问题的方法,但该解决方案已被弃用。

提前致谢,如果需要,我们很乐意提供更多详细信息。

根据要求,这里是simple demo page 的完整代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">

        <script type="text/javascript" src="js/libs/jquery.min.js"></script>
        <script type="text/javascript" src="js/libs/three.min.js"></script>

        <script type="text/javascript" src="js/libs/postprocessing/CopyShader.js"></script>
        <script type="text/javascript" src="js/libs/postprocessing/EffectComposer.js"></script>
        <script type="text/javascript" src="js/libs/postprocessing/MaskPass.js"></script>
        <script type="text/javascript" src="js/libs/postprocessing/RenderPass.js"></script>
        <script type="text/javascript" src="js/libs/postprocessing/ShaderPass.js"></script>
        <script type="text/javascript" src="js/libs/postprocessing/DotScreenShader.js"></script>
        <script type="text/javascript" src="js/libs/postprocessing/SSAOShader.js"></script>

        <link rel="stylesheet" type="text/css" href="demo.css" />
    </head>
    <body>
        <div id="demo-container"></div>
    </body>
</html>
<script>

$(document).ready(function() {

    window.doPostPro = 0;

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 1000);
    camera.position.set(0, 200, 200);
    camera.lookAt(new THREE.Vector3(0, 0, 0));

    clock = new THREE.Clock();

    // Setup the renderer.
    renderer = new THREE.WebGLRenderer({
        antialias: true
    });
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor( 0xFFFFFF );

    function setupPostProcessing() {

        // Setup render pass
        var renderPass = new THREE.RenderPass( scene, camera );

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

        depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, {
            minFilter:      THREE.LinearFilter, 
            magFilter:      THREE.LinearFilter,
            stencilBuffer:  true
        });

        // Setup SSAO pass
        ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
        ssaoPass.renderToScreen = true;
        //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[ 'onlyAO' ].value = ( postprocessing.renderMode == 1 );
        ssaoPass.uniforms[ 'aoClamp' ].value = 0.3;
        ssaoPass.uniforms[ 'lumInfluence' ].value = 0.5;

        // Add pass to effect composer
        effectComposer = new THREE.EffectComposer( renderer );
        effectComposer.addPass( renderPass );
        effectComposer.addPass( ssaoPass );
    };

    setupPostProcessing();

    // Load the mesh.
    var loader = new THREE.JSONLoader();
    loader.load( "js/zombie.js", function( geometry, materials ) {

        var originalMaterial = materials[ 0 ];
        originalMaterial.skinning = true;

        geometry.computeVertexNormals();

        var mesh = new THREE.SkinnedMesh(geometry, originalMaterial);

        window.animMixer = new THREE.AnimationMixer(mesh);
        var animAction = animMixer.clipAction(geometry.animations[0]);
        animAction.play();

        scene.add(mesh);
    });

    var ambientLight = new THREE.AmbientLight( 0xCCCCCC );
    scene.add( ambientLight );

    $("#demo-container").append( renderer.domElement );

    function render() {

        if ( doPostPro ) {

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

            // Render renderPass and SSAO shaderPass
            scene.overrideMaterial = null;
            effectComposer.render();
        }
        else {

            renderer.render( scene, camera );
        }
    }

    function animate() {

        requestAnimationFrame( animate );

        if ( window.animMixer != undefined ) {

            var deltaTime = clock.getDelta();
            animMixer.update(deltaTime);            
        }

        render();
    }

    animate();

    $(document).keyup(function(e) {

        // P is pressed.
        if ( e.which == 80 ) {

            window.doPostPro = !window.doPostPro;
        }
    });

});



</script>

【问题讨论】:

  • 请展示您的完整代码,最好链接到一个简单的实例。
  • 感谢您回复我。我在这里整理了一个非常简单的现场演示:demo.bgk.io 按 P 打开和关闭 SSAO。 (我也会用代码更新主帖)

标签: javascript three.js


【解决方案1】:

如果您正在蒙皮,并在渲染循环中使用此模式

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

你必须确保设置

depthMaterial.skinning = true;

问题是,如果场景中有其他元素没有被蒙皮,这样做会引发错误。在这种情况下,这可能是一个必须解决的 three.js 设计问题。

three.js r.77

【讨论】:

  • 太好了,非常感谢。这确实有效,但它确实会引发非蒙皮网格的错误。如果能够在 three.js 的未来版本中添加该功能,那就太好了。有没有办法让我引起任何人的注意或任何事情?可能是github页面上的问题?
  • 是的,您可以在three.js网站上发布功能请求。
猜你喜欢
  • 2013-02-27
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
相关资源
最近更新 更多