2

假设我遇到了这样的问题:现在我有一个帧缓冲区,并且纹理只包含一个颜色组件(例如,GL_RED)已经绑定到它。片段着色器会是什么样子?我想答案是:

... out float ex_color;

ex_color = ...;

我的问题来了:着色器会自动检测帧缓冲区的格式并向其中写入值吗?如果片段着色器输出浮点值但帧缓冲区格式是 GL_RGBA 怎么办?

顺便说一句,创建纹理只有一个组件的正确方法是什么?我从 g-truc 中阅读了示例,其中包含如下示例:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RED,GLsizei(Texture.dimensions().x), GLsizei(Texture.dimensions().y), 0,GL_RGB, GL_UNSIGNED_BYTE, 0);

将 GL_RGB 分配为像素数据格式是什么意思?

4

2 回答 2

6

就像顶点着色器输入不必与 glVertexAttribPointer 指定的数据的确切大小相匹配一样,片段着色器输出不必与它们正在写入的图像的确切大小相匹配。如果输出提供的组件多于目标图像格式,则忽略额外的组件。如果它提供的更少,则其他组件具有未定义的值(与顶点输入不同,其中未指定的值具有明确定义的值)。

将 GL_RGB 分配为像素数据格式是什么意思?

这就是像素传输格式。这描述了您提供给 OpenGL 的像素格式,而不是 OpenGL 将它们存储为的格式。

您应该始终使用大小合适的内部格式,而不是像GL_RED.

于 2013-07-30T17:51:35.410 回答
3

有关内部格式和格式的体面解释,请参见:

http://opengl.org/wiki/Image_Formathttp://opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml

您基本上需要 GL_RED 作为格式,并且可能需要 GL_R8(无符号归一化 8 位定点)作为内部格式。

很久以前,亮度纹理是单通道的标准,但在现代 GL 中这是一种已弃用的格式,而红色现在是单通道的逻辑“可绘制”纹理格式,就像红/绿是最合乎逻辑的格式一样为双通道。

至于您的着色器,核心规范定义了组件扩展规则。如果您有一个带有 1 个通道的纹理作为输入,但将其采样为 vec4,则它将等效于:vec4 (RED, 0.0, 0.0, 1.0)。

写入纹理有点不同。

来自 OpenGL 4.4 规范,第 15.2 节(着色器执行),第 441 页——http: //www.opengl.org/registry/doc/glspec44.core.pdf

When a fragment shader terminates, the value of each active user-defined output variable is written to components of the fragment color output to which it is bound. The set of fragment color components written is determined according to the variable’s data type and component index binding, using the mappings in table 11.1 [pp. 341].

默认情况下,如果片段着色器的输出是浮点数,它将写入纹理的 x(红色)分量。您可以使用布局限定符(例如layout (component=1) out float color;)来指定它应该写入 y(绿色)、z(蓝色)或 w(alpha)(假设您有 RGBA 纹理)。

于 2013-07-30T17:47:14.543 回答