Trails 效果,清除带有透明四边形的帧缓冲区
Trails effect, clearing a frame buffer with a transparent quad
我想要一个轨迹效果。我正在将粒子绘制到帧缓冲区。永远不会被清除(累积绘图调用)。淡出是通过绘制一个带有小 alpha 的黑色四边形来完成的,例如 0.0, 0.0, 0.0, 0.1
。两步过程,每帧重复:
- 绘制黑色四边形
- 在新位置绘制粒子
一切正常,移动的粒子产生长尾迹,除了黑色四边形没有将 FBO 清除到完美的零。微弱的痕迹永远存在(例如缓冲区的 RGBA = 4,4,4,255)。
我假设当混合函数将 FBO 的 8 位 RGBA(目标颜色)的小值乘以例如 (1.0-0.1)=0.9 并且四舍五入阻止进一步减少时,问题就开始了。例如 4 * 0.9 = 3.6 -> 永远舍入为 4。
我的方法(画一个黑色四边形)对轨迹来说天生无用吗?我找不到可以提供帮助的混合函数,因为它们都将 DST 颜色乘以某个值,该值必须非常小才能产生长轨迹。
路径是使用代码绘制的:
GLuint drawableFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawableFBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO); /// has an attached texture glFramebufferTexture2D -> FBOTextureId
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(fboClearShader);
glUniform4f(fboClearShader.uniforms.color, 0.0, 0.0, 0.0, 0.1);
glUniformMatrix4fv(fboClearShader.uniforms.modelViewProjectionMatrix, 1, 0, mtx.m);
glBindVertexArray(fboClearShaderBuffer);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glUseProgram(particlesShader);
glUniformMatrix4fv(shader.uniforms.modelViewProjectionMatrix, 1, 0, mtx.m);
glUniform1f(shader.uniforms.globalAlpha, 0.9);
glBlendFunc(GL_ONE, GL_ONE);
glBindTexture(particleTextureId);
glBindVertexArray(particlesBuffer);
glDrawArrays(GL_TRIANGLES, 0, 1000*6);
/// back to drawable buffer
glBindFramebuffer(GL_FRAMEBUFFER, drawableFBO);
glUseProgram(fullScreenShader);
glBindVertexArray(screenQuad);
glBlendFuncGL_ONE dFactor:GL_ONE];
glBindTexture(FBOTextureId);
glDrawArrays(GL_TRIANGLES, 0, 6);
Blending is not only defined by the by the blend function glBlendFunc
, it is also defined by the blend equation glBlendEquation
.
默认情况下,源值和目标值在经过混合函数处理后相加。
使用混合函数从目标缓冲区中减去一个微小的值,因此目标颜色会在每一帧中略微降低,最终变为 0.0。
混合方程的结果被限制在 [0, 1].
范围内
例如
dest_color = dest_color - RGB(0.01)
从目标颜色中减去源颜色的混合方程是 GL_FUNC_REVERSE_SUBTRACT
:
float dec = 0.01f; // should be at least 1.0/256.0
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(fboClearShader);
glUniform4f(fboClearShader.uniforms.color, dec, dec, dec, 0.0);
我想要一个轨迹效果。我正在将粒子绘制到帧缓冲区。永远不会被清除(累积绘图调用)。淡出是通过绘制一个带有小 alpha 的黑色四边形来完成的,例如 0.0, 0.0, 0.0, 0.1
。两步过程,每帧重复:
- 绘制黑色四边形
- 在新位置绘制粒子
一切正常,移动的粒子产生长尾迹,除了黑色四边形没有将 FBO 清除到完美的零。微弱的痕迹永远存在(例如缓冲区的 RGBA = 4,4,4,255)。
我假设当混合函数将 FBO 的 8 位 RGBA(目标颜色)的小值乘以例如 (1.0-0.1)=0.9 并且四舍五入阻止进一步减少时,问题就开始了。例如 4 * 0.9 = 3.6 -> 永远舍入为 4。
我的方法(画一个黑色四边形)对轨迹来说天生无用吗?我找不到可以提供帮助的混合函数,因为它们都将 DST 颜色乘以某个值,该值必须非常小才能产生长轨迹。
路径是使用代码绘制的:
GLuint drawableFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawableFBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO); /// has an attached texture glFramebufferTexture2D -> FBOTextureId
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(fboClearShader);
glUniform4f(fboClearShader.uniforms.color, 0.0, 0.0, 0.0, 0.1);
glUniformMatrix4fv(fboClearShader.uniforms.modelViewProjectionMatrix, 1, 0, mtx.m);
glBindVertexArray(fboClearShaderBuffer);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glUseProgram(particlesShader);
glUniformMatrix4fv(shader.uniforms.modelViewProjectionMatrix, 1, 0, mtx.m);
glUniform1f(shader.uniforms.globalAlpha, 0.9);
glBlendFunc(GL_ONE, GL_ONE);
glBindTexture(particleTextureId);
glBindVertexArray(particlesBuffer);
glDrawArrays(GL_TRIANGLES, 0, 1000*6);
/// back to drawable buffer
glBindFramebuffer(GL_FRAMEBUFFER, drawableFBO);
glUseProgram(fullScreenShader);
glBindVertexArray(screenQuad);
glBlendFuncGL_ONE dFactor:GL_ONE];
glBindTexture(FBOTextureId);
glDrawArrays(GL_TRIANGLES, 0, 6);
Blending is not only defined by the by the blend function glBlendFunc
, it is also defined by the blend equation glBlendEquation
.
默认情况下,源值和目标值在经过混合函数处理后相加。
使用混合函数从目标缓冲区中减去一个微小的值,因此目标颜色会在每一帧中略微降低,最终变为 0.0。
混合方程的结果被限制在 [0, 1].
例如
dest_color = dest_color - RGB(0.01)
从目标颜色中减去源颜色的混合方程是 GL_FUNC_REVERSE_SUBTRACT
:
float dec = 0.01f; // should be at least 1.0/256.0
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(fboClearShader);
glUniform4f(fboClearShader.uniforms.color, dec, dec, dec, 0.0);