【问题标题】:GLSL fragment shader output typeGLSL 片段着色器输出类型
【发布时间】:2013-07-30 10:05:26
【问题描述】:

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

【问题讨论】:

  • 我认为GL_RED 不是有效的内部格式。你需要的是一个真实大小的内部格式(很可能是GL_R8)。
  • 所以这就是我感到困惑的地方。但毕竟这个样本在我运行它时运行良好。并且能详细解释一下函数 glTexImage2D 的内部格式、格式和类型吗?
  • “所以这就是我感到困惑的地方。” - 这不是你真正感到困惑的唯一事情。但是我现在没有时间对所有这些东西做出一个好的大规模解释,所以我希望 Nicol Bolasdatenwolf 或其他人跳进去,对所有这些问题给出真正的答案。
  • @ChristianRau:注意GL_RED 有效的内部格式。这不是一个的;您应该始终使用具有明确大小的内部格式。
  • @NicolBolas 哦,我认为 RG 纹理是在非大小的通用格式已经被认为是一个坏主意并且引入通用 RG 格式时引入的(即使那样我也会认为它是GL_R 而不是GL_RED)。我认为GL_RED 仅适用于客户端像素格式。感谢您的澄清。

标签: opengl glsl framebuffer


【解决方案1】:

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

将GL_RGB赋值为像素数据格式是什么意思?

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

您应该始终使用sized internal formats,而不是像GL_RED 这样的小号。

【讨论】:

  • 所以函数glTexImage2D的“内部格式”参数表示颜色分量是如何存储在内存中的,“格式”参数只是表示从用户内存中选取的分量的顺序?我可以认为OpenGL总是以“内部格式”存储颜色,您可以告诉Opengl如何解释数据并通过指定像素传输格式将它们复制到内存中吗?
  • @user2310794:“OpenGL 始终将颜色存储在四个组件中”纹理存储您告诉它们存储的内容。
  • 是的,这是我犯的一个错误……我现在很清楚,非常感谢!
【解决方案2】:

有关内部格式和格式的详细解释,请参阅:

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 纹理)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    相关资源
    最近更新 更多