在C#中实现OpenGL INT_2_10_10_10_REV格式的法向量打包
问题:将float顶点法向量转换为OpenGL INT_2_10_10_10_REV 格式
我有3个范围在-1到1之间的float值表示顶点法向量,需要转换为OpenGL的INT_2_10_10_10_REV格式,但多次尝试都未成功,导致场景着色效果极差。
我曾尝试归一化数值并打包为10位整数,但显然存在错误,初始代码如下:
// 归一化并转换为整数(错误地使用1023,以为是10位整数的范围) int[] intNormals = new int[3] { Convert.ToInt32(1023 * ((2 * ((normals[2] - normals.Min()) / range)) - 1)), Convert.ToInt32(1023 * ((2 * ((normals[1] - normals.Min()) / range)) - 1)), Convert.ToInt32(1023 * ((2 * ((normals[0] - normals.Min()) / range)) - 1)) };
之后我尝试用位掩码和BitArrays处理intNormals,但可能存在多处错误。请问:是否有标准C#库可实现该功能?或有人能分享可用的C#实现代码?
更新:已解决问题,分享方案
通过以下步骤成功完成转换:
- 先使用Vector3归一化float值,再转换为整数:
Vector3 normalised = Vector3.Normalize(new Vector3(normals[0], normals[1], normals[2])); int[] intNormals = new int[3] { Convert.ToInt32(511 * normalised.X), Convert.ToInt32(511 * normalised.Y), Convert.ToInt32(511 * normalised.Z) };
注意:最初误用了1023而非正确的511,这是核心错误之一。
- 通过位掩码获取每个整数的最后10位:
int mask = Convert.ToInt32("1111111111", 2); int last10 = normal & mask;
- 修正位拼接顺序:之前错误地使用
[w][x][y][z]顺序,正确的拼接顺序应为[x][y][z][w](其中w为末尾2个未使用位)。
后续会研究用结构体优化实现。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

