在这种情况下我应该使用顶点着色器吗?

时间:2012-01-07 03:49:15

标签: c++ opengl graphics opengl-es shader

我想通过在帧的过程中在轨迹中的多个点处渲染和叠加运动对象来创建运动模糊效果。

我在想,确定绘图位置的计算可以在顶点着色器中执行。但在我看来,如果我想避免为每个渲染传递几何体,我可能需要使用几何着色器。

我最好的行动方案是什么?我决定:

  1. 每次手动组装每个子帧的顶点数据并将其传递给GPU(如果我这样做,我不需要顶点程序)
  2. 发送几何图形和速度值。我可以计算顶点着色器中的中间位置,但我不确定如何指定某个基本组的特定速度值。我需要为每个子帧渲染发送一次相同的顶点,因为顶点着色器无法创建新的顶点。
  3. 使用几何着色器生成所有子帧的所有几何体。我应该能够获得所有子帧,而不会在整个渲染过程中来回传递任何数据。
  4. 我想在这里取得的平衡是我希望最少的冗余数据传递,同时尽可能多地支持硬件。看起来我应该能够使用顶点缓冲区对象来存储我的几何数据,并且只需传递一些制服即可将速度数据发送到每个渲染上的顶点着色器。那样有用吗? VBO缓冲区也是持久的,所以为了获得最佳性能,我应该根据需要踩入并修改几何数据,对吗?

    另一个我不知道如何处理的潜在问题是我想通过插入刚性物体在一个帧上遍历的平移和旋转来精确地绘制我的中间位置,而不是仅仅插入合成的顶点位置。这里的区别在于旋转物体会留下弯曲的条纹。

    是否有某种方法可以防止必须为每个单独的动态刚性对象发出调用?也许我可以使用通用顶点属性来发送我的速度?这有点多余,因为我可以拥有一个具有相同速度数据的100个顶点的对象,但至少我的着色器可以通过这种方式得到这些数据的流。

    在我看来,通过在GPU上执行顶点变换可能没有太多的收获:我必须传递速度向量,角速度标量和质心向量作为顶点属性。这似乎是对带宽的巨大浪费。但是,我可以将该数据用于潜在的大量“样本”(子帧渲染)。

    我已经使用OpenGL立即模式很长一段时间了,但这次我想做正确的事情。

    更新:请参阅扩展评论讨论,了解其采取的方向。我现在相当肯定,由于“闪光灯效果”,多个样品不会产生好的结果:在某些速度下,出于性能原因,我需要使用模糊。在那种情况下,我需要累积模糊的子帧;渲染子帧然后模糊它仍然会留下瑕疵。

2 个答案:

答案 0 :(得分:3)

  

我想通过在帧的过程中在轨迹中的多个点处渲染和叠加混合移动对象来创建运动模糊效果。

这当然是实现运动模糊的一种方法。但是现在,运动模糊是通过片段着色器中的矢量模糊后处理过滤器实现的。有关其工作原理的说明,请参阅http://www.blender.org/development/release-logs/blender-242/vector-blur/。对于实时,必须使用后处理着色器重现该过程。

答案 1 :(得分:2)

  1. 软件渲染子框架 - 将此视为“基线”案例。
  2. 顶点着色器 - 您可以这样做,但不要尝试发送几何体速度,只需发送顶点速度:

    将帧渲染为VBO,调用glVertexAttrib以包含每个顶点的当前速度和加速度。重复渲染VBO,为每个子帧指定一个统一值的时间偏移量。

    然后,顶点着色器需要根据统一时间值应用offests。

  3. 几何着色器 - 如果您使用它,您可以像#2一样实现它,除了“循环和变化”将在着色器中实现 - 帮助将更多工作卸载到GPU。

  4. 你还提到:

    • 使用VBO渲染所有内容 - 如果你使用这样的VBO /显示列表,你基本上会做更多硬件加速的#1选项。
    • 插值问题 - 获得精确插值可能不值得您努力。除非物体移动速度非常快,否则速度(一阶)的线性插值可能很好。您可以通过加速(二阶)来改进它,但额外的订单或更准确的物理模型可能值得付出努力或成本。
    • 可能不值得 - 这确实是问题的症结所在。根据您的应用程序,硬件和其他详细信息,这些可能的解决方案中的任何一个都可能胜过另一个。如果性能很重要,您可能应该尝试每个的原型实现并在目标设备上运行基准测试以查看最适合的内容。 (令人遗憾的是,在你完成所有工作之前,你不能轻易地执行基准测试。)