【问题标题】:three.js fade in/out post processing shadersthree.js 淡入/淡出后处理着色器
【发布时间】:2015-02-22 12:05:58
【问题描述】:

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

所以对于这个例子,我使用了 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);

【问题讨论】:

    标签: three.js shader fadein fadeout post-processing


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您可以添加一个计时器来缓慢增加 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)
      

      【讨论】:

      • 我也找到了这样一个例子,但这并不是我想要的。假设我有一个漂亮的彩色场景,现在我想将这个场景淡化为灰度、红色或白色或任何颜色。单独使用颜色统一我只能从灰度(红色,蓝色等)到黑色和背面,但不能从单色到多色。我认为我必须向着色器添加一个不透明度统一值,并仅使用不透明度给出的因子应用计算值,然后像您的示例中那样交叉淡化不透明度。
      • 那么你可能不得不使用HSL 值而不是RGB
      • HSL只是另一种写RGB的方式,结果是一样的。我实际上尝试了我的想法(添加不透明度)并且效果很好。如果您需要,可以从我的答案中获取修改后的着色器代码。
      猜你喜欢
      • 2022-09-16
      • 2019-12-15
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 2013-03-17
      • 2016-05-14
      • 1970-01-01
      • 2018-07-24
      相关资源
      最近更新 更多