我正在使用 FireMonkey 创建一个 3D 场景,效果很好:相机设置,在下图中,三个拉伸的立方体显示了三个轴(红色 X、绿色 Y、蓝色 Z。)
FireMonkey 中的普通 3D 透视图 -
Projection
是pjCamera
.
但是,这是一个透视 3D 场景,我想要一个正交 3D 投影——也就是说,对象的大小不会随着距离的增加而减小。(最终的想法是使用它来显示 3D 等距视图。) FireMonkey 似乎没有正交投影代码 -pjCamera
转换为使用透视矩阵。
我根本不需要透视 3D 视图,因此通过用创建正交矩阵的方法替换透视矩阵方法来解决这个问题。也就是说,TContext3D.GetProjectionMatrix
(获取透视矩阵)调用MatrixPerspectiveFovRH
计算透视矩阵:
Result := MatrixPerspectiveFovRH(cPI / 4, FWidth / FHeight, 1.0, 1000.0);
我将其替换为对正交矩阵的调用:
Result := IdentityMatrix3D;
Result.m11 := 2 / FWidth;
Result.m22 := 2 / FHeight;
Result.m33 := 1 / (zn - zf);
Result.m43 := zn / (zn - zf);
其中zn
= 1 和zf
= 1000。 FWidth
是以像素为单位的视图宽度(例如 320)和FHeight
以像素为单位的高度,例如 240。
这最初似乎可以正常工作,尽管离物体比我预期的要远:
问题是渲染图像似乎不再随相机位置而变化。我已经验证了世界视图矩阵的计算方式相同(即不受我的更改影响),但是当我将相机移近(0,0,0)时,可见对象会被修剪,但渲染图像本身不会改变。例如,在这里我将相机移动到非常靠近 (0,0,0) 的位置,这是相同相机位置的透视图和正交渲染图:
显然,我计算正交投影的方式有问题,但我不知道。
- 我确实知道更改正交计算中使用的宽度和高度似乎会使对象越来越近 - 较小的宽度和高度会使它们更靠近屏幕。
- 我相当确定正交矩阵设置应该是正确的 - 尽管显然这是错误的:)
- 虽然它在底层使用了 DirectX,但透视矩阵是右手矩阵,所以正交矩阵也应该是。
我已经阅读了很多关于如何设置正交矩阵的内容,但显然不是正确的东西。例如:
- 做
width
并height
表示屏幕宽度和高度,或其他东西 - 例如截头锥体?假设它们是显而易见的,我读到的任何内容都没有解释这些是什么。 - 如果它们是其他东西,我可以从哪里提取它们的值?如果允许计算,我可以从透视矩阵中提取它们吗?
谢谢您的帮助。