如何渲染为无符号整数格式

时间:2014-12-16 16:26:07

标签: opengl textures glsl fbo render-to-texture

当渲染到具有无符号整数格式的FBO时,我可能不能:

gl_FragColour = uvec4(100,100,100,100);

因为gl_FragColour是vec4。所以我想我必须定义自己的?

out uvec4 colour

但这是否会在没有任何其他变化的情况下正确解释?

此外,我想对无符号整数格式和普通浮点纹理使用相同的着色器,并在统一(静态分支)上使用if。我猜这是不可能的(除非我可以有2个出局而且只设置一个?)我可能需要探索一个函数指针方法?

3 个答案:

答案 0 :(得分:8)

  

所以大概我要定义自己的?

是的,绝对的。您 必须 声明您自己的片段数据输出,以写入除浮点颜色值之外的任何内容。

请注意,“{ANR”(无符号规范化)格式(如GL_RGB8)将浮点颜色作为输入,即使它们是定点数据类型。真正的古怪实际上是OpenGL 3.0中引入的新INT / UINT格式;它们没有定义浮点到整数转换,因此只能使用整数颜色写入。

  

但这是否会在没有任何其他变化的情况下正确解释?

传统上会发生的是,钳制的值<[strong> 0.0 , 1.0 ],然后99%的时间输出颜色格式是无符号标准化的,每个组件都会重新缩放到定点范围(例如如果GL_RGB8 =&gt;(float_color * 255 ))

如果您有浮点或整数颜色缓冲区,则钳位和缩放行为不再适用,但当然如前所述,未定义将浮点颜色写入整数颜色缓冲区。这就是为什么当整数颜色格式(有符号和无符号整数)被引入核心GL时,gl_FragColor被弃用(GL 3.0)。

  

此外,我想对无符号整数格式和普通浮点纹理使用相同的着色器,并在统一(静态分支)上使用if。我猜这是不可能的(除非我可以有两个出局,只设置一个?)我可能不得不探索一个函数指针方法?

实际上, 可行。但它需要您使用两个不同的FBO图像附件位置。

想象一下以下着色器:

#version 330

uniform bool is_float;

layout(location = 0) out vec4  frag_color_float;
layout(location = 1) out uvec4 frag_color_uint;

void main (void) {
  if (is_float)
    frag_color_float = vec4 (0.1f, 0.2f, 0.3f, 1.0f);
  else
    frag_color_uint  = uvec4 (1,2,3,0xff);
}

在上面的场景中,您可以将传统的浮点或定点颜色缓冲区(GL_RGBA32FGL_RGBA8)附加到GL_COLOR_ATTACHMENT0和无符号整数颜色缓冲区({{ 1}})到GL_RGBA32UI

我不知道这种方法从长远来看有多实用,但它有可能。

答案 1 :(得分:2)

自GLSL 130以来,不推荐使用

gl_FragColor。从那时起,您可以为所需的片段着色器定义任何输出,尤其是uvec4格式:

layout(location = 0) out uvec4 fragColor;

void main()
{
    fragColor = uvec4(100,100,100,100);
}

如果帧缓冲区具有无符号整数格式,则应该没有任何问题。

答案 2 :(得分:0)

片段着色器的输出始终自动从0.0-1.0重新调整到适合FBO的范围。因此,无需更改着色器中的输出方式。