In my OpenGL ES 3.0+ apps I use non-normalized GL_INT_2_10_10_10_REV data types which is perfectly fine according to specs - https://docs.gl/es3/glVertexAttribPointer
When porting to Metal I've found that it does support 10_10_10_2 data type for vertex attributes but only as normalized ones - https://developer.apple.com/documentation/metal/mtlvertexformat
iOS 12 used to support OpenGL ES 3.0 which means hardware is perfectly capable of handling both normalized and non-normalized 10_10_10_2 data types.
Am I missing something or is this indeed an artificial limitation by Apple?
Metal doesn't provide additional flag for normalized attribute so it indeed seems like they just "forgot" that 10_10_10_2 could be useful as non-normalized too... I know this is not quite typical usage for this data type but precision is good enough for my use case and it is more compact than 3 half floats.
Currently I see two workarounds to alleviate this:
- De-normalize data in vertex shader with multiplication by 512.
- Re-export meshes to use half floats instead of this more compact packed data type.
Please advise.
Unfortunatenyl, I don't think there's a version of
MTLVertexFormatUInt1010102NormalizedorMTLVertexFormatInt1010102Normalizedthat is not normalized.What you could do instead is write a vertex shader manually that reads a 32-bit value from the buffer and decomposes into the same non-normalized 10-bit components with another one being 2-bit using regular bitwise functions.
More unfortunately, there isn't even a version of the
pack/unpackfunctions such asunpack_unorm10a2_to_halfthat accepts or outputs non-normalized values.