You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:52:54