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

时间:2019-04-09 16:30:16

标签: opengl graphics glsl shader viewport

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

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

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. 一个片段着色器,它discard的{​​{1}}坐标满足y的片段。

但是由于担心分支和y<gl_InvocationID*h || y>=(gl_InvocationID+1)*h会对性能造成极大的影响,我推迟了进一步研究此想法的时间。

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

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

1 个答案:

答案 0 :(得分:8)

粗略地看了一下论文,在我看来actual viewport并没有改变。也就是说,您仍将渲染到相同的宽度/高度和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)。