【问题标题】:Non-monotonic depth buffer; cyclical overlapping in OpenGL非单调深度缓冲区; OpenGL中的循环重叠
【发布时间】:2021-02-21 11:11:12
【问题描述】:

是否可以实现自定义深度缓冲区值,以便实现非传递排序?例如

Red > Green
Green > Blue
Blue > Red

我想这将在片段着色器或其他东西中实现,仅当像素根据上述模式位于现有像素之上时才写入像素。请注意,由于它是不可传递的,因此不可能为每种颜色分配一个数值并保留顺序。

换句话说,我想要一个自定义 z 缓冲区,其中每个元素都是非传递类型。因此,z 缓冲区将是一个充满RedGreenBlue 值的大表。为每个分配一个数字,然后根据上面的模式进行比较以确定哪个在顶部。如果所有三种颜色都在同一个片段上,那么我不在乎哪一种在上面。

下图说明了我的意思(这是我希望它能够做到的):

(来自维基百科的图片)

我想要的东西在 OpenGL 中是否可行,还是我太过分了?如果可能,性能下降会有多严重?

【问题讨论】:

  • @KaiBurjack 感谢您的建议,但我不只是想满足我给出的人为示例。我相信将您的解决方案推广到任意排列的彩色对象是不可能的。我真的需要一个非传递 z 排序
  • @KaiBurjack 我确实举了一个例子......关键是你不能只解决这个例子然后说你已经解决了整个广义问题。我想要一个自定义的 z 缓冲区。我会尽量让这个问题更清楚
  • 等等,你想要的只是简单地制作某种颜色的片段覆盖另一种颜色的片段,而不考虑深度值?
  • "这就是我希望它能够做的事情" 你想要的没有意义。如果这三个都重叠会发生什么?应该是什么颜色?既然不涉及“深度”,这些如何算作“深度缓冲区”?
  • 我认为您可以使用帧缓冲区来完成此操作。

标签: opengl glsl shader depth-buffer


【解决方案1】:

您想要做的不仅是可能的,而且相对快速和简单。为了render the penrose triangle,我在我的游戏中实现了类似的东西。

诀窍是使用stencil buffer 代替深度缓冲区。实际上,您可以通过多种不同的方式使用模板缓冲区来实现循环排序效果,具体取决于您的具体需求。我将在这里描述一种可能的算法:

  1. 在没有模板测试的情况下绘制红色层,同时将1s 写入模板缓冲区。
  2. 使用模板测试not equal to 1 绘制绿色层,同时将2s 写入模板缓冲区。 这将防止它在已绘制红色的地方绘制,有效地将绿色“置于”红色“后面” .
  3. 使用模板测试not equal to 2 绘制蓝色层。这将允许将其绘制在红色之上,而不是绿色之上,从而有效地将其放置在它们之间。

同样的技术可以推广到 N 层,如下所示:

- for each layer X going front-to-back, from `N - 1` down to `0`
    - draw layer X with stencil test `not equal to X + 1`, while writing `X` to the stencil buffer

此代码可能类似于:

glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
for (int X = N - 1; X >= 0; --X) {
    glStencilFunc(GL_NOTEQUAL, X + 1, 0xFF);
    // drawLayer(X);
}

此算法仅保证层 X 将正确地与层 (X - 1) % N(X + 1) % N 交互。如果您想要更复杂的规则,则需要更复杂的算法。

请注意,使用 8 位模板缓冲区,您将被限制为 255 层。

还请注意,由于此算法不使用深度缓冲区,因此它也适用于 3D 场景 - 只需像正常一样启用深度测试,您就可以开始比赛了。这就是我能够在 3D 中渲染彭罗斯三角形示例的方式。

【讨论】:

  • 谢谢!模板缓冲区看起来很完美(我是 OpenGL 的菜鸟,所以我不知道)。一旦我尝试了这种方法,我会尽量记住将其标记为答案,
  • 我正在考虑写入帧缓冲区,然后将其用作绘制所有内容的纹理,然后检查每个像素上的颜色值并仅绘制相关的。但这个解决方案要简单得多。
  • 模板缓冲区是为这类事情设计的,所以我希望这也很快。很好的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
相关资源
最近更新 更多