THREE.js透明度和EffectComposer

时间:2014-12-15 20:33:22

标签: javascript three.js post-processing

我试图在某种程度上组合纹理传递来保留alpha通道。我已经尝试过或确信过了。

  1. 渲染器已将alpha设置为true
  2. 具有许多不同setClearColor设置的渲染器。
  3. 效果传递使用的全屏四边形中的材质将透明度设置为true
  4. 纹理实际上是透明的
  5. 我用于组合的着色器使用alpha通道
  6. 纹理/传递所有绘制正确如果你注释掉其他人,我只是不能让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)
        })
    })
    

1 个答案:

答案 0 :(得分:0)

解决方案:

  

您可以在渲染器中尝试{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")