DXR对如VXGI之类的全局光照算法有多大的影响?

[复制链接]
查看3166 | 回复7 | 2018-4-7 18:15:57 | 显示全部楼层 |阅读模式
本帖最后由 theGIbook 于 2018-4-7 18:56 编辑

看到知乎上有关于DXR能否取代VXGI之类的全局光照算法,这里将其回答分享给观众号的朋友们。

首先DXR和VXGI并不是一类事物,其中算是一个框架,而后者是一个全局光照算法。如果非要比较的话,也许可以说成“以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,仅就针对AO而言,从效率上讲,VXGI肯定要快,毕竟它是对阶层式(hierarchical)的稀疏场景执行圆锥体追踪(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的管线里空跑一趟干什么呢?

以上关于VXGI的更多知识,《全局光照技术》中会有完整的一个章节的介绍;另外,关于DXR,我近期在发起一个全国的渲染技术线下巡讲活动,将在近几天开始报名,这个活动中会包含半个小时关于DXR的内容。

另外,我在翻译DXR的SDK文档,参见这里:

zhaishengfu | 2018-4-7 18:48:34 | 显示全部楼层
可以技术贴赞一个
回复 支持 反对

使用道具 举报

ninjia | 2018-4-7 21:48:35 | 显示全部楼层
期待作者的巡回读书见面会  已经订购图书 广州站到时见
回复 支持 反对

使用道具 举报

yxmm | 2018-4-8 09:06:16 | 显示全部楼层
国内还是以手游开发为主,这些东西太遥远,没什么可关注的。
回复 支持 反对

使用道具 举报

teafeel | 2018-4-8 09:59:07 | 显示全部楼层
谢谢分享受教了
回复 支持 反对

使用道具 举报

Sierkin | 2018-4-8 15:44:24 | 显示全部楼层
不错,赞一个~~~~
回复 支持 反对

使用道具 举报

cg_bull | 2018-4-8 16:25:05 | 显示全部楼层
看使用NV的VXGi可以做反射和漫反射的追踪,CongTracing做这种东西我1080Ti都卡成狗。RayTracing要我上天河二号么(滑稽滑稽)。
回复 支持 反对

使用道具 举报

myp158 | 2018-4-9 07:58:29 | 显示全部楼层
期待楼主的全局光照
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

6

主题

17

回帖

1230

积分

中阶编码师

积分
1230