【图形学】体素全局光照GI

时间:2024-03-15 19:25:23

前段时间出了虚幻引擎5,介绍说是可以实现实时光线追踪,感觉不可思议,后来看文章发现大部分的光线追踪都是基于体素的光线追踪(消耗比较小),一小部分的光线追踪是基于屏幕的射线。于是找了文章开始了解体素光线追踪。

这个技术是英伟达提出来的,不算真正意义上的光线追踪,有点近似的感觉,但是效果也很逼真,下面介绍一下:

本文算法总共有四个阶段,分别为体素化、直接光照、各向异性过滤、间接光照,算法的各个阶段如图1所示。第一阶段是体素化阶段,将图元为三角形的场景转换为体素场景,计算单个体素的基础属性并存储。第二阶段是直接光照阶段,计算光源照射到每个体素上的直接光照,并将其作为出射辐射度存储在体素中。第三阶段为各向异性过滤阶段,将体素的出射辐射度经过各向异性过滤形成层级,既简化了存储光线传输的方向,又保持后续采样的一致性。第四阶段是体素锥追踪阶段,通过锥体的光线束来收集第二阶段中体素的出射辐射度,并用来计算间接光照。

【图形学】体素全局光照GI
图1 四个阶段

第一个阶段就是场景体素化。原来场景的Mesh都是由三角形面片组成的,现在转换成立方体块的体素,这里稍微有点疑问,体素化是发生在哪一个阶段呢,我个人认为这里是进行了预结算,把场景直接体素分块,然后在摄像机旋转的时候再去获取相应场景的体素块。(文章中的体素块是被做成三维纹理来存储的,可以用一个三维坐标来获取体素值,这里的体素值里包括法线等信息(如果是有法线信息,那么这个法线应该是在世界坐标空间系里的))

第二个阶段是计算直接光照,就是利用光线传输方程,出射辐射度等于所有入射辐射度之和,不过一个体素中可能有多个法线,这时不能做简单的加法然后取均值,因为均值之后这个法线可能就收不到光照了,所以要考虑衰减值等等。具体公式如下:

【图形学】体素全局光照GI

:k 为体素内子三角形的数量;nj为体素内子三角形的法线;V 为法线衰减值;ns和Ls为法线和入射光在三个坐标轴上的分量。根据均值法线的方向选取入射光主轴方向,分别计算三个轴上的衰减,再采用法线权值求和,以避免均值法线方向不当而影响体素内光照的情况。

还要计算环境光遮蔽情况,(这里简单解释一下AO环境光遮蔽,就是用来模仿全局阴影,从一个点出发向半圆球内射线,如果命中物体射线越多,则这个点越暗,命中光源越多,这个点越亮)

第三个阶段是各项异性处理,这里留个坑 没太看明白

第四个阶段就是利用体素锥进行追踪,

【图形学】体素全局光照GI

这里,漫反射通过6个光圈值为60°的锥进行追踪如图b,高光反射通过一个光圈值为10°的光锥进行追踪,如图d。

这里的l是出射辐射度的反方向,也就是视线方向。

【图形学】体素全局光照GI
单个光锥追踪

这里的利用体素锥进行追踪和光线追踪有点不同,区别在于它是一个整体的光线步进,如上图,而传统管线追踪是每个光线单独去步进检测碰撞。

单个锥体采样的过程类似于光线步进,锥体的光圈值为γ,锥体的方向为d,锥体每一步会步进一定的距离,然后对辐射体进行一次采样,采样的层级由锥体底端的半径确定。设t 为步进的距离,则锥体底部的半径r=2t×tan(γ/2),采样层级为log2(r/Vmax),Vmax为渐近贴图最高层级的体素边长,即三维场景的最长边的大小。在第m步中,锥体都需要对辐射度cm与累积遮蔽值am进行计算。如下图

【图形学】体素全局光照GI锥体累积到指定的距离后,cm就是间接光照值。

这里一些法线的计算,还有各向异性计算都是paper中提到的,一般的算法流程中可能略有不同。但是总体流程大致相似

参考资料

  1. 桂梅书, 侯进, 谭光鸿,等. 基于体素锥追踪的全局光照算法[J]. 光学学报, 2019, 39(6).
  2. 博客https://blog.csdn.net/pizi0475/article/details/49422123