2

这是演示: 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 的值,你应该接近于零,对吧?但是,如果您运行演示,您会发现它变得更暗,但在某个中间色调灰度值处停止。

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

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

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

4

1 回答 1

4

这是因为颜色缓冲区存储离散值。在某一点

texel.rgb * scaleRate

当四舍五入时,以你开始时的结果结束——所以它永远不会变低。

事实上,你可以预测出近似的颜色。对于color0 到 255,求解

scaleRate * color = ( color - 0.5 )

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

于 2013-09-19T22:04:01.857 回答