OpenGL从未绑定的纹理单元读取数据

4

OpenGL标准规定了,如果程序没有将uniform sampler2D绑定到纹理单元,texture2d操作的结果应该是什么吗?

例如,在像素着色器中:

layout(binding=0) uniform sampler2D Map_Diffuse;
...
texture2D(Map_Diffuse, attrib_Fragment_Texture)

程序中的位置:

::glActiveTexture(GL_TEXTURE0); 
::glBindTexture(GL_TEXTURE_2D, 0);

背景是我想知道是否可以对纹理和非纹理实体使用同一个着色器,只需确保将GL_TEXTURE_2D绑定到纹理2d(texture2d())返回0、0、0、1。否则我将需要为每个排列组合使用一个着色器。


可能是在OpenGL中绑定零纹理的重复问题。 - Bahbar
是的,谢谢。回答了我的问题! - Robinson
2个回答

4
据我阅读规范,保证返回黑色。以下引用摘自3.3规范。
在第81页“顶点着色器”下的第2.11.7节中:
如果采样器关联的纹理未完全定义,使用顶点或几何着色器中的采样器将返回(R,G,B,A) = (0,0,0,1),如第3.8.14节所定义。
并且在第188页“片段着色器”下的第3.9.2节中同样适用:
如果采样器关联的纹理未完全定义,使用片段着色器中的采样器将返回(R,G,B,A) = (0,0,0,1),如第3.8.14节所定义。
在第3.8.14节“纹理完整性”中,它说:
如果利用纹理应用程序所需的所有图像数组和纹理参数都被一致地定义,则称纹理是完整的。
现在,它并没有明确说明甚至不存在的纹理对象。但由于不引用纹理对象(包括0)的纹理名称肯定没有“所有图像数组和纹理参数一致定义”,我认为它们属于上述定义中的“不完整”。

2

如果程序没有绑定一个统一的sampler2D到一个纹理单元,OpenGL标准是否规定了texture2d操作的结果应该是什么?

当一个纹理采样器没有绑定到一个纹理对象时,默认会绑定到纹理对象0/null,这就像C/C++中的null。当访问null对象时,根据我的经验你会得到零值。例如:

 vec2 Data = texture(unboundSampler, textureCoords); 

Data通常是零,但我的假设是这取决于实现,有些驱动程序可能会崩溃。

为了上下文,我想知道是否可以对纹理和非纹理实体使用相同的着色器

在我的引擎中,我通过创建一个默认的白色纹理来解决这个问题,该纹理由代码生成并在引擎初始化时使用。当我想要使用具有纹理采样器的着色器并且相应的材料没有纹理时,我分配默认的白色纹理。这样我就可以重复使用同一个着色器。如果您非常关心性能,您可能希望为无纹理对象使用没有纹理的着色器。

标准没有讨论实现,但它鼓励您将零对象视为非功能对象。 https://www.opengl.org/wiki/OpenGL_Object#Object_zero


这是个好主意,但通常情况下,如果程序尝试执行其不应该执行的操作,我更喜欢它们彻底崩溃。我讨厌驱动程序和库对错误输入具有鲁棒性。它们并没有为程序员带来任何好处。你知道我的意思吗?我仍然想知道标准是否有相关规定。 - Robinson
@Robinson编辑了答案以澄清。 - concept3d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接