Algorithm 墙的抹灰顺序;假3D“;棱镜

Algorithm 墙的抹灰顺序;假3D“;棱镜,algorithm,3d,geometry,2d,rendering,Algorithm,3d,Geometry,2d,Rendering,我正在使用Python和pygame开发一个“假3D”游戏。gfx仅由使用不同大小和颜色的2D基本体创建的棱镜组成: 游戏的gfx是如何工作的: 问题出现在第4点,当我想在渲染队列中按正确的顺序对墙进行排序时(以确定哪一个是最接近的,并且必须首先渲染,哪一个是第二个,哪一个是最后一个等) 目前,为了对墙进行排序,我移除了所有不可见的墙,并测量player和wall之间的最短距离。它是有效的。。。但仅当场景中有一个多边形时。示例(2个多边形): 我可以处理这类特定的问题,但我不知道将来是否还

我正在使用Python和pygame开发一个“假3D”游戏。gfx仅由使用不同大小和颜色的2D基本体创建的棱镜组成:

游戏的gfx是如何工作的:

问题出现在第4点,当我想在渲染队列中按正确的顺序对墙进行排序时(以确定哪一个是最接近的,并且必须首先渲染,哪一个是第二个,哪一个是最后一个等)

目前,为了对墙进行排序,我移除了所有不可见的墙,并测量
player
wall
之间的最短距离。它是有效的。。。但仅当场景中有一个多边形时。示例(2个多边形):


我可以处理这类特定的问题,但我不知道将来是否还会有其他问题。我的问题:是否有任何算法(可以工作…)可以将我的墙按正确的顺序排序,并且我可以面带微笑地渲染它们

我猜我们可以公平地假设多边形不相交。如果是这种情况,我们不需要拆分任何内容。然而,找到正确的顺序仍然需要大量的计算。尽管有人可能会提出一种增量方法,只在不同的帧之间更新必要的内容

事情是这样的。在2多边形示例中,基于直线的两个最近点的顺序显然不起作用,因为它们具有不同的视图方向。但是,如果您选择具有相同视图方向的点(在它们重叠的区域中),您将清楚地看到A在B的前面。那么,我们需要做什么:

首先查找所有可见的墙。我们将为这些墙创建可见性图。因此,创建一个图形,其中每面墙都由一个节点表示。最后,您将计算该图的拓扑排序以获得绘图顺序。现在,我们如何找到边,即,关于另一面墙前面是什么墙的信息?为此,首先查找重叠的墙对(拉伸墙)。您可能希望使用像AABB树这样的加速数据结构来加快速度

然后我们需要对视图方向进行一维参数化。方向和x轴之间的角度可能工作得很好(
a=atan2(lineY-playerY,lineX-playerX)
),尽管它有这个令人讨厌的周期性,您需要处理。我们现在只考虑两个壁的原始多边形边缘(不是挤压的)。找出两条线的1D间隔(例如,线1在10°和35°之间,线2在20°和135°之间)。如果这两个间隔不重叠,您可以跳过这一对,因为它们的相对顺序无关紧要。如果有,则找到重叠间隔中的任何点(例如25°),找到相应的视图方向(
x=playerX+cos(25°),y=playerY+sin(25°)
)以及线上与该方向对应的点(例如,通过计算线与视图光线的交点)。然后,简单地计算沿着这条光线的两条线的距离。选择重叠间隔中的哪个点无关紧要,因为直线是线性的,原始多边形不相交。如果到第1行的距离小于到第2行的距离,请在可见性图形中添加从第1行到第2行的定向边(表示第1行在第2行的前面),否则添加反向边

最后,计算图形的拓扑顺序,就得到了绘图顺序

选择2 这里是上述方法的替代方法,对于动态渲染可能更有效。这个想法是基于

首先对场景进行三角形化,即用三角形填充空隙(只需执行一次)。然后,可见性图存储三角形(而不是边)。对于从内部看到的每个三角形边,将三角形中的边添加到与该边关联的相邻三角形。最后,再次计算拓扑排序并按该顺序绘制墙(跳过空心三角形)


动态情况下的效率来自这样一个事实,即您只需对图形进行少量更新。对于每个边,您要确定是从前面还是从后面看到它们。因此,仅当视点穿过由边指定的无限线时,边的方向才会反转。如果找到所有这些边(自上一帧以来方向发生了变化),则可以更新图形并进行相应排序。

如果没有Z缓冲区,则需要按每个交点/重叠分割面,并将每个面作为单个面进行处理。正如您所看到的,编写代码将是一个可怕的混乱。使用Z缓冲将gfx移植到3D中要容易得多。。。此外,使用具有视图方向和面法线的点积来移除不可见面的方法要比现在的排序(称为面剔除)简单得多。如果要使用2D,需要检查每个像素,而不是多边形。或者你可以坚持Spktre建议。看看这个,在2GDI环境中有一个小型的C++线框渲染例子,如果你没有3D引擎,它可能很方便。