C++ OpenGL 4和ES 3.0与packHalf2x16/2x16不符
我很想问一个简洁的问题,让我有一个明确的答案,但我担心有太多关于FBO初始化的小事情我不完全理解,我需要澄清。我正在编写一个针对OpenGL 4.3和OpenGL ES 3.0的延迟着色器,前者的行为完全符合我的预期,但后者给了我无法确定问题来源的问题 首先,我将描述我对为GL 4.2和ES 3.0设置MRT FBO的理解/困惑,希望有人能够纠正任何误解C++ OpenGL 4和ES 3.0与packHalf2x16/2x16不符,c++,opengl,opengl-es,glsl,glsles,C++,Opengl,Opengl Es,Glsl,Glsles,我很想问一个简洁的问题,让我有一个明确的答案,但我担心有太多关于FBO初始化的小事情我不完全理解,我需要澄清。我正在编写一个针对OpenGL 4.3和OpenGL ES 3.0的延迟着色器,前者的行为完全符合我的预期,但后者给了我无法确定问题来源的问题 首先,我将描述我对为GL 4.2和ES 3.0设置MRT FBO的理解/困惑,希望有人能够纠正任何误解 OpenGLES3.0规范说它支持“四个或更多的渲染目标”,但没有提到(我可以找到)这些渲染目标的规范。关于这些渲染目标的大小,可以安全地假设
RGBA32F
(四个32位浮点通道)?在我看来,这是着色器编写到RTs的关键假设/知识。常见程序是:尝试创建具有特定规格的固定基地运营商,然后测试固定基地运营商的完整性?如果失败:减少要求并使用替代着色器来补偿减少的位深度highp
、mediump
、lowp
究竟用于什么,以及它们如何与渲染目标的位深度一起发挥作用。首先,我假设渲染目标的位深度是在FBO中确定和配置的,并且精度限定符自动匹配这一点,这使我认为高
、中
和低
与32
、16
、8
深度位有某种关系。我已经看过了OpenGL ES 3.0规范,但还不是很清楚glTexStorage2D
(使用target=GL\u texture\u 2D
,levels=1
)配置的,我认为在这里使用它比glTexImage2D
更正确,因为只有internalformat
才重要glFramebufferTexture2D
将(3.)中配置的纹理附加到FBOsCOLOR_附件
奇怪的地方(
packHalf2x16
/unpackHalf2x16
):
假设我使用两种颜色附件设置FBO,第一种(RT1
)使用internalformatGL_RGBA32UI
,第二种(RT2
)使用GL_RGBA32F
。对象在两个过程中渲染。第一个是FBOs RTs,然后两个是由默认帧缓冲区处理的全屏四元组
为了简化,我将只关注在两个阶段之间传递RGB颜色数据。我尝试了三种不同的方式:
RT2
,将颜色数据定期存储为浮点,将其读取为浮点纹理,并将其输出到默认帧缓冲区RT1
,存储转换为uint
的颜色数据(每个通道在[0,…,255]
中),将其读取为uint
纹理,将其转换为float[0,1]
,并将其输出到默认帧缓冲区RT1
,使用packHalf2x16
将颜色数据打包到一个半通道中。将其作为uint
纹理读取,然后使用unpachalf2x16
将其转换回float不确定代码细节的相关性/重要性(我将迅速跟进任何请求)。我对
float
和int
都使用了highp
。第一个过程的渲染目标定义为:
layout (location = 0) out uvec4 fs_rt1;
layout (location = 1) out vec4 fs_rt2;
在第二个过程中,作为纹理访问:
uniform highp usampler2D RT1;
uniform highp sampler2D RT2;
...
// in main():
uvec4 rt1 = texelFetch(RT1, ivec2(gl_FragCoord.xy), 0);
vec4 rt2 = texelFetch(RT2, ivec2(gl_FragCoord.xy), 0);
方法1.
:
// in first pass:
fs_rt2.rgb = decal.rgb;
// in second pass:
color = vec4(rt2.rgb, 1.0);
方法2.
:
// in first pass:
fs_rt1.rgb = uvec3(decal.xyz * 256.0f);
// in second pass:
color = vec4(vec3(rt1.xyz)/256.0f, 1);
方法3.
:
// in first pass:
fs_rt1.x = packHalf2x16(decal.xy);
fs_rt1.y = packHalf2x16(vec2(decal.z, 0.0f));
// in second pass:
vec2 tmp = unpackHalf2x16(rt1.y);
color = vec4(vec3(unpackHalf2x16(rt1.x), tmp.x), 1);
在方法
1
、2
和3
中,桌面总账输出如下所示:
在Nexus 5上,方法1
和2
OpenGL ES 3.0输出如下所示:
nexus 5上的方法3
看起来如下:
我不明白为什么第三种方法在OpenGLES3.0上失败。如有任何帮助或建议,将不胜感激。我并不反对阅读文档,因此如果您只想为我指出正确的方向,这也会有所帮助。关于前几个问题:
GL\u MAX\u COLOR\u ATTACHMENTS
以获取可以附加到FBO的彩色附件的数量。对于ES 3.0,这保证大于4。这与颜色附件的格式无关(无论是渲染缓冲还是纹理)。但是,对于可以渲染到的格式有一些限制。请查看表格,特别是“颜色可渲染”列。这使您知道可以附加到FBO的格式。代码不需要测试FBO的完整性,但不是因为多个颜色附件。检查所有附件是否具有相同数量的样本和其他特定于供应商的内容,如深度/模板附件