Javascript THREE.js transparency and EffectComposer

Javascript THREE.js transparency and EffectComposer,javascript,three.js,post-processing,Javascript,Three.js,Post Processing,我试图以某种方式组合纹理过程,以保留alpha通道。我已经试过或者保证过了 渲染器已将alpha设置为true 具有许多不同setClearColor设置的渲染器 效果过程使用的全屏四边形上的材质的透明度设置为true 这些纹理实际上是透明的 我用于组合的着色器使用alpha通道 纹理/过程都画得很好,如果你把其他的注释掉,我就是无法让PNG1.png与gits.jpg混合 var width = window.innerWidth; var height = window.innerHeigh

我试图以某种方式组合纹理过程,以保留alpha通道。我已经试过或者保证过了

  • 渲染器已将alpha设置为true
  • 具有许多不同setClearColor设置的渲染器
  • 效果过程使用的全屏四边形上的材质的透明度设置为true
  • 这些纹理实际上是透明的
  • 我用于组合的着色器使用alpha通道
  • 纹理/过程都画得很好,如果你把其他的注释掉,我就是无法让PNG1.png与gits.jpg混合

    var width = window.innerWidth;
    var height = window.innerHeight;
    var updateFcts    = [];
    
    var masterRenderer = new THREE.WebGLRenderer({
        alpha: true,
        autoClear: false
    });
    masterRenderer.setSize( window.innerWidth, window.innerHeight );
    masterRenderer.setClearColor ( 0xFFFFFF, 1.0);
    document.body.insertBefore( masterRenderer.domElement, document.body.firstChild);
    
    var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
    var renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
    var masterComposer = new THREE.EffectComposer(masterRenderer, renderTarget);
    
    var gitsTexture = THREE.ImageUtils.loadTexture( "images/gits.jpg" );
    var pngTexture = THREE.ImageUtils.loadTexture( "images/PNG1.png" );
    
    // declare passes
    var passes = {};
    passes.toScreen = new THREE.ShaderPass(THREE.CopyShader); passes.toScreen.renderToScreen = true;
    passes.gitsTexturePass = new THREE.TexturePass(gitsTexture);
    passes.gitsTexturePass.material.transparent = true;
    passes.pngTexturePass = new THREE.TexturePass(pngTexture);
    passes.pngTexturePass.material.transparent = true;
    
    //add passes
    masterComposer.addPass(passes.gitsTexturePass);
    masterComposer.addPass(passes.pngTexturePass);
    masterComposer.addPass(passes.toScreen);
    
    // render the webgl
    
    updateFcts.push(function(delta,now){
        masterComposer.render();
    })
    
    
    //////////////////////////////////////////////////////////////////////////////////
    //      handle resize                           //
    //////////////////////////////////////////////////////////////////////////////////
    
    function onResize(){
        width = window.innerWidth;
        height = window.innerHeight;
        // notify the renderer of the size change
        masterRenderer.setSize( window.innerWidth, window.innerHeight );
        // update the camera
        camera.aspect   = window.innerWidth / window.innerHeight
        camera.updateProjectionMatrix();
        resizeFcts.forEach(function(resizeFn){resizeFn()})
    }
    
    window.addEventListener('resize', onResize, false)
    
    //////////////////////////////////////////////////////////////////////////////////
    //      loop runner                         //
    //////////////////////////////////////////////////////////////////////////////////
    var lastTimeMsec= null
    requestAnimationFrame(function animate(nowMsec){
        // keep looping
        requestAnimationFrame( animate );
        // measure time
        lastTimeMsec    = lastTimeMsec || nowMsec-1000/60
        var deltaMsec   = Math.min(200, nowMsec - lastTimeMsec)
        lastTimeMsec    = nowMsec
        // call each update function
        updateFcts.forEach(function(updateFn){
            updateFn(deltaMsec/1000, nowMsec/1000)
        })
    })
    
    解决方案:

    您可以在渲染器中尝试{premultipliedAlpha:false} 构造函数,但如果 你这样做

    这个评论处理了我最初的问题


    我不知道我的问题到底在哪里。我的最佳猜测是,当使用CopyShader时,您的纹理会“预倍增”。我找到了一个解决方法,通过编写一个着色器,将alpha的倍数恢复到原来的效果

        fragmentShader: [
    
    
        "uniform sampler2D tBase;",
        "uniform sampler2D tAdd;",
        "uniform float amount;",
    
        "varying vec2 vUv;",
    
        "void main() {",
    
            "vec4 t1 = texture2D( tBase, vUv );",
            "vec4 t2 = texture2D( tAdd, vUv );",
            "gl_FragColor = (t1 * (1.0 - t2.a))+(t2 * t2.a);",
    
        "}"
    
    ].join("\n")
    

    一个活生生的例子将有助于。。。此外,您没有正确设置
    autoClear
    。使用
    renderer.autoClear=false同样,你有
    alpha:true
    ,但是你的clearAlpha是1.0。非常感谢你的时间,我设法达到了我想要的效果,但仍然不知道是什么导致了最初的问题。你可以在渲染器构造函数中尝试
    {premultipledalpha:false}
    ,但是如果你这样做的话,你需要小心混合模式。就是这样!我的项目朝着一个不同(更好)的方向发展,但那是我的问题。如果您想将此评论复制粘贴到答案中,我将接受。您只需在下面更新您的答案即可。:-)