着色器将 uint8 转换为浮动,并将其重新解释回 uint
Posted
技术标签:
【中文标题】着色器将 uint8 转换为浮动,并将其重新解释回 uint【英文标题】:Shaders casting uint8 to float, and reinterpretting it back to uint 【发布时间】:2019-11-17 09:03:46 【问题描述】:我有一个顶点属性被我的着色器非常奇怪地咀嚼。它以(uint8)1
的形式上传到VBO,但是当片段着色器看到它时,它被解释为10653532160
或0x3F800000
,你们中的一些人可能会将其识别为浮点中1.0f
的位模式。
我不知道为什么?我可以确认它以 1 (0x00000001
) 的形式上传到 VBO。
顶点属性定义为:
struct Vertex
...
glm::u8vec4 c2; // attribute with problems
;
// not-normalized
glVertexAttribPointer(aColor2, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, c2));
虽然着色器具有与该属性绑定的属性
glBindAttribLocation(programID, aColor2, "c2");
顶点着色器非常顺利地通过属性:
#version 330
in lowp uvec4 c2; // <-- this value is uploaded to the VBO as 0x00, 0x00, 0x00, 0x01;
flat out lowp uvec4 indices;
void main()
indices = c2;
最后片段着色器得到了它:
flat in lowp uvec4 indices; // <-- this value is now 0, 0, 0, 0x3F800000
out lowp vec4 fragColor;
void main()
fragColor = vec4(indices) / 256.0;
根据我的着色器检查器,indices
变化将顶点着色器作为 0x3F800000
用于 indices.w
,所以那里发生了一些奇怪的事情?这可能是什么原因造成的?
【问题讨论】:
【参考方案1】:如果顶点属性的类型是整数,那么你必须使用glVertexAttribIPointer
而不是glVertexAttribPointer
(关注I
)。见glVertexAttribPointer
。
glVertexAttribPointer
中指定的类型是源缓冲区中数据的类型,并没有指定着色器中的目标属性类型。如果使用glVertexAttribPointer
,那么shader程序中属性的类型就假设为浮点数,转换成整数数据。
如果您使用glVertexAttribIPointer
,那么这些值将保留为整数值。
【讨论】:
哦,那是被****了......我永远不会怀疑100年后,谢谢 @AnneQuinn 我第一次使用积分属性时遇到了同样的问题。不客气。以上是关于着色器将 uint8 转换为浮动,并将其重新解释回 uint的主要内容,如果未能解决你的问题,请参考以下文章
将 datetime 转换为 Unix 时间戳并将其转换回 python