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

chr*_*989 3 opengl fbo textures glsl render-to-texture

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

gl_FragColour = uvec4(100,100,100,100);
Run Code Online (Sandbox Code Playgroud)

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

out uvec4 colour
Run Code Online (Sandbox Code Playgroud)

但是如果没有任何其他变化,这将被正确解释吗?

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

And*_*man 8

所以我想我必须定义自己的?

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

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

但是如果没有任何其他变化,这将被正确解释吗?

传统上发生的事情是,该值被钳位到范围[ 0.0,1.0 ],然后自的输出颜色格式被无符号归一化,每个组件是重新缩放到定点范围(99%的时间例如如果GL_RGB8=> (float_color*255)).

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

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

实际上,这可行的.但它需要您使用两个不同的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);
}
Run Code Online (Sandbox Code Playgroud)

在上面的场景中,您将附加一个传统的浮点或定点颜色缓冲区(GL_RGBA32FGL_RGBA8)GL_COLOR_ATTACHMENT0和一个无符号整数颜色缓冲区(GL_RGBA32UI)GL_COLOR_ATTACHMENT1.

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

  • 我应该指出,如果你没有写入片段着色器的输出,那么该输出的值是未定义的...所以理论上,实现可以自由地写出它想要的任何内容,或者根本不对输出_*你*_没有写信给._"如果后续的固定功能消耗片段数据并且片段着色器可执行文件的执行没有向其写入值,那么消耗的片段数据是未定义的."_(有效地指出混合之类的东西将具有未定义的分支结果而不是拍摄). (2认同)