2

我正在使用 FireMonkey 创建一个 3D 场景,效果很好:相机设置,在下图中,三个拉伸的立方体显示了三个轴(红色 X、绿色 Y、蓝色 Z。)

FireMonkey 中的普通 3D 透视图

FireMonkey 中的普通 3D 透视图 -ProjectionpjCamera.

但是,这是一个透视 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,但透视矩阵是右手矩阵,所以正交矩阵也应该是。

我已经阅读了很多关于如何设置正交矩阵的内容,但显然不是正确的东西。例如:

  • widthheight表示屏幕宽度和高度,或其他东西 - 例如截头锥体?假设它们是显而易见的,我读到的任何内容都没有解释这些是什么。
  • 如果它们是其他东西,我可以从哪里提取它们的值?如果允许计算,我可以从透视矩阵中提取它们吗?

谢谢您的帮助。

4

1 回答 1

2

YouTube 上有很棒的视频。搜索“夸克立方”。一个 - 显然 - 德国开发商有一些很棒的视频,展示了 Firemonkey 中的大量 3D 编程。

对您提出问题 - 这对我有用:如果虚拟形状是您的形状的父级,则需要 2 个简单的更改:

这些调用将视图设置为正交: 在虚拟事件“OnRender”调用中:
Context.SetCameraViewAngle(0.1);
虚拟 Scale.Point 属性必须设置为:
Dummy.Scale.Point:= TPoint3D.Create(1, 1, 1) / 45;

要恢复到透视视图:
Dummy.Scale.Point:= TPoint3D.Create(1, 1, 1); Context.SetCameraViewAngle(45);

上面的代码对我有用。不,我绝对不是专家,但上面的代码是从一个 2 年前的 YouTube 视频中提取的:“教程:Utah teapot in lineframe with Orthogonal view (FireMonkey XE6 / Delphi XE6)”-频道“Quark Cube”。
顺便说一句,我使用的是 Berlin 10.2,所以它也适用于该版本。
希望这对其他有同样问题的开发人员有所帮助和有用。

于 2017-01-31T10:41:41.553 回答