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

4
我想通过在帧的多个时间点上渲染和叠加混合移动对象来创建运动模糊效果。
我认为可以在顶点着色器中执行确定绘制位置的计算。不过,如果要避免为每次渲染传递几何体,则可能需要使用几何着色器。
我的最佳行动方案是什么?我正在考虑以下两种选择:
1.手动组装每个子帧的顶点数据并每次将其传递到GPU(如果这样做,则不需要顶点程序)。 2.沿着速度值发送几何体。我可以在顶点着色器中计算中间位置,但我不确定如何指定某个速度值分配给某些基元组。由于顶点着色器无法创建新的顶点,因此每个子帧渲染都需要一次发送相同的顶点。 3.使用几何着色器为所有子帧生成所有几何体。我应该能够在整个渲染过程中不传递任何数据就获取所有子帧。
我想要达成的平衡是尽量减少冗余数据传递,同时支持尽可能多的硬件。看起来我应该能够使用顶点缓冲对象来存储我的几何数据,并只传递一些uniform变量以在每次渲染时将速度数据发送到顶点着色器。这样可以吗?另外,VBO缓冲区是持久的,因此为了获得最佳性能,我应该根据需要定期进行几何数据的步进和修改,对吗?
我不知道如何处理的另一个潜在问题是,我想通过插值刚体对象在帧上遍历的平移和旋转来准确绘制中间位置,而不仅仅是插值结果顶点位置本身。区别在于旋转的物体会留下弯曲的条纹。
有没有办法防止为每个单独的动态刚体发出调用?也许我可以使用通用顶点属性来发送我的速度?这有些冗余,因为我可以拥有具有相同速度数据的100个顶点的对象,但至少这样我的着色器可以以这种方式获取数据流。
在GPU上执行顶点变换可能没有太多可获得的好处:我必须将速度向量、角速度标量和质心向量作为顶点属性传递。这似乎是一种带宽浪费。但是,我可以将该数据用于潜在的大量“样本”(子帧渲染)。
我很长时间以来一直在使用OpenGL即时模式,但这次我想做正确的事情。
更新:请参见扩展的评论讨论以获取其方向。我现在相当确定多个样本不会产生好结果,因为存在“闪光灯效应”:在某些速度下,我需要出于性能原因使用模糊。在这种情况下,我需要累积模糊的子帧;渲染子帧然后对其进行模糊处理仍将留下伪影。
2个回答

3
我想通过在帧的整个过程中以多个点渲染和叠加移动对象来创建动态模糊效果。
这确实是一种实现动态模糊的方法。但是,现在动态模糊是通过片段着色器中的矢量模糊后处理滤镜实现的。请参见http://www.blender.org/development/release-logs/blender-242/vector-blur/了解其工作原理。对于实时应用,必须使用后处理着色器来重现该过程。

我之前实现的二维运动模糊使用了一个片段着色器的方向模糊方法,问题是它会模糊和混合靠近移动物体的非移动物体,这是不可取的。除此之外,效果还是很好的。 - Steven Lu
我只是想说,我可以发送大量的2D几何图形,现代3D硬件可以轻松处理,因为它们被设计用于处理大型3D网格。我可能会通过多次混合到同一个像素中产生很多“过度绘制”,但这些都不会浪费,因为它实际上正在执行真正长时间曝光所做的事情。 - Steven Lu
@StevenLu:这种运动模糊仍然只累积个别采样点。运气不好的话,你可能看不到模糊,而是像“频闪灯”一样的图像。矢量模糊的好处在于,它不容易出现这种伪影。此外,性能将更好,因为您只需绘制整个场景一次,然后使用着色器在3个全屏幕四边形中进行后处理。不幸的是,我目前正忙于其他事情,否则我会做一个示例实现。 - datenwolf
我发现这个向量模糊方法很好地避免了静态物体的模糊,这是我之前错过的。这很好。虽然我应该能够通过在渲染缓冲区和片段着色器上执行模糊来避免每像素1个四边形的疯狂,因为我不需要担心遮挡。你提出了一个关于“闪烁”伪影的好观点:如果我渲染足够多的样本以完全覆盖扫描区域,我将能够避免它,但对于我无法负担渲染所需的许多样本的大型平移,我将需要进行模糊处理。嗯。 - Steven Lu
我可以在渲染子帧时使用模糊片段着色器。如果我能确保模糊相互匹配并互补,那么我就可以通过这种方式获得子帧细节。 - Steven Lu
显示剩余12条评论

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

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

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

  3. 几何着色器 - 如果您选择了这个选项,您可以像第2种方法一样实现它,只是“循环和变化”将在着色器中实现,从而有助于将更多工作卸载到GPU上。

您还提到:

  • 使用VBO渲染所有内容 - 如果您像这样使用VBO /显示列表,则基本上正在执行选项#1,具有更多的硬件加速。
  • 插值问题 - 要获得精确的插值可能并不值得。除非物体移动非常快且弯曲,否则速度的线性插值(一阶)可能已足够。您可以通过包括加速度(二阶)来改进它,但更高的阶数或更准确的物理模型可能不值得付出努力或成本。
  • 可能不值得 - 这实际上是问题的关键。根据您的应用程序、硬件和其他细节,这些可能解决方案中的任何一个都可能优于另一个。如果性能很重要,您应该尝试每个原型实现,并在目标设备上运行基准测试,以确定哪种最适合。 (可悲的现实是,在完成所有工作之前,您无法轻松进行基准测试。)

我很感激你的分析。我又仔细思考了一下这个问题,意识到我想要根据物体移动的速度来改变每个物体的样本数量。所以这是我的计划:我会在CPU上组装我的顶点缓冲区,其中包括所有的变换和适当的混合值,使用alpha通道,并且我将永远不需要编写一个顶点着色器。 - Steven Lu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接