【发布时间】:2014-06-15 19:13:22
【问题描述】:
我在片段着色器中使用了一个简单的开/关开关。我想将运动模糊通道的输出与未处理的输出进行比较,因此我在片段着色器中添加了一个布尔统一,如下所示:
uniform boolean blur;
我像这样激活它(基于键盘输入和一个名为 blur 的全局 int):
if ( key == 'b' ) blur = !blur;
glUseProgram( program );
glUniform1i( blur_loc, blur );
然后在着色器中用我所有的其他制服声明它:
uniform bool blur;
然后这样读:
if ( blur ) {
FragColor = texture( color_texture, uv );
} else {
FragColor = color/MAX_SAMPLES;
}
现在这里是有趣的部分......当我删除 if 子句时,这两个 FragColor 语句中的任何一个都可以正常工作。硬编码到 FragColor 没有模糊它看起来像这样:
使用模糊硬编码到 FragColor,如下所示:
buuuut...一旦我添加了 if 子句,就会呈现第三个(!)意外图像...看起来被夸大了,或添加了混合或其他东西...像这样:
到底发生了什么?如何添加一个布尔 if 子句导致呈现完全不同的图像?我唯一可以假设的是,存在某种内存损坏或着色器由于某种原因运行了两次(看起来像是我添加了两个图像)......可能是什么原因造成的,我在使用像傻瓜一样统一布尔值?
更新
似乎在 if 子句中,非模糊片段写入充当添加剂,而模糊片段写入正常...无论我将它们放在什么顺序。什么给出?
if ( blur ) {
FragColor = texture( color_texture, uv ); // writes an odd compound image
} else {
FragColor = color/MAX_SAMPLES; // correctly writes a blurred image
}
或
if ( blur ) {
FragColor = color/MAX_SAMPLES; // correctly writes a blurred image
} else {
FragColor = texture( color_texture, uv ); // writes an odd compound image
}
同样,如果我去掉 if 子句并只使用其他语句之一,它们会正确地写入非模糊图像或模糊图像...
FragColor = color/MAX_SAMPLES; // correctly writes a blurred image
或
FragColor = texture( color_texture, uv ); // correctly writes a non-blurred image
更新 2
所以我发现一些文档在条件语句中完成状态纹理采样时未定义......(下面的 cmets 之一也建议这样做)。但是,即使纹理采样发生在 if 语句之外,行为也是相同的:
vec4 sampled_color = texture( color_texture, uv );
if ( blur ) {
FragColor = color/MAX_SAMPLES; // correctly writes a blurred image
} else {
FragColor = sampled_color; // writes an odd compound image
}
更新 3
在 keltar 的评论让我将 blur 的值绘制到屏幕上以确保它将屏幕变成全黑或全白(确实如此)之后,我决定尝试一个非常基本的 if-then 或者写一个蓝色片段或红色片段取决于我传入的布尔值:
if ( blur ) {
FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
} else {
FragColor = vec4( 0.0, 0.0, 1.0, 1.0 );
}
当然,这行得通。不过,这就是有趣的地方...
if ( blur ) {
FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
} else {
FragColor = color/MAX_SAMPLES;
}
也可以使用......就像
if ( blur ) {
FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
} else {
FragColor = texture( color_texture, uv );
}
只有当我感兴趣的两件事都涉及到时:(
if ( blur ) {
FragColor = texture( color_texture, uv ):
} else {
FragColor = color/MAX_SAMPLES;
}
也许值得注意的是,变量color 也以纹理样本的形式开始了它的生命,实际上是同一个:
vec4 color = texture( color_texture, uv );
情节变厚了?
更新 4
这是完整的着色器,(基于chapter 27 of GPU GEMS 3)
#version 150
in vec2 vUV;
out vec4 FragColor;
uniform sampler2D depth_tiu;
uniform sampler2D color_tiu;
uniform mat4 P;
uniform mat4 V;
uniform mat4 V_prev;
uniform bool blur;
void main() {
float z_over_w = texture( depth_tiu, vUV ).r;
vec4 view_pos = vec4( 2*vUV.x - 1, 2*(1 - vUV.y) - 1, z_over_w, 1.0 );
vec4 D = P * V * view_pos;
vec4 world_pos = D/D.w;
vec4 previous_world_pos = P * V_prev * view_pos;
previous_world_pos /= previous_world_pos.w;
vec2 velocity = vec2((world_pos - previous_world_pos)/2.0);
velocity = clamp( velocity, vec2(-0.001, -0.001), vec2(0.001, 0.001) );
int MAX_SAMPLES = 10;
vec4 color = texture( color_tiu, vUV );
vec2 write_UV = vUV;
write_UV += velocity;
for ( int i = 0; i < MAX_SAMPLES; ++i, write_UV += velocity ) {
vec4 curr_color = texture( color_tiu, write_UV );
color += curr_color;
}
if ( blur ) {
FragColor = color/MAX_SAMPLES;
} else {
FragColor = texture( color_tiu, vUV );
}
【问题讨论】:
-
如果您将条件表达式提取到另一段代码中,然后将一个值分配给
FragColor,该怎么办?还有,FragColor变量是什么类型的? -
FragColor 在 vec4...没有 if 子句)它按预期工作,第二个 FragColor 正确指示结果...
-
您确定您的
blur_loc实际上是blurs 的位置,而不是color?将模糊投射到颜色上,看看是否正确。 -
肯定的,当我抓取
*_loc变量时,我会打印它们...color_texture_loc是 8,blur_loc是 9。 -
你说的有些不对劲。
texture(color)的意思是texture(color_texture)?在这种情况下,仅将采样颜色除以某个常数不会产生模糊效果;那它是从哪里来的呢?奇迹不会发生在软件中(好吧,除非内存没有损坏)。