OpenGL- 简单的2D剪裁/遮挡方法?

9
我正在制作一个相对较小的2D(俯视)游戏演示,使用OpenGL进行图形处理。它以基本的隐身为基础,因此对于所有敌人,我都会绘制一个视线弧线,以便玩家知道他们在看哪里。
到目前为止,我的一个问题是,当我绘制这个视线弧线(作为填充多边形)时,它自然而然地穿过屏幕上的任何墙壁,因为没有什么能阻止它:

http://tinyurl.com/43y4o5z

我很好奇如何能够最好地防止这种情况发生。我已经编写了代码来检测墙壁等的线段交点(用于敌人视线检测),理论上可以使用这些来检测这种情况并相应地绘制多边形,但这可能会非常琐碎和/或低效,因此如果有任何内置的OpenGL系统可以为我完成这项工作,它可能会做得更好。
我尝试寻找关于剪辑/遮挡等主题的问题,但我甚至不确定这是否正是我应该寻找的内容;我的OpenGL技能有限。似乎使用glClipPlanes或glScissor等任何东西都不适合由于大量单独的墙壁等。
最后,这只是我在业余时间制作的演示,所以图形并不是我主要担心的问题。如果有(合理)无痛的方法可以解决这个问题,我希望有人能指点我正确的方向;如果没有简单的方法,那么我可以暂时放弃这个问题或寻找其他解决办法。

我实际上正在寻找类似的东西,以处理顶部平铺游戏中的阴影。到目前为止,我的怀疑是沿着射线投射(慢但完美)和从遮挡物创建掩码以及某种类似于阴影映射机制的方向。 - ssube
你有没有考虑使用OpenGL灯光?这可能需要一些工作,但适当位置的灯光可能会产生所需的效果。 - Keith
@Keith:谢谢,这可能是个好主意。我对灯光的经验也有限,可能需要做很多调整才能让它们协同工作。但如果没有更好的方案,我会记住这个建议的。 - Linkage
2
"OpenGL lighting" 无法处理阴影。因此,它也会穿过墙壁。您需要使用阴影映射或模板阴影等技术。 - Nicol Bolas
据我所知,棘手的部分是将2D级别转换为可用于在地图上投射阴影的内容(好的)。此外,我还没有弄清楚对此的影响。 - ssube
3个回答

4
OpenGL内置的遮挡处理是为3D任务设计的,我想不到一个简单的方法来实现你想要的效果。如果是我,我会使用片段着色器程序来解决这个问题,但请注意,这绝对不属于“一个(相对)轻松的方法来做这件事”。简而言之,首先渲染一个二进制的“遮挡地图”,其中墙壁处为黑色,其他地方为白色。然后,您使用一个片段程序来渲染“视角弧线”,该程序被设计为从观察者朝向目标位置搜索遮挡物(黑色像素)。如果它找到了一个遮挡物,则将“视角弧线”的那个像素呈现为100%透明。总的来说,虽然这是一个“正确”的解决方案,但我肯定会说,这是一个复杂的功能,而且您似乎没有实施它也没关系。

1
那会很“昂贵”,但可能会起作用。将它们绘制为透明可能比使用内置的discard要慢。 - ssube
这是一个非常棒的想法,可以实现像素级别的功能。虽然GPU会承担相当大的负载,但如果视线弧线只覆盖屏幕的相对较小部分,那么就应该没问题了。 - geofftnz

4
这实际上是一个阴影问题。这是我的解决方案:
对于弧边缘的每个点,从敌人向该点追踪一条(2D)射线,寻找与绿色方块的交点。如果绿色方块始终是轴对齐的,则数学计算会更容易(查找Ray-AABB交点)。将交点渲染为三角形扇形将给您提供您的弧。
由于您已经编写了线-墙相交代码,只要它能告诉您敌人到墙的距离,就可以用于视线弧。不要自动假设它会太慢——我们不再使用486了。您始终可以减少弧边缘的点数以加快速度。

这听起来相当不错,但我仍然有一点担心速度。我的意思是,假设我在一个地图上有多达10个敌人,每个敌人至少有30个弧点,再加上25堵墙...那就是一个帧需要进行10 * 30 * 25次交叉检查,对于一个相对简单的效果来说,这听起来需要很多处理器工作量。 不过,这是一个好答案,我可能会很快尝试一下。 - Linkage
2
不要忘记空间索引来减少需要检查相交的墙壁数。 - genpfault

4
我认为如果有任何内置的OpenGL系统可以为我完成这个任务,它可能会做得更好。OpenGL是一个绘图API,而不是几何处理库。实际上,您的交点测试方法是正确的方法。但是,为了加快速度,您应该使用空间子分割结构。在您的情况下,您需要一个“二进制空间分割”树。BSP树具有很好的特性,即寻找线与墙之间的交点的复杂度平均约为O(log n),最坏情况为O(n log n),换句话说,BSP树非常高效。有关详细信息,请参见BSP FAQ:http://www.opengl.org//resources/code/samples/bspfaq/index.html

我之前从未研究过BSP树,但现在看起来确实非常有用。如果我最终采用geofftnz早期的建议(或者如果我发现我的碰撞系统不足),我可能会尝试实现它。 - Linkage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接