我目前正在实施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方法,所以我还不知道所有的技巧。我最初想过用以下组合替换我对内置视口支持的使用:
h*gl_InvocationID
是所需的视口高度)之后将y
添加到顶点的h
坐标,并将gl_InvocationID
传递到片段着色器上;和discard
s片段与y
坐标满足y<gl_InvocationID*h || y>=(gl_InvocationID+1)*h
。但是,由于担心分支和discard
对性能非常不利,我被推迟调查这个想法。
上面的论文的作者发布了一个描述他们的GPU加速方法的technical report,但它不够详细,无法回答我的问题。第3.2.3节说“在几何实例化过程中,视口信息附加到每个顶点......自定义像素着色器会剪切在预定义视口之外的像素”。这听起来类似于我上面描述的解决方法,但他们使用的是Direct3D,因此要比较2011年的功能与我今天在OpenGL中可以实现的功能并不容易。
我意识到我的问题唯一明确的答案是实现变通方法并测量其性能,但它目前是一个低优先级的好奇心,我还没有在其他任何地方找到答案,所以我希望更有经验的GLSL用户可能是能够提供他们节省时间的智慧。
从粗略地看一眼这篇论文,我觉得actual viewport并没有改变。也就是说,您仍然使用相同的深度范围渲染相同的宽度/高度和X / Y位置。
你想要的是改变你正在渲染的图像。这是gl_Layer
的用途;更改附加到要渲染的帧缓冲区的分层图像数组中的哪个图层。
因此,只需将gl_ViewportIndex
设置为0即可获得所有顶点。或者更具体地说,根本不要设置它。
GS instancing invocations的数量不一定是限制;那是你的选择。 GS调用可以写入多个基元,每个基元到不同的层。因此,您可以让每个实例写入4个基元,每个基元分别写入4个单独的层。
您唯一的限制应该是您可以使用的层数(由GL_MAX_ARRAY_TEXTURE_LAYERS
和GL_MAX_FRAMEBUFFER_LAYERS
控制,两者必须至少为2048),以及单个GS调用可以发出的基元和顶点数据的数量(即kind of complicated)。