当前位置: 首页 > 知识库问答 >
问题:

带有FBO渲染纹理的OpenGL两遍着色器效果仅在Windows上产生噪声

汝跃
2023-03-14

执行以下操作的正确方法是什么:

  1. 使用FBO(fbo-a)将场景渲染为纹理
  2. 然后使用纹理(tex-a)应用效果并使用相同的fbo(fbo-a)将其渲染为另一个纹理(tex-b)
  3. 然后渲染这第二个纹理,应用效果(tex-b)为全屏四边形。

我的方法是这样的,但这给了我一个在应用效果窗口上充满“噪音”的纹理(所有像素都是随机着色的红、绿、蓝、白、黑)。

  • 我使用的是一个FBO,两个纹理分别设置为GL_COLOR_ATTACHENT0(tex-a)和GL_COLOR_ATTACHMENT1(tex-b)
  • 我绑定我的fbo,确保它使用glDrawBuffer(GL_COLOR_ATTACHMENT0)渲染到tex-a中。
  • 然后我在一个有tex-a边界的着色器中应用效果,并设置为“sampler2D”。使用纹理第一单元,并切换到第二个颜色附件(glDrawBuffer(GL\u color\u 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; 
    } 

}

我读过这篇关于opengl的FBO文章。org,他们在文章底部描述了一个反馈循环。这个描述对我来说并不完全清楚,我想知道我是否在做他们描述的事情。

更新1:

链接到源代码

更新2:

当我第一次设置gl_FragColor.rgb=vec3(0.0, 0.0, 0.0);在我开始采样循环之前(使用NUM_SAMPLES),它可以找到。虽然不知道为什么。

共有1个答案

彭博厚
2023-03-14

问题是您没有初始化gl_FragColor,而是在用行修改它

gl_FragColor += sample;

gl_FragColor *= u_exposure;

两者都取决于gl_FragColor的先前值。因此,你会得到一些随机垃圾(着色器编译器决定用于gl_FragColor计算的寄存器中发生的任何东西)。这很有可能在某些驱动程序/硬件组合上工作良好(因为编译器出于某种原因决定使用始终为0的寄存器),而在其他组合上则不工作。

 类似资料:
  • 我想在FBO中加载两个纹理,其中一个纹理包含HDR图像,我的第一个目标是将图像从第一个纹理“复制”到第二个纹理(该纹理为空),并称为“下采样纹理”。 所以我创建FBO,加载我想用颜色_附件_0书写的纹理,并绑定它;然后初始化我的着色器程序并渲染一个四边形,其中包含我要在GL\u texture\u 0中读取的纹理。 然后我解开FBO并绑定“DownSamplingTex”,然后画一个四元组。 我不

  • 我有一个非常简单的OpenGL应用程序,只渲染一个带纹理的四边形。这是我的代码,效果很好(带纹理的四边形看起来很好): 然后我想介绍一个简单的着色器。所以我稍微修改了我的代码: 顶点着色器: 片段着色器: 现在我得到的只是一个黑色的四边形:-( 我已经尝试并测试了很多东西: 着色器编译良好(无错误) 有人知道为什么我在使用着色器时看不到我的纹理吗?

  • 在一个教程之后,我将尝试使用FreeType在OpenGL中渲染文本。因此,灰度8位图像用作每个字符的纹理,使图像的每个字节对应于纹理的红色分量。 为了以其他颜色呈现文本,建议您使用着色器。但是,当使用提供的着色器时,我看到的不是彩色字母,而是彩色框,好像根本没有纹理。 以下是没有着色器时的效果: 这是它在着色器中的外观: (盒子的位置也会发生变化) 以下是顶点着色器代码: 这是片段着色器代码:

  • 我正在渲染很多轴对齐的3D立方体。每个立方体的中心位置和/或颜色可能不同于其他立方体。这就是我现在渲染它的方式 My DrawCube()使用和存储在VBO中的顶点数据,简单地渲染立方体每一侧对应的6个四边形。glVertexPointer和glColorPointer用于设置属性元素。 这是可行的,但是我想通过使用可能是glDrawElementsInst的()来使用即时渲染。但是由于项目的一些

  • 我一直在尝试渲染到一个FBO,并将两个FBO渲染到屏幕上,但在合并两个FBO时进行深度测试失败。我尝试使用计算着色器合并纹理,但无法读取深度纹理的值(所有值都是值1,但渲染到FBO时深度测试有效)。有人知道我做错了什么,或者知道其他方法来合并两个FBO吗? 以下是我创建FBO的方式: 以下是我向FBO渲染的方式: 我尝试用glBindTexture绑定纹理(所有值均为1): 计算着色器: 我已尝试

  • 纹理根本不渲染,几何体都是黑色的。 截图:http://i.imgur.com/ypMdQY4.png 代码:http://pastebin.com/SvB8rxxt 我也会链接到我试图渲染的纹理和transformations.py模块,但是我没有被允许放置两个以上链接的声誉。谷歌搜索“现代opengl 02”会给你前者的教程,“转换py”会给你后者。 搜索“纹理材料开始”以查找纹理材料的设置位