【问题标题】:OpenGL motion blur without accumulation buffer没有累积缓冲区的OpenGL运动模糊
【发布时间】:2013-05-08 08:04:56
【问题描述】:

我正在尝试使用 OpenGL 实现 真实 运动模糊,但没有累积缓冲区(因为它在我的显卡上不起作用)。这是我的实现想法:

  • 为每个“模糊”设置一个固定的(临时)空白帧缓冲区和纹理数组
  • 每当遇到新帧时,将第一个元素移动到末尾,然后渲染到那个帧缓冲区
  • 全部渲染,第一帧的不透明度为 1/n,第二帧的不透明度为 1/(n / 2),依此类推...直到最新的帧为 1 .

还有比这更简单/更快/更优化的方法吗?或者这是最好的解决方案?

【问题讨论】:

  • 此算法不会产生任何类型的“真实”运动模糊。
  • @NicolBolas,以什么方式?它不工作吗?如果没有,我怎样才能让它工作?
  • 它肯定会“模糊”,它会有“动感”。但它不会像 现实 运动模糊。它只是混合帧,最远的帧淡出。这不是运动模糊在“真实”世界中的实际运作方式。

标签: c++ algorithm opengl motion-blur


【解决方案1】:

NicolBolas 在他的 cmets 中所说的是正确的:要获得真正的运动模糊,您必须应用由每个片段的速度控制的矢量模糊;计算每个顶点的屏幕空间速度,并将其作为另一个统一传递给片段着色器。然后在片段速度的方向和距离上应用矢量模糊。

由于这会与其他片段模糊,您最终会遇到透明度排序问题。因此,您应该将其应用为后期处理效果,最好使用深度剥离层。您可以通过使用积压的先前渲染帧进行混合来节省深度排序的复杂性,这本质上是您建议的帧缓冲区方法,并添加了矢量模糊。

【讨论】:

  • 我对着色器还是很陌生,我该如何实现呢?我什至找不到任何关于矢量模糊的文档!你能给出一些示例代码吗?
  • @MiJyn:YouTube 上有一段视频展示了我的建议。该技术也在clementshimizu.com/… 上的一篇论文中进行了描述,尽管它使用 Cg 而不是 GLSL 作为着色语言。不过原理是一样的。
  • 你发送的链接给了我一个 403... 你能链接 youtube 视频吗?
  • 您可以从here下载论文。
【解决方案2】:

有两种通用的方法来做这种事情:

  1. 分别渲染最后一帧的每个“子帧”,然后在最后一个通道中合并所有子帧
  2. 逐个子帧渲染子帧,在每次传递中,您将读取前一次传递的结果,将其乘以您的权重系数,因此您的最终传递将是所有这些传递的组合。

判断这些方法中哪种方法效果更好并非易事。方法(2)的缺点是您要通过很多次,因此开销很大。方法 (1) 将在纹理读取时受到瓶颈。尽管在方法 (1) 中,您最终仍会读取方法 (2) 中的所有数据,但在方法 (1) 中,您将能够利用多个缓存线来获取纹理内存。 所以决定性能的两个最重要的因素是

a) 你有多少个“子帧” b) 你的屏幕有多大,因此要读取和写入的纹理有多大。

【讨论】:

    猜你喜欢
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    相关资源
    最近更新 更多