1. 分解方式:缩放矩阵和平移矩阵
描述
将正交投影矩阵分为两步:
- 缩放矩阵 (
ortho_scale_Matrix
):将坐标范围缩放为标准化设备坐标的大小范围 ([-1, 1])。 - 平移矩阵 (
ortho_translate_Matrix
):将坐标范围居中到原点。
最后将两者相乘,得到完整的正交投影矩阵。
优点
- 逻辑清晰:分开处理缩放和平移,有助于理解和调试。
- 复用性高:缩放和平移可以独立用于其他变换,不必耦合在一起。
- 教育性强:便于教学和解释正交投影的原理。
示例代码
Eigen::Matrix4f ortho_scale_Matrix;
ortho_scale_Matrix << 2/(r-l), 0, 0, 0,
0, 2/(t-b), 0, 0,
0, 0, 2/(f-n), 0,
0, 0, 0, 1;
Eigen::Matrix4f ortho_translate_Matrix;
ortho_translate_Matrix << 1, 0, 0, -(r+l)/2,
0, 1, 0, -(t+b)/2,
0, 0, 1, -(f+n)/2,
0, 0, 0, 1;
Eigen::Matrix4f ortho_Matrix = ortho_scale_Matrix * ortho_translate_Matrix;
2. 合成方式:直接构造完整矩阵
描述
直接根据正交投影的数学公式构造完整的正交投影矩阵,而不是将缩放和平移分开。
优点
- 效率高:一次性计算完整矩阵,减少了矩阵相乘的计算成本。
- 代码简洁:省略了中间步骤,更加紧凑。
缺点
- 可读性低:难以直接看到缩放和平移的独立作用。
- 不易调试:如果矩阵结果出错,难以定位具体的问题来源。
示例代码
Eigen::Matrix4f ortho_Matrix;
ortho_Matrix << 2/(r-l), 0, 0, -(r+l)/(r-l),
0, 2/(t-b), 0, -(t+b)/(t-b),
0, 0, 2/(f-n), -(f+n)/(f-n),
0, 0, 0, 1;
3. 哪种方式更常用?
教育场景(如课程、教程中)
- 分解方式 更常用。
- 教学中需要详细讲解投影矩阵的构造原理。
- 将缩放和平移分开,可以帮助学生理解矩阵的作用。
- 有利于调试和实现其他变换。
实际工程中
- 合成方式 更常用。
- 在性能敏感的应用(如实时渲染)中,直接使用预先计算的完整矩阵更加高效。
- 代码量少且逻辑清晰,适合工业实现。
- 特别是 GPU 编程中,完整矩阵通常在 CPU 或着色器代码中直接给出。
灵活性和代码复用
- 如果一个框架或引擎需要支持复杂的变换组合(如正交投影、平移、旋转等),可能会分开实现缩放和平移的矩阵,以便灵活组合。
4. 实例:OpenGL 和 DirectX 的实现
-
OpenGL:
- OpenGL 提供了类似于
glOrtho
和glFrustum
的函数,直接生成完整的正交或透视投影矩阵,属于合成方式。 - 示例:
glOrtho(left, right, bottom, top, nearVal, farVal);
- OpenGL 提供了类似于
-
DirectX:
- DirectX 提供类似于
XMMatrixOrthographicLH
和XMMatrixPerspectiveFovLH
的函数,同样生成完整的投影矩阵,效率优先。
- DirectX 提供类似于
5. 建议
- 学习和教学:使用分解方式,便于理解和调试。
- 实际开发:使用合成方式,减少运算开销。
- 灵活场景:分解方式的矩阵可以组合使用,更加灵活,但需要注意性能优化。
在实际应用中,可以根据具体需求选择合适的方式,权衡代码的清晰度和性能。