2014-12-24 4 views
1

Я хочу вывести сцену в оттенки серого, но это также относится к другим эффектам пост-обработки, которые я хотел бы угаснуть или выпустить.three.js fade in/out post processing shaders

Так для этого примера я использую THREE.ColorifyShader, но при его активации, вся сцена мгновенно получает предназначен цвета

Как можно «применить непрозрачности/альфа» для пост-обработки?

Пример кода:

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

ответ

0

Я решил проблему, добавив формулу «непрозрачность» к цветному шейдеру. Это позволяет плавно смешиваться с обычной, окрашенной сценой до определенного цвета, увеличивая непрозрачность или наоборот.

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

}; 
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) 
+0

Я нашел такой пример, тоже, но это не совсем то, что я ищу. Допустим, у меня хорошая сцена и цветная сцена, и теперь я хочу, чтобы эта сцена исчезла в оттенках серого, или красном, или белом или вообще. Используя только один цвет, я могу только перейти от оттенков серого (красный, синий и т. Д.) К черному и обратно, но не от одноцветного до многоцветного. Я думаю, что мне нужно добавить равномерное значение непрозрачности в шейдер и применить рассчитанное значение только к коэффициенту, заданному непрозрачностью, а затем перечеркнуть непрозрачность, как в вашем примере. – Artimus

+0

, то вам, вероятно, придется играть со значениями [HSL] (http://en.wikipedia.org/wiki/HSL_and_HSV) вместо RGB –

+0

HSL - это еще один способ записи RGB, результат тот же. Я действительно пробовал то, что имел в виду (добавление непрозрачности), и он отлично работает. Если вам когда-нибудь понадобится, вы можете взять измененный код шейдера из моего ответа. – Artimus