OpenGL 动态物体运动模糊

7
我一直在跟进GPU Gems 3教程,学习如何根据相机移动进行模糊处理。但我也想根据物体的移动来实现模糊效果。文章中提供了解决方案(见下面的引用),但我很好奇如何具体实现。
目前,我正在将对象的矩阵与视图投影矩阵相乘,然后再分别对上一个视图投影矩阵进行相同的操作,并将它们传递到像素着色器中计算速度,而不仅仅是视图投影矩阵。
如果这确实是正确的方法,那么为什么我不能简单地传递模型视图投影矩阵呢?我本以为它们的值是相同的?
生成刚性动态物体的速度纹理,需要使用当前帧的视图投影矩阵和上一帧的视图投影矩阵来变换物体,然后通过与后处理通道相同的方式计算视口位置的差异。此速度应通过将两个变换后的位置传递到像素着色器中并在其中计算速度来逐像素计算。
参考链接:GPU Gems 3运动模糊
1个回答

10

请查看我几个月前在这个主题上所做的研究:https://slu-files.s3.us-east-1.amazonaws.com/Fragment_shader_dynamic_blur.pdf

标准渲染塔碾压
(来源:stevenlu.net)

模糊渲染的塔碾压
(来源:stevenlu.net)

遗憾的是,我在制作此材料时没有实现纹理对象,但请发挥您的想象力。我正在开发一款游戏引擎,因此当它最终以游戏的形式面世时,您可以确定我会来发布面包屑。

它主要解决如何在2D中实现此效果,在不重叠物体的情况下。使用片段着色器来“扫描”样本以生成“准确”的模糊是没有很好的处理方法的。尽管随着样本数量的增加,该效果接近像素完美,但必须手动组装覆盖扫描区域的几何形状,这些技术有点“丑陋”。

在完全的3D场景中,要知道动态对象在一帧中将扫过哪些像素是相当困难的问题。即使具有静态几何形状和移动的相机,GPU Gems文章提出的解决方案在快速移动物体时也是不正确的,因为它无法解决需要混合某个移动物体扫过的区域的问题...

话虽如此,如果这个忽略扫描的近似是足够的(可能是),那么您可以为动态对象进行扩展的方法是考虑它们的运动。当然,您需要详细研究一下,但请查看您链接的文章中第二个代码块中的第2行和第5行:它们是像素的当前和先前的屏幕空间“位置”。您只需要以某种方式传递矩阵,以使您能够计算每个像素的上一个位置,考虑到您对象的动态运动。

这不应该太麻烦。在渲染动态对象的过程中,您会发送一个额外的矩阵,表示其在最后一帧中的运动。

更新:我发现这篇论文描述了一种优雅且性能良好的方法,为3D流水线提供了相对高质量的物理正确模糊效果。在全场景仅渲染一次的性能限制下,很难再做得更好了。

我注意到其中一些示例的速度缓冲区的质量可能会更好。例如,旋转的轮子在速度空间中应该有一些曲线。我相信如果它们被正确设置(可能需要自定义片段着色器来渲染速度...),它们将看起来直观上是正确的,就像上面从我的2D探索中看到的旋转立方体。


谢谢这篇文章,我会在有更多时间的时候全神贯注地阅读它。昨晚我对我的方法进行了更多的工作。现在我正在将当前和上一个世界矩阵从顶点着色器传递到片段着色器中。我是否正确地认为,我需要将这些值转换为非齐次坐标才能偏移我的像素? - Aequitas
嘿@Aequitas,哇,已经过去两年了!我突然想到你可能还没有挖出我当时制作的gif。好吧,我仍然希望最终能够回到这个项目上来,并在重新设计我的网站时重新制作了这个答案。针对你两年前的实际评论,我基本上反对在每个片段上执行矩阵乘法的概念。所以你自己解决吧。 - Steven Lu
抱歉我的 HTTPS 证书已过期。 - Steven Lu

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