有没有一种有效的方法来超越GL_MAX_VIEWPORTS?



我目前正在实现Oikonomidis等人,2011年提出的姿势估计算法,该算法涉及在N不同的假设姿势中渲染网格(N可能约为64)。第 2.5 节建议通过使用实例化同时生成多个渲染来加快计算速度(之后他们将每个渲染减少到 GPU 上的单个数字),从他们的描述来看,听起来他们找到了一种同时生成N渲染的方法。

在实现的设置阶段,我使用 OpenGL 视口数组来定义GL_MAX_VIEWPORTS视口。然后在渲染阶段,我将GL_MAX_VIEWPORTS模型姿势矩阵的数组传输到 GPU 内存中的mat4uniform数组(我只对估计位置和方向感兴趣),并在几何着色器中使用gl_InvocationID为网格的每个多边形选择适当的姿势矩阵和视口。

GL_MAX_VIEWPORTS在我的机器上是 16(我有一个 GeForce GTX Titan),所以这种方法将允许我在 GPU 上一次呈现多达 16 个假设。这可能足够快,但我仍然对以下内容感到好奇:

对于GL_MAX_VIEWPORTS限制,是否有一种解决方法可能比调用我的渲染函数ceil(double(N)/GL_MX_VIEWPORTS)次更快?

几周前我才开始学习基于着色器的OpenGL方法,所以我还不知道所有的技巧。我最初考虑将内置视口支持替换为以下组合:

  1. 一个几何着色器,用于在透视投影后向顶点的y坐标添加h*gl_InvocationID(其中h是所需的视口高度),并将gl_InvocationID传递到片段着色器上;以及
  2. 一个片段着色器,discard具有满足y<gl_InvocationID*h || y>=(gl_InvocationID+1)*hy坐标的片段。

但是我推迟了对这个想法的进一步调查,因为担心分支和discard会对性能非常有害。

上面论文的作者发布了一份技术报告,描述了他们的一些GPU加速方法,但它不够详细,无法回答我的问题。第 3.2.3 节说"在几何实例化期间,视口信息附加到每个顶点......自定义像素着色器可剪辑其预定义视口之外的像素"。这听起来类似于我上面描述的解决方法,但他们使用的是 Direct3D,因此将他们在 2011 年能够实现的目标与我今天在 OpenGL 中实现的目标进行比较并不容易。

我意识到我的问题的唯一明确答案是实施解决方法并衡量其性能,但它目前是一个低优先级的好奇心,我还没有在其他任何地方找到答案,所以我希望更有经验的 GLSL 用户能够提供他们节省时间的智慧。

粗略地看了一眼论文,在我看来,实际的视口并没有改变。也就是说,您仍然渲染到具有相同深度范围的相同宽度/高度和 X/Y 位置。

您想要的是更改要渲染到的图像。这就是gl_Layer的目的;以更改附加到帧缓冲区的图像分层数组中的哪个层。

因此,只需将所有顶点的gl_ViewportIndex设置为 0。或者更具体地说,根本不设置它。

GS 实例化调用的数量不必是限制;这是您的选择。GS 调用可以将多个基元写入多个基元,每个基元写入不同的层。因此,您可以让每个实例写入 4 个基元,每个基元写入 4 个单独的层。

您唯一的限制应该是您可以使用的层数(由GL_MAX_ARRAY_TEXTURE_LAYERSGL_MAX_FRAMEBUFFER_LAYERS控制,两者都必须至少为 2048),以及单个 GS 调用可以发出的基元和顶点数据的数量(这有点复杂)。

最新更新