C++ 使用深度纹理OpenGL/GLSL的深度遮挡(3.3/330)

C++ 使用深度纹理OpenGL/GLSL的深度遮挡(3.3/330),c++,opengl,glsl,C++,Opengl,Glsl,我的世界被分割成八叉树(tris被自动分割),每个chuck都有自己的索引缓冲区(vbo被共享)。我已经设置了FBO,在一个简单且最小的预处理过程中写入深度纹理,但我很难想象下一步 我希望将截头体(从八叉树返回)中的块从前到后进行组织,然后将其渲染为深度纹理。如果没有写入,则可以假定卡盘是隐藏的。然而,我不知道这样的测试在opengl中是否可行,因为我一直认为,当FBO绑定时,您无法读取深度纹理。另外,我不知道这种比较测试是如何进行的(FBO可以这样使用吗?) 另一种方法是为最终渲染使用最终深度

我的世界被分割成八叉树(tris被自动分割),每个chuck都有自己的索引缓冲区(vbo被共享)。我已经设置了FBO,在一个简单且最小的预处理过程中写入深度纹理,但我很难想象下一步

我希望将截头体(从八叉树返回)中的块从前到后进行组织,然后将其渲染为深度纹理。如果没有写入,则可以假定卡盘是隐藏的。然而,我不知道这样的测试在opengl中是否可行,因为我一直认为,当FBO绑定时,您无法读取深度纹理。另外,我不知道这种比较测试是如何进行的(FBO可以这样使用吗?)

另一种方法是为最终渲染使用最终深度纹理(将其传递到片段着色器),并消除被认为在从预传递(早期Z?)获取的深度纹理中确定的值之后的片段

我可以接受第二种方法,但更愿意放弃块,以最小化绘图调用和材质绑定

我希望有人能对这个问题有所帮助,因为我一直在寻找“最好的方法”,但我对这些方法和FBO的了解相对有限,我只将FBO用于阴影贴图灯光

很抱歉,这是一个麻烦-我知道硬件遮挡测试,但希望实现一个更通用的深度遮挡系统,它不需要“等待”

编辑:只是一个注释,对于预传递,我只打算首先渲染一个紧密贴合的边界框。

如果您不寻找,那么您可能需要基于CPU的解决方案

我向您推荐的是软件光栅化器。
在CPU而不是GPU上渲染遮罩/遮罩。
算法示例:

  • 将所有遮光罩的z值栅格化到缓冲区(例如墙)
  • 对于每个遮挡对象(例如家具和其他小对象),通过将其边界框栅格化到同一缓冲区(不写入缓冲区)来检查遮挡
  • 如果渲染遮挡边界框时存在未包含的像素,请渲染遮挡
  • 这是一个几乎可以在任何硬件上使用的解决方案

    这里有两个关于游击队如何在Killzone中实现它的精彩演示(在CPU上渲染遮罩,并通过栅格化遮罩边界框检查遮罩):

    以下是Crytek的工作方式(读回并修改前一帧的深度缓冲区,并在其顶部光栅化遮挡边界框):

    下面是关于Umbra 3遮挡剔除的演示:

    英特尔也进行了演示(也使用了软件光栅化器)


    无论如何,你的问题没有完美的解决方案。你必须自己决定什么最适合你。

    你问的问题不太清楚。你所说的许多算法都没有真正意义。例如,如果您有最终深度缓冲区(又名:您进行了深度预处理),为什么需要片段着色器“消除片段…”?当然,只要再次渲染对象,就会发生这种情况。嗨,尼科尔,我想我理解你的意思。当GFX卡在片段着色器中插值时,它将自动消除深度测试失败的片段,对吗?如果是这样的话,我甚至不需要做一个预考???然而,我试图弄清楚的是,为了防止在最终渲染过程中绑定它们(包括纹理等),使用从八叉树返回的卡盘进行深度遮挡。将其视为一个BSP系统,但仅使用三角形块,并在第二次传递之前使用深度缓冲区消除整个块。