4

我想将场景淡入灰度,但这也适用于我想淡入或淡出的其他后处理效果。

所以对于这个例子,我使用了 THREE.ColorifyShader,但是当激活它时,整个场景会立即接收到预期的颜色

如何“应用不透明度/alpha”进行后期处理?

代码示例:

var effectColorify,
    copyPass;

    effectColorify = new THREE.ShaderPass(THREE.ColorifyShader);
    effectColorify.uniforms['color'].value.setRGB(0.8, 0.8, 0.8); // Grayscale

    copyPass = new THREE.ShaderPass(THREE.CopyShader);
    copyPass.renderToScreen = true;

    this.composerGrayscale = new THREE.EffectComposer(this.engine.renderer);
    this.composerGrayscale.addPass(this.renderPass);
    this.composerGrayscale.addPass(effectColorify);
    this.composerGrayscale.addPass(copyPass);
4

2 回答 2

2

我通过向着色着色器添加“不透明度”制服解决了这个问题。这允许通过增加不透明度或相反的方式从正常的彩色场景平滑地混合到某种颜色。

effectColorify.uniforms['opacity'].value = 0.5; // 50% scene-color, 50% shader-color.

这是调整后的着色器代码,您可以将其复制到 ColorifyShader.js,它向后兼容以前的版本,因为默认不透明度为 1.0:

THREE.ColorifyShader = {

    uniforms: {

        "tDiffuse": { type: "t", value: null },
        "color":    { type: "c", value: new THREE.Color( 0xffffff ) },
        "opacity":  { type: "f", value: 1.0 }

    },

    vertexShader: [

        "varying vec2 vUv;",

        "void main() {",

            "vUv = uv;",
            "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",

        "}"

    ].join("\n"),

    fragmentShader: [

        "uniform float opacity;",
        "uniform vec3 color;",
        "uniform sampler2D tDiffuse;",

        "varying vec2 vUv;",

        "void main() {",

            "vec4 texel = texture2D( tDiffuse, vUv );",

            "vec3 luma = vec3( 0.299, 0.587, 0.114 );",
            "float v = dot( texel.xyz, luma );",

            "vec3 finalColor = vec3(",
                "(opacity * v * color.x) + ((1.0 - opacity) * texel.x),",
                "(opacity * v * color.y) + ((1.0 - opacity) * texel.y),",
                "(opacity * v * color.z) + ((1.0 - opacity) * texel.z)",
            ");",

            "gl_FragColor = vec4( finalColor, texel.w );",

        "}"

    ].join("\n")

};
于 2014-12-25T08:18:15.600 回答
0

您可以添加一个计时器来缓慢增加 RGB 值。或将其添加到渲染循环中,我将使用计时器,但可以在渲染函数中应用完全相同的循环。

var interval = 200; //interval for the animation in ms
var darkness = 1; //we'll start with a fade in, so we need the darknes at its biggest value
var fade = 'in';

var effectTimer = setInterval(function(){
    switch(fade){

        case 'in':
            if(darkness > 0){
                darkness -= 0.1;
            }
            else{
                fade = 'off';
            }
        break;

        case 'out':
            if(darkness < 1){
                darkness += 0.1;
            }
            else{
                fade = 'off';
            }
        break;
    }
    effectColorify.uniforms['color'].value.setRGB(darkness, darkness, darkness);
}, interval)
于 2014-12-24T15:12:52.763 回答