首 页 | 博 客 | 试读下载 | 读者反馈 | 在校学生特惠申请 | QQ群: 308861655

DirectX Raytracing会取代VXGI吗?


#1

转一个来自知乎的问题,因为我们的图书会包含VXGI的内容,这里也是对其的一个某种介绍


#2

以下转载自我来自知乎的回答,原文这里:
https://www.zhihu.com/question/269610419/answer/360441082

首先,正如龚大所言,这两个确实不是一个东西,所以不存在直接的“取代”的问题。
我想题主的意思可能是“以DXR所能实现的光线追踪算法在GI方面能够替代现在的VXGI算法吗?”,如果问题是这样,那答案就非常简单,那就是现在光线追踪算法远远不能做到实时。不过问题又来了,可DXR说它是“实时光线追踪”(real-time ray tracing)啊,所以这就导致了题主的困惑。
要解开这个困惑,我们从三个方面来阐述,首先是DXR的实时光线追踪到底是不是真的,如果不是真的,它到底包含了那些内容;其次是将现有DXR能实现的效果与VXGI进行比较;最后是如果DXR仅仅是一个光线追踪框架,VXGI能否集成即DXR中。

DXR实现了完全的实时光线追踪了吗?

这个答案毫不犹豫的是:No!
你在GDC上看到的所谓real-time ray-traced demo,实际上并不是整个渲染都是基于光线追踪的,整个渲染的大部分工作都还是传统的光栅化来完成的,DXR基本上只用来做反射,环境遮挡,和面积光源产生的软阴影等少数几项事情。为什么,因为一条光线的成本太高了,所以目前DXR能够实时完成的事情,基本上满足两个条件:一是光线数量很低,例如目前实现的几种效果都是针对屏幕空间(screen space)的像素发射光线,也就是光栅化生成的可视图像所在的那些像素;二是每个像素只发射一条或者少数几条光线,例如反射只需要对屏幕空间的每个像素沿反射方向只发射一条反射光线,而AO和针对面积光源的Shadow rays也只需要少数几条光线即可。这样下来,整个场景每一帧也就是针对屏幕空间的每个像素发射少数几条光线而已,仅此而已,甚至两次以上反弹想都不用想。但即便这样,你都需要一个买不起的Volta。
另外也有一种情况,那就是完全使用光线追踪,而不包含光栅化,这种情况就是从摄像机向每个屏幕空间的像素所在的范围随机发射一条光线,然后根据BRDF随机选择一个方向,并且反弹控制在极少的数量,例如2,3次,这样下来每个屏幕空间的像素差不多也只有几条光线,整个过程都是基于蒙特卡洛方法的,由于光线数量非常少,所以最后的结果就需要严重依赖于降噪(denoising),文大他们展示的一些这些面的工作大概就是这个思路。这和上面的两个条件基本上也是吻合的,即只对屏幕空间的像素发射光线,并且每个像素只产生很少的几条光线?
那我们在激动什么呢?其实DXR并没有什么技术的革新,是NVidia在宣传显卡而已,在向你兜售未来,开玩笑的。我觉得DXR的意义就是将这种少数光线能做的事情开始引入到光线追踪算法中,这不仅仅是说我们迈出了第一步的事情,实际上它带来的画面提升也是非常大的,比如传统的光栅化只能处理点光源,即便是面积光源,也大都是被近似为一个“点光源”后按照阴影贴图的方式来做,但是使用DXR,面积光源完全按真实的物理方式去计算,这种效果的提升不仅仅是“画质”上的提升,它是由近似向物理正确上的提升,你看GDC上那些Demo,即便是简单的场景,使用DXR的面积光源要比光栅化的画面效果要好得多,因为整个场景更加接近自然。
但是,但是,但是,我们离完全的实时光线追踪是不是近了,毕竟我们迈出了第一步不是?
通常人类做一件事情,只要迈出第一步,第二,三…步通常很简单,最后99步可能非常困难,但是对于光线追踪来讲,第一步跟第二步的距离会非常漫长,毕竟光线一反弹起来就不可收拾。

现有的DXR GI与VXGI的比较

那当然也是不好比较了,DXR目前实现的主要是反射,AO和面积光源,VXGI实现的主要是间接光照,你让DXR去追踪一下间接光试试,估计10块Volta都不够!
当然它们都能处理AO,从效率上讲,VXGI肯定要快,比较它是对阶层式的稀疏场景执行圆锥体追踪(cone tracing),而DXR是对整个几何场景的三角形网格执行光线追踪(ray tracing);但是从结果来讲,DXR绝对要好得多,因为Ray tracing本书是基于物理的,而VXGI的cone tracing是基于体积渲染积分模型的,它在光线步进的过程中,其遮挡关系是通过混合出来的,这种方式随着步进的距离的增大,其误差大大增加,并且cone的半径过大也会导致误差。从下图就可以看出,观察点的发出的Cone上有两个物体各遮挡50%,从实际上看观察点被完全遮挡而处于阴影当中,而实际上在VXGI中它的可见性为25%=50% x 50%。关于VXGI可以在《全局光照技术》中找到更多更详细的描述。


VXGI的Cone tracing使用的体积渲染模型

所以这也可以看到,目前实时渲染的方法,大都是近似,从这就可以看出上面所说的“由近似向物理正确的”转变的意义所在。

VXGI可以集成进DXR中吗?

目前我们更愿意把DXR看做一个框架,而不是一种光线追踪算法,那新的问题是,VXGI可以集成进DXR吗,龚大的回答里也提到这个问题。据我所了解,不太容易,或者说效率很低。这主要有两个方面的原因。


DXR的光线追踪管线

首先是DXR所支持的基元类型的限制。DXR目前支持两种类型的基元类型,一种是三角形网格,一种是自定义的程序化基元(procedural geometry primitives),其中后者仅向DXR传输一个AABB的包围盒,然后具体的形状有application提供的一个intersection shader来实现,这个方面VXGI以体素的形式存在,显然只能选择后者。这个从表述上看问题不大,但是效率会有很大问题,首先是procedural primitives的性能本身并不如triangle primitive,其次是DXR基于光线追踪,它会遍历所有体素结构,其光线与体素的相交顺序是不定的,因为DXR内部会针对光线与AABB包围盒的相交计算执行一定的调度,比如重新排序;而VXGI则是基于对阶层式结构的遍历,它依赖于由近向远或者说由前向后的步进顺序,这里直接就矛盾了,DXR并不保证这种顺序。
第二个问题更加严重,VXGI是基于光线步进(ray marching)算法的,这个步进的目的是为了能够根据步长来选择阶层式体素结构的分辨率层级,据我所知,DXR目前完全不提供ray marching的机制,它只有光线与几何体相交时才触发相关的shader调用。你可以说,如果我设置一个覆盖整个空间的几何体,然后在shader来做全部工作呢,那我说为什么不直接用compute shader呢,不然的代码还要在DXR的管线里空跑一趟干什么呢?