【问题标题】:Do we need to clear the buffer if we use double buffering?如果我们使用双缓冲,我们需要清除缓冲区吗?
【发布时间】:2016-06-25 08:21:23
【问题描述】:

假设我们使用双缓冲。我们首先将帧写入后台缓冲区,然后将其交换到前台缓冲区进行显示。

这里有两种情况,我假设结果相同。

  • 假设我们清除后台缓冲区,然后我们将一个新帧写入后台缓冲区。将其交换到前端缓冲区。

  • 现在假设我们没有清除后台缓冲区,后台缓冲区无论如何都会被新帧覆盖。最后两个缓冲区将被交换。

因此,假设我是对的,并且假设我们使用双缓冲,无论是否清除缓冲区,两者都会以相同的显示结束,是吗?

如果我们不清除缓冲区,是否会有任何可能的渲染伪影?

【问题讨论】:

  • 对问题的补充。 “缓冲区”特指“颜色缓冲区”,因为它处于双缓冲状态

标签: opengl framebuffer doublebuffered double-buffering


【解决方案1】:

第二种方法的关键在于这个假设:

后台缓冲区将被新帧覆盖

我假设我们谈论的是包含颜色值、深度、模板等的 OpenGL 帧缓冲区。它们在下一帧中究竟会被覆盖多少?

渲染代码会进行恒定的深度比较,因此请查看需要绘制哪些对象。使用旧的帧深度数据,一切都会变得一团糟。如果您在启用混合的情况下渲染任何半透明项目,也会发生同样的情况。

清除缓冲区是将所有内容重置为零(或您需要的任何其他特定值)的最快方法。

有些技术依赖于不清除缓冲区(考虑到这已被证实是平台上的一项昂贵操作)。例如,没有透明几何体而后面没有不透明,并在 0-0.5 / 0.5-1.0 范围内切换深度测试更少/更大,以使其始终覆盖旧帧值。

【讨论】:

  • 我现在有点困惑,因为据我所知,双缓冲只处理“颜色缓冲区”。深度和模板缓冲区与双缓冲无关。我对吗?如果这是真的,那么深度缓冲区在这里就不是真正的问题了。
  • 但感谢您提出另一点,即突出显示 overwritten 部分。这不是一个安全的假设吗?因为下一帧将被写入与先前大小相同的大小,因此会覆盖所有现有的颜色缓冲区。
  • @Yeo,不,不是。参见例如 glxgears(upload.wikimedia.org/wikipedia/commons/thumb/6/62/…)。三角形每帧都被渲染,但黑色背景来自透明。没有清除,新框架就不是整个窗口,而只是渲染的齿轮。
  • @BasNieuwenhuizen 哦,现在我明白了透明颜色缓冲区的来源。我以为世界空间一直都是特定的原始人本身,显然是在清理之后出现的。除非我们自己制作封闭的世界空间。
【解决方案2】:

在渲染过程中,您至少需要清除深度缓冲区这一事实。

当双缓冲时,后台缓冲区的值将(可能)是您在 2 帧前渲染的值。

如果深度缓冲区没有被清除,那么你的脸永远不会消失。

可以通过例如在禁用深度测试时使用天空盒渲染具有纹理的全屏四边形来清除深度缓冲区。

【讨论】:

  • 只是一个旁注,围绕“不清除深度”方法存在渲染技术。
【解决方案3】:

缓冲区交换后,后台缓冲区的内容是未定义的,即它们可以是任何东西。由于许多 OpenGL 渲染操作依赖于目标帧缓冲区的众所周知的状态才能正常工作(深度测试、模板测试、混合),因此必须先将后台缓冲区置于众所周知的状态,然后再执行其他操作。

因此,除非您采取谨慎措施以确保您的渲染操作依赖于目标缓冲区内容,否则您必须在交换后清除后台缓冲区,然后再执行任何其他操作。

【讨论】:

  • 您能否提供一个示例,说明它们不仅仅是“来自上一帧”,而是特别是“未定义”?
  • @KromStern:这与现实世界的“示例”无关。归结为OpenGL 规范是这样说的。实践中任何事情都可能发生:您可能会看到上一帧,看到未初始化的内存、纯色等。
  • @KromStern 现代系统通常并不真正使用双缓冲,除非可能用于全屏渲染。对于窗口渲染,您不会在每个窗口中获得双缓冲。特别是如果你用阴影等来描绘重叠的窗口,你可以想象很难让它工作。实际上,您渲染到一个缓冲区,该缓冲区成为窗口系统组合的一部分。也可以有三重缓冲之类的东西。因此,假设 2 帧前的内容在当前缓冲区中几乎不会在现实中起作用。
  • @RetoKoradi 没有在应用程序渲染级别实现双缓冲 (DB)? IE。应用程序从 OGL/D3D 请求 DB 并渲染到后台缓冲区,而 OS 接收其组成的前缓冲区?否则,如果我们的单个缓冲区用于合成,我们会看到渲染正在进行中?
  • @KromStern:不。在 OpenGL 中,双缓冲细节在驱动程序内部处理,除了设置标志和选择渲染是向前还是向后,应用程序无法控制它。
【解决方案4】:

如果您喜欢现代硬件的性能,那么清除缓冲区是绝对必要的。清除缓冲区不一定写入内存。相反,它会做一些缓存魔法,这样,每当系统尝试从内存中读取(如果它在被清除后还没有被写入),它就会读取清除颜色。所以它甚至不会真正访问该内存。

这对于深度缓冲区之类的东西非常重要。深度测试/写入是读取/修改/写入操作。第一次阅读基本上是免费

因此,如果您要覆盖每个像素,从技术上讲,需要清除后台缓冲区,但您确实应该这样做。

【讨论】:

    猜你喜欢
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 2012-07-31
    • 2020-09-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多