既然您要求体验,这里就是我的。
在我编写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时代做到这一点。