使用分层的alpha四边形是否适合地面雾?


16

分层方法将使用一系列与地面平行排列的大块alpha纹理化四边形,与所有介入的地形几何相交,从而从上到下,俯视到地面时都非常有效地提供了地面雾的幻觉,而在雾中时,效果却稍差一些。朝着地平线看(见下图)。

替代地,主要基于着色器的方法将改为根据进入地面雾化基底的视距来计算密度,并基于该密度输出片段值。

在不必亲自测试每种方法的性能的情况下,我想先听听别人对分层alpha纹理方法可能会产生什么样的性能影响的经验(而不是猜测!)。我特别要问的是,透支经常会受到影响(不确定填充率对普通台式机系统的限制)。使用此方法的游戏列表,尤其是较旧的游戏,将非常有用:如果在DX9 / OpenGL2之前的硬件上可行,那么对我来说可能很好用。

关于这种效果,一个大问题是:

在此处输入图片说明

(图片来源:lume.com的Lume)

请注意垂直雾的渐变如何连续/平滑。OTOH,使用带纹理的四层,我只能假设遍历它们时这些层会非常明显-它们越稀疏,就越明显。这与雾面对齐以每帧面向播放器的情况相反,在这种情况下,这种粗糙程度将不那么明显。


1
您为什么为此使用alpha Quad图层?“重着色器方法”不仅更准确,而且还因其速度慢而并不确切。
Nicol Bolas 2012年

1
@StephanvandenHeuvel当然可以,但这是视图空间对齐的基于距离的雾。没有地面对准的雾。正确?
工程师

1
@NickWiggill是的,您是对的。
斯蒂芬·范登休维尔

1
IIRC,Wii在其(半)固定管道中有与地面对齐的雾。显然glFogCoord,旧版OpenGL中的扩展也允许这样做。尽管听起来很有限:它是基于地面的还是基于距离的。
洛朗·库维杜

1
Quake 3使用与GL1.1一起使用的固定管道方法做了类似的事情。我最担心的是fillrate / overdraw可能堆积得很厉害,但是可能值得下载Q3源代码并回顾其实现。您可能做的并不完全相同,但至少可以帮助您做出决定。
Maximus Minimus 2012年

Answers:


15

既然您要求体验,这里就是我的。

在我编写PS2游戏时,“分层的alpha方形字体”方法是我们经常实施雾化的一种方式。有时像地面雾一样,但更常见的是全屏雾。无论哪种情况,它都能正常工作。所以是的,它在片段着色器之前的时代是可行的。

好吧,有点。正如您所指出的,问题是,如果您想要平滑的雾气(如屏幕截图所示),则需要相当荒谬的alpha四边形。

在PS2上,我们通常可以负担三到五层之间的费用。看起来确实像雾在你面前漂浮的“墙”。不仅如此,填充率开始削弱我们的帧速率。

通常,这些四边形将在相机前面以固定距离绘制,因此您永远不会遇到提到的情况,即“穿越”其中一个。另一方面,通过使用这些固定距离,世界其他所有区域玩家四处走动时穿过这些平面,这是一个非常明显的图形故障。那时几乎每个人都这样做了,但是现在不被接受(除非您出于风格原因这么做)。(例外:有些人将雾值作为PS2等效于顶点着色器的一部分进行了计算。这种方法虽然工作且速度更快,但要求模型高度细分。例如,雾墙不能长,因为雾只是在墙壁的各个角落进行计算,然后涂抹在墙壁的整个表面上,例如,如果您正好站在墙壁的中间位置,则墙壁看起来会完全雾化,例如,因为它只是在测试墙壁的雾度端点)

请注意,如果您将雾状四边形静态地放置在世界上(如您所提到的那样),那么您将无法获得极平滑的雾状外观,如您提供的图像中那样-两者之间会有奇数个重叠相邻的四边形,具体取决于观看者的方向。那些重叠可能显示为条纹或梯形(如果四边形没有纹理)或成块(如果它们有纹理)。

但是,假设我们正在使用面向屏幕的宽幅四边形来进行地面雾化,并进行一些计算,以了解如何使用这种方法在平坦的地面上使用直视摄像头,使真正的平滑雾化-这是我们的理想情况。让我们假设HD分辨率为1920x1080,这将我们的视线置于扫描线540。我们还假设我们一直到视线都具有可见性(也就是说,假设在到达视线之前雾没有达到完全不透明的状态)。在每个扫描线上有一个雾状四边形开始并且一个停止(为了获得平滑的雾状),我们需要(540 * 2 ==)1080个雾状四边形。这1080个雾状四边形中的每一个都将覆盖屏幕的整个水平方向,

让我们估计低,并说平均而言,雾平面将覆盖大约300行像素。最接近的将覆盖较少,最远的将覆盖较少,中间的行将覆盖更多。

通过该估计,我们得到(1920x300 ==)576,000像素被平均雾四边形触摸。总体来说,整个“通过渲染很多半透明的几何体的平滑雾”效果总共达到(576,000 * 1080 ==)622,080,000像素。对于运行更高分辨率的人来说,这个数字将会增加。而且,由于所有这些透明层一次又一次地相互绘制,因此我们可以对z缓冲区进行相同数量的测试,并进行几乎相同数量的像素混合操作。这是一个很大的像素。

那是最好的情况-如果用户低头或蹲下,您将获得更多雾四边形的屏幕覆盖。

请注意,由于我们重叠了1080个四边形,因此我们可能希望在每个像素上设置大约(1.0 / 1080〜=)0.0009的Alpha值,这样,如果您查看所有1080个四边形,雾化将达到完全不透明。(我们可以高于该值,但这是假设我们要尽可能扩大范围的值)。请注意,此值不能表示为32位颜色值的alpha分量(256 * 0.0009〜= 0.237,因此,如果尝试将四舍五入为0)。您需要为OpenGL提供0.0009值作为浮点值,以使其完全起作用。(另外请注意,您实际上并不想在每个值上都设置相同的值-虽然我们定义要在水平线以下的每条扫描线上开始一个四边形,然后完成一个四边形,以使我们平滑雾化,

还要注意,使用这种方法,雾混合将无法正常工作,就像使用现代着色器那样-而不是通过“计算该百分比使用基础百分比颜色与雾颜色之间的混合”来进行计算计算“到目前为止的颜色与雾的颜色之间的混合程度(按雾化百分比)”。这意味着在对数衰减之后,雾将影响对象。(也就是说,受20个雾四边形影响的对象的雾化程度小于受10个雾四边形影响的对象的雾化,因为第一个雾四边形在混合操作中的影响更大)。

所有这些都是要说的: 请只使用片段着色器。

不完全是。它更简单,更便宜,实现起来更快,更快捷,并且更少出现错误,并且让您回到实际制作游戏的过程中,并且在所有可能的方面都变得更好。如果当时甚至还可以实现的话,我们完全可以在PS2时代做到这一点。


1
+1可根据现实世界的经验提供全面的答案。
concept3d

3
一年零一个月前,当我写这个问题时,我仍然愿意以填充率玩鸡。现在,我将选择粗糙的3D纹理来表示具有不断变化的密度(由3D柏林噪声确定)的地面雾量,然后将其用作屏幕空间效果的基础,就像您建议的那样。
工程师
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.