我正在尝试使用OpenGL实现真正的运动模糊,但没有积累缓冲(由于它不能在我的显卡上工作)。以下是我的实现思路:
- 有一个固定的(暂时的)空白帧缓冲区数组&每个"模糊"的纹理
- 每当遇到新帧时,将第一个元素移到最后,并将 framebuffer渲染到,而不是
- 将它们全部渲染,第一帧具有1/n不透明度,第二帧具有1/(n/2),等等…直到最新的有1.
有没有比这更简单/更快/更优化的方法?或者这是最好的解决方案?
NicolBolas在他的评论中说的是正确的:要获得真正的运动模糊,你必须应用矢量模糊,这是由每个片段的速度控制;计算每个顶点的屏幕空间速度,并将其作为另一个统一的碎片着色器。然后在碎片速度的方向和距离上应用矢量模糊。
由于这将与其他片段模糊,你最终与透明度排序的问题。因此,你应该将其作为后期处理效果,理想情况下使用深度剥离层。您可以通过使用先前渲染的帧的积压来混合来节省深度排序的复杂性,这实际上是您建议的framebuffer方法,添加了矢量模糊。
一般有两种方法:
- 分别渲染最终帧的每个"子帧",然后在最终通道中将它们组合在一起
- 渲染子帧逐子帧,在每个通道中,您将读取前一个通道的结果,将其乘以您的权重系数,因此您的最终通道将是所有这些的组成。
要判断这些方法中哪一种效果更好并不容易。方法(2)的缺点是需要多次传递,因此开销很大。方法(1)将在纹理读取时遇到瓶颈。虽然在方法(1)中,你仍然最终读取所有的数据,你会在方法(2),在方法(1)中,你将能够利用多个缓存线的纹理内存获取的优势。所以这里决定性能的两个最重要的因素是
a)你有多少"子帧"b)你的屏幕有多大,因此要读取和写入的纹理有多大