【问题标题】:3D graphics: Changing object's world position relative to it's screen position3D 图形:更改对象相对于屏幕位置的世界位置
【发布时间】:2013-07-15 17:29:33
【问题描述】:

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

我需要我的游戏在任何方面都无视距离。

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

我需要这个,因为我想到了特定的机制,并且我需要它在 3d 世界中,因为我需要在游戏中拥有准确的阴影。

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

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

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

附:顺便说一句,感谢您的编辑,它看​​起来确实更好。

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

【问题讨论】:

    标签: 3d orthogonal


    【解决方案1】:

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

    输入

    假设给你一个

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

    结果

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

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

    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 也是一种解决方案。

    【讨论】:

    • 我没有提到我在 c#/XNA 中编码,也许那里有一个内置函数已经计算了这个?因为对我来说,试图编写你的解释真的很可怕:)。
    • Erm 是的,我认为是 :) ...我刚刚发现这个问题很有趣:找到一个恒定的屏幕空间速度。如果您愿意,我会尝试修改我对 XNA/C# 代码的回答。我实际上提出的另一个解决方案是定义屏幕空间中的所有移动。然后通过ray casting 将屏幕空间位置映射到您的 3d 平面
    • 我的游戏有一些我需要实现的特定机制以及一些视觉效果。也就是说,我需要角色以屏幕空间速度移动以实现平滑瞄准(瞄准将通过移动发生),但我还需要角色在死亡时爆炸成许多血腥位:)。而且由于第二部分很可能是手动实现的(物理引擎集成将是一种矫枉过正且太困难的事情),我更喜欢将角色实际定位在 3d 世界中的平面上,这样我就可以更灵活地进行逼真的创作- 看起来很血腥:)。
    • 无论如何我都会非常感谢一个 c# 代码或至少一些有用的功能,我肯定会深入研究你提供的光线投射链接。
    • 忽略我的帖子#3,我现在明白你的意思了:)。如果没有现成的 c#/xna 实现,很可能是光线投射。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-04
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多