在AAA游戏中越界


21

在许多常见的AAA游戏中(尤其是Source引擎游戏),当玩家到达“未归类”的区域时,例如越界或在地图下打c;屏幕上出现奇怪的效果(缓冲区撕裂?)。

可以将其描述为类似于Windows XP的窗口轨迹,Windows XP可能会在系统挂起时留下被拖动的窗口。

我只能假定开发人员在刷新屏幕时不会清除颜色缓冲区吗?

那是对的吗?如果是这样,为什么?


8
顺便说一句,这通常称为“镜厅”效果或HOM。
内森·里德

Answers:


35

曾几何时,清除颜色和深度缓冲区实际上需要时间。做一个清除意味着图形卡将必须遍历帧缓冲区的每个像素并向其中写入一个值。

因此,游戏开发人员发现,简单地假设每个像素都会被重新渲染会更有效。他们为此开发了许多技术。

颜色缓冲区最容易忽略。深度缓冲区不太容易,因为它会被旧数据污染。所以他们所做的很简单。

在第0帧上,它们将使用glDepthRange(0,0.5)(或等效于D3D的值)进行渲染,并且将使用glDepthFuncof GL_LESS(或GL_LEQUAL)。这意味着您在深度缓冲区中获得的最远深度值为0.5。因此,在第0帧末尾深度缓冲区中的最大值为0.5(假设您写入了每个像素)。

在第1帧上,它们会将深度范围更改为(1,0.5)。请注意,在这种情况下,近距离深度值大于远距离深度。但是他们也将深度函数更改为GL_GREATER(或GL_GEQUAL),这颠倒了深度测试的含义。因为深度缓冲区中的最大值是0.5,所以您编写的所有内容的值都将于此值。由于深度测试被反转,这实际上意味着在帧0上写入的内容现在比可能在帧1上写入的内容都更远。在帧1的末尾,深度缓冲区中的最小值现在为0.5。

然后重复。

在2003年左右以来制造的任何硬件上,这不再是优化。实际上,这是一个负面的优化。清除深度缓冲区实际上会使硬件更快。不完全是。

基本上,发生的事情是清除缓冲区实际上没有写入任何内容。它们将一些位存储在GPU的缓存中,以使系统知道已清除的颜色/深度。当系统尝试写入帧缓冲区的高速缓存行时,无需费心读取那里的内容,因为它已经知道它是具有清晰颜色/深度值的空白字段。如果您尝试与其中的内容进行融合或进行深度测试,则无需再读:它知道与/进行融合/测试的价值。

因此,清除后在每个高速缓存行上进行的每个第一次读/修改/写基本上都是写操作。它是免费的

另外,具有锯齿状的深度缓冲区可以与硬件中的Hyper-Z / Hierarchial-Z /任何Z剔除优化配合使用。是的,当您添加细节时,您的场景最终将与那些场景发生冲突。但是,如果深度缓冲区与以前的渲染呈锯齿状,即使这些背景对象位于背景中,也会影响Z剔除技术的效率。这不会帮助性能。

因此,您永远不要在现代游戏中使用这种深度反转技术。

注意:Jari在基于图块的渲染体系结构(在大多数移动平台中都可以找到)上很不错。不清除深度也会使事情变得令人不快。


您的最后一句话是否暗示深度缓冲区永远不会交替执行?好答案。
deceleratedcaviar

1
@丹尼尔是的。我澄清了我的帖子。
Nicol Bolas

3
另外,由于图形芯片无法对颜色缓冲区的状态做出假设,因此跳过明确的分箱架构(像大多数OpenGL ES芯片一样)会导致巨大的性能损失。
贾里·孔帕

5

是的,没错,没有清除后台缓冲区。

原因是(主要是)使用自定义着色器(每帧在相反方向上对深度值进行乒乓)并依赖于游戏始终在屏幕上渲染每个像素这一事实,这种速度更快。

因此,为零成本,您每帧节省一个缓冲区清除空间。


1
我不知道深度乒乓。我熟悉的每个引擎都会在每帧清除深度/模板缓冲区。但是除此之外,是的,如果游戏渲染了所有像素(应该如此),则不需要清除颜色缓冲区。
内森·里德

您能举个着色器的例子,否则好答案。
deceleratedcaviar

1
我意识到您正在询问最近的引擎,请阅读@NathanReed的评论,指出现在有多少个PC引擎可以工作。Z缓冲区扭曲是一种较旧的技术,我将看看是否可以找到参考。控制台引擎也将同时清除所有颜色缓冲区,即使显示Nathan命名的HOM效果的一个像素也将无法通过标题,并迫使其重新进行提交。
Patrick Hughes
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.