如何归一化世界矩阵?保留旋转并重置缩放至1、平移至原点
解决方案:提取旋转信息并重置矩阵的缩放与平移
完全可以做到——不需要记住之前的缩放值,就能从修改后的世界矩阵中提取纯旋转信息,生成一个缩放为1、平移为(0,0,0)的矩阵,同时保留原有的旋转姿态。
具体步骤
提取并归一化轴向量:
图形API中常用的4x4世界矩阵(列主序),前三个列向量分别对应物体的X、Y、Z局部轴方向。缩放操作会让这些轴向量的长度等于缩放因子(比如你乘了0.5,轴向量长度就是0.5)。对每个轴向量做归一化,就能消除缩放的影响,得到纯旋转对应的轴方向。- 注意:如果原矩阵存在非均匀缩放或者浮点精度误差,直接归一化后的三个轴可能不再正交,这时候需要用叉乘重新计算正交轴,保证矩阵的旋转正确性:
- 归一化X轴向量
- 用归一化后的X轴和原Y轴叉乘得到Z轴,再归一化
- 用新的Z轴和X轴叉乘得到正交的Y轴,再归一化
- 注意:如果原矩阵存在非均匀缩放或者浮点精度误差,直接归一化后的三个轴可能不再正交,这时候需要用叉乘重新计算正交轴,保证矩阵的旋转正确性:
构建目标矩阵:
将归一化后的三个正交轴向量作为新矩阵的前三列,第四列设为(0, 0, 0, 1)(清零平移分量),最后一行保持(0, 0, 0, 1)即可。如果是行主序矩阵,就把轴向量作为前三行,第四行设为(0, 0, 0, 1)。
为什么之前法线会失效
法线的正确变换需要使用世界矩阵逆矩阵的转置。你直接缩放矩阵对角元素后,原矩阵的逆矩阵缩放因子是原缩放的倒数,若直接用原矩阵变换法线,法线长度会被缩放,导致光照(包括光晕效果)计算出错。换成纯旋转矩阵后,逆矩阵等于转置矩阵,法线变换后长度保持不变,效果就能恢复正常。
伪代码示例
// 列主序4x4矩阵的处理函数 Matrix4x4 ExtractRotationMatrix(Matrix4x4 scaledWorldMatrix) { // 提取并归一化X轴 Vector3 xAxis = {scaledWorldMatrix.m00, scaledWorldMatrix.m10, scaledWorldMatrix.m20}; xAxis = Normalize(xAxis); // 计算正交的Z轴并归一化 Vector3 yAxisTemp = {scaledWorldMatrix.m01, scaledWorldMatrix.m11, scaledWorldMatrix.m21}; Vector3 zAxis = Cross(xAxis, yAxisTemp); zAxis = Normalize(zAxis); // 计算正交的Y轴并归一化 Vector3 yAxis = Cross(zAxis, xAxis); yAxis = Normalize(yAxis); // 构建纯旋转矩阵,平移清零 Matrix4x4 rotationOnlyMatrix = { xAxis.x, yAxis.x, zAxis.x, 0.0f, xAxis.y, yAxis.y, zAxis.y, 0.0f, xAxis.z, yAxis.z, zAxis.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; return rotationOnlyMatrix; }
内容的提问来源于stack exchange,提问作者KiraHoneybee
相关产品推荐
相关产品推荐

