Math 广告牌精灵绘画背后的数学原理是什么?(逆矩阵)

Math 广告牌精灵绘画背后的数学原理是什么?(逆矩阵),math,matrix,graphics,rendering,raycasting,Math,Matrix,Graphics,Rendering,Raycasting,我在这个网站上学习“光线投射教程”,以便在2D地图中创建一个3D透视图,类似于一个名为“光线投射”的老游戏 以下是目前为止的结果,如图所示: 我所困惑的是渲染始终面向摄影机方向的公告牌2d精灵背后的数学 以下是billboard 2d sprite的外观: 我遵循了关于精灵渲染的教程,你可以在这里找到它,我设法在我的场景中显示广告牌精灵,正如你在第一幅图像中看到的,在教程中,他们使用了逆矩阵, 他们将精灵的相对位置乘以摄影机矩阵的倒数 精灵的相对位置与2个坐标组合,因为我们正在处理2d地图,

我在这个网站上学习“光线投射教程”,以便在2D地图中创建一个3D透视图,类似于一个名为“光线投射”的老游戏

以下是目前为止的结果,如图所示:

我所困惑的是渲染始终面向摄影机方向的公告牌2d精灵背后的数学

以下是billboard 2d sprite的外观:

我遵循了关于精灵渲染的教程,你可以在这里找到它,我设法在我的场景中显示广告牌精灵,正如你在第一幅图像中看到的,在教程中,他们使用了逆矩阵, 他们将精灵的相对位置乘以摄影机矩阵的倒数

精灵的相对位置与2个坐标组合,因为我们正在处理2d地图,如下所示:

摄像机矩阵如下所示:

在我前面提到的教程中,他们将精灵的相对位置乘以摄影机矩阵的倒数,如下所示:

但我不明白它是如何工作的,为什么我们需要将摄像机矩阵的倒数乘以精灵矩阵,我想了解它背后的逻辑,这个公式如何使精灵旋转,始终朝向摄像机方向?!
我在游戏开发方面还是新手。

首先,我需要一些数学背景:

2D的2x2矩阵仅包含旋转矩阵。这意味着:

mat2 m;    // rotation matrix
vec2 a,b;  // 2D points

b = m*a;   // rotates a by m and stores into b
如果乘以逆:

mat2 n;
n = inverse(m);
b = n*b;
您获得了原始位置
a
,因为逆矩阵和正矩阵相乘是单位矩阵:

           b =            m*a 
inverse(m)*b = inverse(m)*m*a 
inverse(m)*b =              a 
然而,在2D光线投射器中使用矩阵是非常不寻常的,因为它使事情变得复杂。见:

此外,仅使用旋转矩阵意味着您必须在旋转之前或之后自行偏移/平移。我打赌你在代码中做的事情如下:

a = rotation_matrix*a;
a += translation;
a = Inverse(rotation_matrix)*a;
正如我在纯旋转矩阵的注释中提到的,转置函数与其逆函数相同,因此对于2D:

m = a0 a1    inverse(m) = transpose(m) = a0 a2
    a2 a3                                a1 a3
有关矩阵的更多信息,请查看:

有更多可能的数学表示法(使用正矩阵或逆矩阵、行/列主顺序、乘法顺序等,这可能会稍微改变方程式)

但是,您的矩阵描述似乎不正确。应该是:

| camerax.x cameray.x |
| camerax.y cameray.y |
所以基本上是世界坐标系中的两个方向向量(一个用于相机/播放器的x轴,一个用于y轴)(但相机平面法线平行于另一个方向,所以它是相同的…只是混淆了很多)

现在我是这么看的:

播放器是您的相机,因此您需要操作系统将精灵世界位置
sw
转换为播放器坐标
sp
。然后只需将精灵渲染为平行于player
xz
平面(或任何其他轴配置不同的轴)

因此,让
mp
成为球员轮换矩阵和
pp
球员世界位置,然后:

sp = mp*(sw-pp)
将精灵转换为玩家坐标。然而,根据你的引擎,你可能需要一个与玩家平行的假墙来代替世界坐标。因此,墙将位于:

sprite_wall_vertexes = sw (+/-) (inverse(mp)*sprite_half_size)

多亏了@Spektre我能够理解为什么我们将精灵的相对位置乘以相机矩阵的倒数,我只想添加更多的信息和解释

首先,让我们看看下图中的球员位置:

正如我们可以看到的,玩家的位置是(2,1),精灵的位置是(2,3),我们必须做的第一件事是根据玩家的位置知道精灵的位置,所以:

SpriteX = SpritePosX - PlayerPosX = 2 - 2 = 0
SpriteY = SpritePosY - PlayerPosY = 3 - 1 = 2
然后,根据玩家的位置,我们的精灵位置是(0,2),这是由上图中的红色向量表示的

但是如果我们不将红色向量坐标与摄影机矩阵的逆相乘,会发生什么呢

然后我们将使用从玩家位置到精灵位置的实际距离,当摄影机视图旋转时,红色向量将随之旋转,因此当您绘制精灵时,它将始终与
摄影机平面
垂直,这是我们不希望发生的

下面是它在图中的样子:

下面是它在游戏中的样子:

现在,如果我们将精灵(红色向量)的相对位置乘以相机矩阵的倒数,会发生什么

正如您所知,以及评论部分提到的@Spektre

“通过乘以逆矩阵,可以取消先前的旋转…其 “不旋转”回

因此,当我们将精灵(红色向量)的相对位置乘以相机矩阵的倒数时,相机/播放器的旋转将不会影响红色向量,它将保持静止,我们将根据相机视图获得红色向量的新坐标

如果我们将红色向量乘以摄像机矩阵的倒数,图中会出现以下情况:

在游戏中:


通过乘以“逆”可以取消上一次旋转。。。它不转回来了。在2D光线投射器中使用矩阵很奇怪。。。正如你所看到的,没有使用矩阵…@Spektre是的,我只是在本教程中使用向量和摄影机,而不是欧几里德角度。此外,如果你的矩阵只有2x2,并且只保持旋转,那么转置与反转相同,所以你不需要实现复杂/缓慢的矩阵反转。。。转置很简单,只需交换第二条对角线上的2个元素(左下右上)@Spektre是的,这样更快我以前不知道这个信息,非常感谢。