了解libGDX投影矩阵

在过去的几周里,我一直在尝试学习libGDX库。 我发现很难,尤其是我第一次尝试游戏开发时,要理解相机/视口关系系统。 我被告知使用的一行代码和API提到的是:

batch.setProjectionMatrix(camera.combined); 

尽管进行了4个小时的研究,但我仍然缺乏对此代码function的完整理解。 根据我的基本理解,它“告诉”相机正在寻找的批次。 我缺乏理解力令人沮丧和愤怒,如果有人能帮助我,我会很感激。 代码片段的另一个问题是我不确定何时需要实现(在render方法中,create方法等)。

考虑用相机拍照。 例如,使用智能手机相机拍摄公园长椅的照片。 当你这样做时,你会在智能手机屏幕上看到公园的长凳。 这看起来非常明显,但让我们来看看这涉及到什么。

照片上工作台的位置与拍照时的站立位置有关。 换句话说,它是相对于相机。 在典型的游戏中,您不会相对于对象放置对象。 相反,你把它们放在游戏世界中。 在游戏世界和相机之间进行翻译是使用矩阵完成的(这只是一种转换坐标的数学方法)。 例如,当您将相机向右移动时,工作台会在照片上向左移动。 这称为视图矩阵。

图片上工作台的确切位置也取决于工作台和相机之间的距离。 至少,它在3D中(2D非常相似,所以继续阅读)。 当它离更远的地方时它更小,当它靠近相机时它更大。 这称为透视投影。 您也可以使用正投影,在这种情况下,对象的大小不会根据到相机的距离而改变。 无论哪种方式,公园中工作台的位置和大小都会转换为屏幕上的位置和大小(以像素为单位)。 例如,公园里的长凳是两米宽,而照片上则是380像素。 这称为投影矩阵。

camera.combined表示组合的视图和投影矩阵。 换句话说:它描述了游戏世界中的事物应该在屏幕上呈现的位置。

调用batch.setProjectionMatrix(cam.combined); 指示批处理使用该组合矩阵。 每当值发生变化时,您都应该调用它。 这通常是在调用resize时以及移动或以其他方式更改相机时。

如果您不确定,那么您可以在render方法的开头调用它。

另一个答案非常好,但我想一个不同的描述方式可能有助于它点击。

您通常在“世界空间”中处理您的游戏,这是一个类似于现实世界的坐标系。 在线性代数中,您可以通过将点的坐标乘以表示两个坐标系之间关系的矩阵,将空间中的点从一个坐标系转换为另一个坐标系。

视图矩阵乘以一个点,将其从世界空间转换为相机空间(相机的视角)。 投影矩阵用于将点从相机空间转换为屏幕空间(设备屏幕的平面2D矩形)。 当您在Libgdx中的相机上调用update()时,它会将最新的位置,方向,视口大小,视野等更改应用到其视图和投影矩阵,以便可以在着色器中使用它们。

您很少需要在2D中处理相机空间中的内容,因此SpriteBatch不需要单独的视图和投影矩阵。 它们可以组合成一个矩阵,直接从世界空间转换到屏幕空间,这已经在相机中自动完成,因此是camera.combined矩阵。

SpriteBatch有一个默认的内置着色器,它将此投影矩阵乘以精灵的所有顶点,以便它们正确映射到平面屏幕。

无论何时移动摄像机或调整屏幕大小,都应调用setProjectionMatrix

存在第三种types的矩阵,称为模型矩阵,用于3D东西。 模型矩阵描述了模型在世界空间中的方向,比例和位置。 因此,它乘以模型中的坐标,将它们从局部空间移动到世界空间。

以一个基本的sidecrolling游戏为例。 当玩家向侧面移动时,相机会跟随他们。 这意味着世界中的对象不一定对应于它们在屏幕上的位置,因为屏幕和世界相对于彼此移动。

这是一个例子:说你的屏幕是100px * 100px平方(由于某种原因)。 您将对象放置在位置(50,0),因此它现在位于屏幕的中间和底部。 现在假设您将播放器向右移动,整个屏幕平移以跟随播放器。 这意味着您之前放置的对象应该在屏幕上向左移动。 因此它在世界上仍然处于(50,0),因为它实际上并没有相对于其他景物移动,但它现在应该在屏幕上绘制,例如,(10,0),因为哪个部分屏幕正在看的世界已经改变了。 这是“世界空间”(对象在世界中)和“屏幕空间”(在实际显示器上绘制对象)之间的区别。

当你尝试使用SpriteBatch进行绘制时,默认情况下假设世界空间坐标与屏幕空间坐标相同:当你说“绘制在(50,0)”时,它将在(50,0)处绘制对象屏幕上。 即使相机移动,它总是在屏幕上绘制(50,0),因此当相机平移时,对象将跟随并保持粘在屏幕上的相同位置。

由于您通常不希望这样,因此您可以为SpriteBatch提供投影矩阵 ,这是一个转换矩阵,用于说明如何将屏幕空间坐标转换为世界空间坐标,反之亦然。 这样,当你告诉批处理“绘制在(50,0)”时,它可以查看从相机获得的矩阵并看到,由于相机已移动,(50,0)在世界中实际意味着( 10,0)在屏幕上,它会在正确的位置绘制你的精灵。