有没有有效的方法来超过GL_MAX_VIEWPORTS?

Ose*_*Ose 4 opengl graphics shader glsl viewport

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

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

GL_MAX_VIEWPORTS我的机器上是16(我有GeForce GTX Titan),因此这种方法将允许我一次在GPU上渲染多达16个假设。事实证明这足够快,但是我对以下内容感到好奇:

有没有一种GL_MAX_VIEWPORTS限制的解决方法,该方法可能比调用渲染函数的ceil(double(N)/GL_MX_VIEWPORTS)时间更快?

我只是在几周前才开始学习基于着色器的OpenGL方法,所以我还不了解所有技巧。我最初想到的是将组合使用的内置视口支持替换为:

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

但是由于担心分支discard会严重损害性能,因此我推迟了进一步研究此想法的时间。

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

我意识到,对我的问题的唯一确定答案是实施变通办法并衡量其性能,但是目前这是一种低优先级的好奇心,我在其他任何地方都找不到答案,因此我希望有经验的GLSL用户可以能够提供节省时间的智慧。

Nic*_*las 8

粗略浏览一下纸张,在我看来,实际的视口没有改变。也就是说,您仍将渲染到相同的宽度/高度和X / Y位置,并具有相同的深度范围。

您想要的是更改要渲染到的图像。这gl_Layer是为了什么?更改要渲染到的帧缓冲区的图像分层数组中的哪一层。

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

GS实例化调用具备成为一个限制; 那是你的选择。GS调用可以编写多个原语,每个原语都写入不同的层。因此,您可以让每个实例分别编写4个基元,每个基元分别写入4个单独的层。

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