这是演示: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/
答案 0 :(得分:3)
这是因为颜色缓冲区存储了离散值。在某些时候
texel.rgb * scaleRate
当四舍五入时,最终会得到你开始的东西 - 所以它永远不会降低。
事实上,您可以预测近似颜色。对于0到255之间的color
,解决
scaleRate * color = ( color - 0.5 )
对于scaleRate
= 0.995,color
= 100.我在演示中观察到96。