文章

Games202(5·第9章,实时GI总结)

第9章

Screen Space Directional Occlusion (SSDO)屏幕空间方向遮蔽

DO

在AO中,我们假设每个p点受到的环境光都是常数,虽然AO效果更强烈,但是只是简单的让遮蔽位置整体暗一点,而不能颜色混合(现实世界中环境光是有颜色的)

DO利用了ray tracing思想,向周围发射光线,和AO相反的是,AO的 RT思想是未击打的部分可以接受间接光照,击打的部分表示被遮挡,这和DO是刚好相反的

其中DO未击打部分计算直接光照,击打部分计算被击打Q点的直接光照对p点的radiance贡献

现实的情况是AO和DO的混合,所以它们并没有矛盾

Rendering Equation分解简化

对于次级光源是哪些点,仍然用之前的做法RSM,对于渲染方程我们会将没有遮蔽的部分与遮蔽的部分分开考虑,我们只关心V == 0 的部分,因为这些点提供间接光照,但如何求得哪些patch的V == 0呢?

我们需要知道哪些次级光源对p有贡献,与AO一样的是在半球区域撒点,在屏幕空间也就是camera方向看patch的V(也就是深度值),但是V项判定是反的,如果x点比摄像机SM中pixel的depth值大,则x点提供间接光照

问题

1741272814251

和AO一样由于都是在屏幕空间,仍然会出现判断错误,例如A点,我们判断为V == 0,但实际上它的patch是没有遮挡的

Screen Space Reflection (SSR)屏幕空间反射

它也可以叫做Screen space Raytracing屏幕空间的光线追踪,不需要知道3D空间中的三角形、网格、加速结构等3D信息,只需要屏幕缓冲区(也就是camera)中已有的这些信息

镜面反射

当我们看到一个光滑地面反射的场景信息,其实就是GI,因为它接受了其他场景给它的间接光照,那么如何渲染它呢?

steps:

  • 对于p点已知屏幕中的颜色、法线、深度……信息
  • 根据相机发射的ray方向,依据法线求出反射光,在场景中找到交点,得到的反射值作为p点的GI值

屏幕空间RayMarch光线步进

3d空间的raytracing,每个光线都要遍历场景中所有物体求交(虽然可以用例如BVH的空间加速结构),会很慢,屏幕空间不必每次去遍历所有物体,而是依据march方式比较深度值,相当于与camera方向看场景的一层外壳求交

沿着反射方向以一个固定的步长逐步前进,每一次获得的深度如果 > 缓冲depth,则表示找到交点停止步进, 从而投射到交点所对应屏幕上的pixel,从而获得GI信息

Hierachical ray trace层级光线追踪

RayMarch质量取决于步长的大小,步长小越精准,同时计算量也越大(每次都要做一次深度比较),我们引入一种动态决定步长的方法,它是一个加速结构,可以快速跳过不可能相交的像素

首先把场景的深度图,做一个mip-map,但这个跟平常的mip-map不一样,高一级的Mipmap存的并不是周围四个像素的深度平均,而是四个像素中深度的最小值

最小值mipmap

1741319393459

最小值mipmap的思想非常类似空间数据结构,比如看这个1维表示的深度图,每个横轴格子代表一个像素,纵轴代表深度值(深度值越小纵轴值越高),

红色线为ray的深度,高度代表深度,长度表示march步进的长度(对应到了某个像素的xy),我们只看ray的终点位置是否有交点

对于LVL0每一格是一个pixel,LVL1是每两格,LVL2是每4格,比如看LVL1的12像素,由于记录的是最小值,我们取a的深度值,光线并不会和它相交,因此内部的12都不用看

求交Steps:

1741319398398

  • 从lvl0第一个pixel开始,走1格,发现没有交点
  • lvl++,lvl1,在已有基础上走2格,发现没有交点
  • lvl++,lvl2,在已有基础上走4格,发现有交点
  • lvl–,lvl1,发现有交点
  • lvl–,lvl0,发现没有交点
  • lvl++,lvl1,在已有基础上走2格,发现有交点
  • lvl–,lvl0,发现有交点,求交结束

也就是如果没有交点,就去高层级,走像素格步, 如果有交点,去底层级,是否相交,

如果到达了最底层有交点,即求得交点,如果超出了像素范围 / march太长 则没有交点

问题

由于只关心屏幕的部分,当raymarch到屏幕外,不再有pixel的深度值作比较时,就得不到反射,因此会出现断层,可以通过衰减 减少违和感

IBL . PRT . RSM . LPV . VXGI . SSAO . SSDO . SSR总结

它们都是RTR实时渲染中实现GI的方法

IBL:

  • 对场景渲染一张环境贴图,以cubemap/sh存储
  • 将rendering equation分解简化,以便预计算L,F,Max……项

PRT:

  • 对场景渲染一张环境贴图,以cubemap/sh存储
  • 将rendering equation分解为入射光和传输函数两部分,
  • 预计算L,F,V,Max……项,并利用基函数存储,在运行时只需要简单的线性组合,就可以计算出p点的GI值

RSM:

  • 对每个光源渲染一张反射阴影贴图RSM,pixel存储深度,世界坐标,法线等信息,每个pixel对应的世界网格作为次级光源 ,
  • 对每个p点,投影到RSM中,从RSM中取临近像素对应的次级光源 * 权重 ,并求累加和作为p点的GI值

LPV:

  • 把3D场景划分体素,利用空间数据结构
  • 利用SM找到次级光源,并注入到体素内(一个体素可能包括多个光源),
  • 遍历体素内所有次级光源,从中心的6方向(上下左右前后),传播radiance,接收到radiance的各自用2阶的sh表示,
  • 对于p点找到所在的体素,获得体素存储的所有radiance,即p点的GI值

VXGI

  • 把3D场景划分体素,利用空间数据结构
  • 利用SM找到次级光源,并注入到体素内,还包括输入方向和法线范围两个信息,根据材质准确算出出射方向
  • 对于p点是根据camera ray找到的,因此知道入射方向,根据p点的表面材质
    • Glossy,向反射方向追踪出一个锥形(cone)区域,对体素层级查询,找到所有与锥形相交的体素,通过体素的2个信息计算的radiance得到p点GI
    • diffuse,考虑若干cone

SSAO

  • 自定义环境光 * 以p点的法向半球内撒点作为遮挡/未遮挡因子 * 权重 计算V项

SSDO

  • 根据RSM求得次级光源的贡献值 * (乘以)
  • 以p点的法向半球内撒点作为遮挡/未遮挡(和AO相反)因子 * 权重 计算V项

SSR

  • 相机发射ray方向,对于p点,已知屏幕缓冲中的颜色、法线、深度……信息
  • 依据法线求出反射光方向,利用屏幕光线步进,在场景中找到交点,依据屏幕缓冲中的数据作为p点的GI值
本文由作者按照 CC BY 4.0 进行授权
本页总访问量