为什么我的Fade-to-Black着色器不会一直变黑?

时间:2013-09-19 19:48:49

标签: three.js webgl

这是演示:http://percentcer.github.io/poi3d/

我在黑色背景上画了一个形状,我想给它一些“光迹”效果,我认为我可以通过保持前一帧缓冲并使每帧“变暗”来实现(即在片段着色器中,将每个片段向量缩放小于1的值,假设最终颜色将会接近vec4(0.0,0.0,0.0,a))。

每一帧,我重绘前一帧的片段* some_scalar,在其上绘制对象,然后通过复制着色器将其发送到屏幕。我通过EffectComposer完成所有这些操作,使用如下。

初​​始化:

composer  = new THREE.EffectComposer( renderer );

shDim = new THREE.ShaderPass( THREE.DimShader );
composer.addPass( shDim );

var scenePass  = new THREE.RenderPass( scene, camera );
composer.addPass( scenePass );

var shCopy = new THREE.ShaderPass( THREE.CopyShader );
composer.addPass( shCopy );

动画循环:

shDim.uniforms[ 'prevTDiffuse' ].value = composer.writeBuffer;
composer.render();

https://github.com/percentcer/poi3d/blob/master/js/logic.js#L61

DimShader本身并不复杂:

fragmentShader: [

        "varying vec2 vUv;",

        "uniform sampler2D tDiffuse;",
        "uniform sampler2D prevTDiffuse;",
        "uniform float scaleRate;",

        "void main() {",

            "vec4 texel = texture2D( prevTDiffuse, vUv );",
            "gl_FragColor = vec4( texel.rgb * scaleRate, texel.a );",

        "}"

    ].join("\n")

因此,反复将值乘以小于1的值,你应该接近零,对吗?但是,如果您运行the demo,您会看到它变得更暗,但会停在某个中间色调灰度值。

默认缩放率为0.995,您可以通过向上翻页和向下翻页来更改。如果你以更快的速度(0.95,从默认状态向下翻页一次),淡出将更接近黑色,但实际上从未到达它,它挂在(非常暗)灰色。我的一些朋友认为这是浮动精度问题的症状。我还认为这可能是一个混合问题,其中alpha值被缩放到0.0,所以在某些时候新的像素颜色停止显示,但是当我强制alpha为1.0时会发生这种情况。

我很感激任何帮助,我是three.js和GLSL的新手。我有一些openGL经验,但也认为自己也是初学者。谢谢!

哦,这里也是完整的回购:https://github.com/percentcer/poi3d/

1 个答案:

答案 0 :(得分:3)

这是因为颜色缓冲区存储了离散值。在某些时候

texel.rgb * scaleRate

当四舍五入时,最终会得到你开始的东西 - 所以它永远不会降低。

事实上,您可以预测近似颜色。对于0到255之间的color,解决

scaleRate * color = ( color - 0.5 )

对于scaleRate = 0.995,color = 100.我在演示中观察到96。