有没有一种有效的方法可以超过GL_MAX_VIEWPORTS?

Is there an efficient way to exceed GL_MAX_VIEWPORTS?

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

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

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

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

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

  1. 一个几何着色器,它在透视投影后将 h*gl_InvocationID 添加到顶点的 y 坐标(其中 h 是所需的视口高度)并将 gl_InvocationID 传递到片段着色器;和
  2. 片段着色器 discards 片段 y 坐标满足 y<gl_InvocationID*h || y>=(gl_InvocationID+1)*h.

但是由于担心分支和 discard 会对性能造成非常不利的影响,我推迟了进一步研究这个想法。

上述论文的作者发表了一篇technical report描述了他们的一些GPU加速方法,但不够详细,无法回答我的问题。 3.2.3 节说 "During geometry instancing, viewport information is attached to every vertex... A custom pixel shader clips pixels that are outside their pre-defined viewports"。这听起来与我上面描述的解决方法类似,但他们使用的是 Direct3D,因此很难将他们在 2011 年实现的目标与我今天在 OpenGL 中实现的目标进行比较。

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

粗略地看了一下论文,在我看来 actual viewport 没有改变。也就是说,您仍在渲染相同的 width/height 和 X/Y 位置,具有相同的深度范围。

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

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

GS instancing invocations的人数没有的限制;那是你的选择。 GS 调用可以写入多个原语,每个原语到不同的层。所以你可以让每个实例写入,例如,4 个基元,每个到 4 个单独的层。

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