带有FBO渲染到纹理的OpenGL双过程着色器效果仅在窗口上产生噪波
执行以下操作的正确方法是什么:带有FBO渲染到纹理的OpenGL双过程着色器效果仅在窗口上产生噪波,opengl,glsl,shader,textures,fbo,Opengl,Glsl,Shader,Textures,Fbo,执行以下操作的正确方法是什么: 使用FBO(FBO-a)将场景渲染为纹理 然后使用纹理(tex-a)应用效果,并使用相同的fbo(fbo-a)将其渲染为另一个纹理(tex-b) 然后使用应用效果(tex-b)将第二个纹理渲染为全屏四边形 我的方法是这样的,但这给了我一个在窗口上填充“噪波”的纹理+应用效果(所有像素都随机着色为红色、绿色、蓝白色和黑色) 我使用的是一个FBO,两个纹理分别设置为GL_COLOR_ATTACHENT0(tex-a)和GL_COLOR_ATTACHMENT1(tex
- 我使用的是一个FBO,两个纹理分别设置为GL_COLOR_ATTACHENT0(tex-a)和GL_COLOR_ATTACHMENT1(tex-b)
- 我绑定我的fbo,确保它使用glDrawBuffer(GL_COLOR_ATTACHMENT0)渲染到tex-a中
- 然后,我在一个具有tex-a边界的着色器中应用该效果,并将其设置为“sampler2D”。使用纹理单元1,并切换到第二个颜色附件(glDrawBuffer(GL_color_ATTACHMENT1))。并渲染一个全屏四边形。现在,所有内容都渲染为tex-b
- 然后我切换回默认的FBO(0),并使用tex-b和全屏四边形渲染结果
attribute vec4 a_pos;
attribute vec2 a_tex;
varying vec2 v_tex;
void main() {
mat4 ident = mat4(1.0);
v_tex = a_tex;
gl_Position = ident * a_pos;
}
uniform int u_mode;
uniform sampler2D u_texture;
uniform float u_exposure;
uniform float u_decay;
uniform float u_density;
uniform float u_weight;
uniform float u_light_x;
uniform float u_light_y;
const int NUM_SAMPLES = 100;
varying vec2 v_tex;
void main() {
if (u_mode == 0) {
vec2 pos_on_screen = vec2(u_light_x, u_light_y);
vec2 delta_texc = vec2(v_tex.st - pos_on_screen.xy);
vec2 texc = v_tex;
delta_texc *= 1.0 / float(NUM_SAMPLES) * u_density;
float illum_decay = 1.0;
for(int i = 0; i < NUM_SAMPLES; i++) {
texc -= delta_texc;
vec4 sample = texture2D(u_texture, texc);
sample *= illum_decay * u_weight;
gl_FragColor += sample;
illum_decay *= u_decay;
}
gl_FragColor *= u_exposure;
}
else if(u_mode == 1) {
gl_FragColor = texture2D(u_texture, v_tex);
gl_FragColor.a = 1.0;
}
}
片段着色器
attribute vec4 a_pos;
attribute vec2 a_tex;
varying vec2 v_tex;
void main() {
mat4 ident = mat4(1.0);
v_tex = a_tex;
gl_Position = ident * a_pos;
}
uniform int u_mode;
uniform sampler2D u_texture;
uniform float u_exposure;
uniform float u_decay;
uniform float u_density;
uniform float u_weight;
uniform float u_light_x;
uniform float u_light_y;
const int NUM_SAMPLES = 100;
varying vec2 v_tex;
void main() {
if (u_mode == 0) {
vec2 pos_on_screen = vec2(u_light_x, u_light_y);
vec2 delta_texc = vec2(v_tex.st - pos_on_screen.xy);
vec2 texc = v_tex;
delta_texc *= 1.0 / float(NUM_SAMPLES) * u_density;
float illum_decay = 1.0;
for(int i = 0; i < NUM_SAMPLES; i++) {
texc -= delta_texc;
vec4 sample = texture2D(u_texture, texc);
sample *= illum_decay * u_weight;
gl_FragColor += sample;
illum_decay *= u_decay;
}
gl_FragColor *= u_exposure;
}
else if(u_mode == 1) {
gl_FragColor = texture2D(u_texture, v_tex);
gl_FragColor.a = 1.0;
}
}
uniformintu\u模式;
均匀的二维u_纹理;
均匀浮动u__曝光;
均匀浮u_衰减;
均匀浮球密度;
均匀浮球重量;
均匀浮动u___x;
均匀浮球;
const int NUM_SAMPLES=100;
可变矢量2 v_tex;
void main(){
如果(u_mode==0){
屏幕上的vec2位置=vec2(u灯x、u灯y);
vec2 delta_texc=vec2(v_tex.st-pos_on_screen.xy);
vec2 texc=v_tex;
delta_texc*=1.0/浮点数(样本数)*u密度;
浮动照明衰减=1.0;
对于(int i=0;i
我在opengl.org上读过这篇文章,他们在文章的底部描述了一个反馈循环。这个描述对我来说并不完全清楚,我想知道我是否在做他们描述的事情
更新1:
更新2:
当我第一次设置
gl_FragColor.rgb=vec3(0.0,0.0,0.0)代码>在启动采样循环(使用NUM_SAMPLES)之前,它可以工作。不知道为什么。问题是您没有初始化gl\u FragColor
,而是用行修改它
gl_FragColor += sample;
及
两者都取决于gl_FragColor的先前值。因此,您将得到一些随机垃圾(着色器编译器决定用于gl_FragColor计算的寄存器中发生的任何东西)添加到中。这很有可能在某些驱动程序/硬件组合上运行良好(因为编译器出于某种原因决定使用始终为0的寄存器),而在其他组合上运行不好。这看起来可能是一个绑定错误的纹理,你能发布你的FBO/纹理设置代码吗?Stugray,我在帖子底部添加了链接。Stugray,还添加了一个修复。。。虽然没有回答。谢谢克里斯!我确实通过设置gl_FragColor修复了它。