我看过{several)(semi) - (related)(posts)(about)这个,但没有人回答以下问题直接:
当
时glTexImage.D
确切地将输入值钳位到[0,1]?
文档似乎暗示总是(可能除了GL_DEPTH_STENCIL,我似乎记得不允许这样做,尽管文档不支持这一点)。这就是我目前在我的代码中处理它的方式。
其他链接源似乎表明,数据在转换为标准化颜色格式时会被精确限制,或者仅在图像格式为整数时才会被钳制。为了证实这一点,我测试了一个GL_RGBAF32内部格式:负浮点数据被钳位到0,而正数据根本没有被钳位。
然后是(所有组合)无符号/有符号规范化/非规范化整数内部格式。
那么,像素解包时,特别是glTexImage.D
,何时钳制数据?我对GL_((R|RG|RGB|RGBA)((8|16|32)(|I|UI|_SNORM)|(16F|32F))|DEPTH_COMPONENT(16|24|32))
特别感兴趣(即所有颜色浮点和整数纹理,加上所有深度纹理),但可能所有内部格式都应该被解决。
答案 0 :(得分:0)
从技术上讲,它不需要夹住任何东西。
此行为定义的一个地方是像素传输操作。换句话说,如果内部格式和传输到纹理中的数据格式不同,那么可能会发生许多有趣的事情,包括缩放/钳位到某个范围。如果您正确匹配内部格式和像素传输格式,则可以避免隐式归一化和图像数据的钳位,因为不需要进行转换。
当然,像素传输只是钳位的一个来源。在GL4.3中,您可以在多个纹理对象之间共享基础数据存储,并使用texture views更改兼容图像类(例如任何32位纹理格式)的内部格式。例如,这可用于在采样时将UNORM图像数据重新解释为SNORM。
<小时/> 我应该解释像
GL_RGB8
这样的东西是定点的......更具体地说,它是无符号归一化(UNORM)。如果您使用GL_RGBA32F
作为像素传输格式将图像数据传输到GL_RGBA
图像,并将GL_UNSIGNED_BYTE
作为数据类型GL将其解释为来自GL_RGBA8
的转换(来源格式)到GL_RGBA32F
(内部格式)。
在GLES中,您必须始终匹配这些格式,因为未定义像素传输转换。但是,在桌面GL中,此示例仅在[ 0.0 , 1.0 ]范围内生成值。如果您希望范围为[ -1.0 , 1.0 ],则需要使用SNORM格式。
如果您尝试从具有不同内部格式和目标格式的纹理中读取,那么它也会以相反的方式工作。如果要在纹理中输入/输出正确的值,则需要避免像素传输转换。
8.4.4.2转换为浮点
此步骤仅适用于浮点组件组。它不对索引或整数组件执行。对于包含组件和索引的组,例如
GL_DEPTH_STENCIL
,索引不会被转换。组中的每个元素都转换为浮点值。对于无符号或有符号整数元素,方程 2.1 或 2.2 分别为使用
该规范将在稍后进一步阐明所有类图像数据的这种行为:
如部分 8.4.4 中所述,将所选组转移到GL,然后将其限制为内部格式的可表示范围。如果纹理的内部格式是有符号或无符号整数,则组件被钳制到[ -2 n-1 , 2 n-1 - 1 ]或[ 0 , 2 n - 1 ],其中n是每个组件的位数。对于颜色分量组,如果纹理的内部格式是有符号或无符号标准化定点,则组件被限制为[ -1 , 1 ]或[ 0 , 1 ]。对于深度组件组,深度值被限制为[ 0 , 1 ]。否则,不会修改值。模板索引值被2 n - 1屏蔽,其中 n 是内部格式分辨率中的模板位数(见下文)。如果基本内部格式为
GL_DEPTH_STENCIL
且格式不是GL_DEPTH_STENCIL
,则模板索引纹理组件的值未定义。