3D图形:相对于屏幕位置更改对象的世界位置

时间:2013-05-08 12:29:43

标签: 3d orthogonal

我正在实施一款带有相机视图的游戏,如暗黑破坏神3(3D表面上的三维物体,自上而下的视图),但我有一个限制:

我需要在任何方面忽视距离。

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

我需要这个,因为我想到的具体机制,我需要它在一个3D世界,因为我在游戏中有什么准确的阴影。

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

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

你们有什么想法可以做到这一点吗?

P.S。感谢您编辑btw,它看起来确实更好。

编辑:我在c#/ XNA编码

2 个答案:

答案 0 :(得分:3)

数学不是很整齐,但我希望它适合你:

输入

假设你有一个

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

结果

  • 缩放系数a,用于在世界空间中沿V_dir移动屏幕空间中的对象“v_screen”单位。因此,您希望实际移动对象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解决这个问题。我用我的Mathematica为你计算a。如果您想了解更多详情,我可以详细说明答案。 假设MXV_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也是一种解决方案。

答案 1 :(得分:-1)

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