GLSL片段着色器输出类型

时间:2013-07-30 10:01:38

标签: opengl glsl framebuffer

假设我遇到这样的问题:现在我有一个帧缓冲区,并且纹理只包含一个颜色组件(例如,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指定为像素数据格式是什么意思?

2 个答案:

答案 0 :(得分:6)

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

  

将GL_RGB指定为像素数据格式是什么意思?

那是pixel transfer format。这描述了您为OpenGL提供的像素格式,而不是OpenGL将它们存储为的格式。

您应该始终使用sized internal formats,而不是GL_RED等未经过身份验证的人。{/ p>

答案 1 :(得分:3)

有关内部格式和格式的合理解释,请参阅:

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

您基本上希望GL_RED用于格式,并且可能需要GL_R8(无符号标准化8位定点)作为内部格式。

很久以前,亮度纹理是单通道的标准,但在现代GL中这是一种不推荐的格式,红色现在是合乎逻辑的" drawable"单通道的纹理格式,就像红色/绿色是双通道的最合理格式一样。

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

写入纹理有点不同。

从OpenGL 4.4规范,第15.2节(着色器执行),第262页 - 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. 340].

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