在我的 OpenGL ES 3.0+ 应用程序中,我使用非标准化
GL_INT_2_10_10_10_REV
数据类型,根据规范,这完全没问题 - https://docs.gl/es3/glVertexAttribPointer
移植到 Metal 时,我发现它确实支持顶点属性的
10_10_10_2
数据类型,但仅限于标准化数据类型 - https://developer.apple.com/documentation/metal/mtlvertexformat
iOS 12 过去支持 OpenGL ES 3.0,这意味着硬件完全能够处理标准化和非标准化数据类型。
我错过了什么还是这确实是苹果人为的限制? Metal 没有为标准化属性提供额外的标志,所以看起来他们确实只是“忘记”了10_10_10_2
也可以用作非标准化属性...我知道这对于这种数据类型来说不是很典型的用法,但精度是对于我的用例来说已经足够好了,而且它比 3 个半浮点数更紧凑。
目前我看到两种解决方法可以缓解这个问题:将顶点着色器中的数据乘以 512 进行反标准化。
10_10_10_2
或
MTLVertexFormatUInt1010102Normalized
没有未标准化的版本。您可以手动编写一个顶点着色器,从缓冲区读取 32 位值,并使用常规按位函数分解为相同的非标准化 10 位组件,另一个组件为 2 位组件。
更不幸的是,甚至没有
MTLVertexFormatInt1010102Normalized
/
pack
函数的版本,例如 unpack
接受或输出非标准化值。