1

我正在实现一个带有摄像机视图的游戏,如暗黑破坏神 3(3d 表面上的 3d 对象,自上而下的视图),但我有一个限制:

我需要我的比赛在任何方面都无视距离。

这包括让所有 3d 模型在屏幕上的任何位置以相同的角度面对相机,在屏幕上的任何位置具有相同的大小并以相同的速度移动(屏幕空间方面)。

由于我考虑到了特定的机制,我需要它,并且我需要它处于 3d 世界中,因为我需要在游戏中拥有准确的阴影。

我知道如何实现每个功能(主要是通过使用正交投影和一些着色器魔法),但最后一个,即我无法理解如何移动 3d 对象,该对象位于 3d 平面上,具有相同的屏幕空间速度.

如果对象位于屏幕的上部,它会移动得更慢,反之亦然,所以我确实需要一些代码来弥补这一点。

你们知道如何做到这一点吗?

PS 感谢您的编辑顺便说一句,它看起来更好。

编辑:我在 c#/XNA 中编码

4

2 回答 2

3

不是很整洁的数学,但我希望它对你有用:

输入

假设给你一个

  • worldViewPerspectiveMatrix M(将世界空间转换为透视空间,正交矩阵也应该可以工作!)
  • 屏幕空间中的恒定速度(更具体地说是每帧的距离)v_screen
  • 世界空间中的(归一化)方向向量V_dir,这将给出对象移动的方向。将计算矢量的实际长度。
  • X您的对象放置在世界空间中的位置。

结果

  • 用于在屏幕空间中沿世界空间a移动对象“v_screen”单位的比例因子。V_dir因此,您实际上想要移动您的对象X += a*V_dir

首先,我们使用齐次坐标和 w-clipping将世界空间映射到屏幕空间的公式。.表示矩阵乘法运算符。

X_proj := M.(x,y,z,1);
X_screen := (x_proj/w_proj,y_proj/w_proj);

从那里我们可以指定对象X在屏幕空间中的位置以及应用定向移动后的位置X+(a*V_dir)

屏幕空间的长度以及所需的距离(每帧)很简单

Length[(X+(a*dir))_screen - X_screen] == v_screen.

让我们解决这个问题a。我用我的 Mathematicaa为你计算。如果您想了解更多详细信息,我可能会详细说明答案。假设M,XV_dir

         / xp \          / vx \                        / vxp \
X_proj = | yp |  V_dir = | vy |    V_proj = M.V_dir =  | vyp |
         | zp |          | vz |                        | vzp |
         \ wp /          \ 0  /                        \ vwp /

并且v_screen是您想要的屏幕空间速度。然后a是:

vlen = v_screen*v_screen;
a = (-dwp*vlen*wp + dxp*xp + dyp*yp + 
    0.5*Sqrt(
       Power(-2*dwp*vlen*wp + 2*dxp*xp + 2*dyp*yp,2)  - 
       4*(dxp*dxp + dyp*dyp - dwp*dwp*vlen)*(xp*xp + yp*yp - wp*wp*vlen)
       )
    ) /
    (dxp*dxp + dyp*dyp - dwp*dwp*vlen);

记住,-a也是一种解决方法。

于 2013-05-13T15:30:23.107 回答
-1

猜猜看,由于正交视图的特殊性,只需将正交矩阵指定为 Projection 即可自行解决所有问题。模型以相同的速度移动,并保持它们所在位置的大小。然而,唯一的问题是当你改变屏幕分辨率时,世界并不能适应它。所以我们必须使用依赖于当前屏幕分辨率的缩放因子来在游戏加载时手动缩放我们的世界。

于 2013-07-15T09:29:33.707 回答