【GAMES-202实时渲染】4、3D空间全局光照(RSM、LPV、VXGI)

article/2025/9/11 20:44:27

Lec7~8

  • 1、Reflective Shadow Maps(RSM)
  • 2、Light Propagation Volumes(LPV)
  • 3、Voxel Global Illumination(VXGI)

1、Reflective Shadow Maps(RSM)

RSM是一个特别经典的计算全局光照的方法,前置基础知识为:辐射度量学+光线追踪原理

全局光照(Global Illumination)= 直接光照 + 间接光照

计算着色点 p p p 间接光照的步骤(2-pass)

  • 找出被光源直接照亮的面片 (surface patch)

    • shadow mapping,每个纹素都对应空间中的一块离散的面片
    • 对于每个直接照亮的面片 q q q,需要知道对于它来说直接光的出射方向。这个方向不是相机的方向,而是目标着色点 p的方向,并且我们不知道q点的brdf。因此需要做个假设:被光源直接照亮的反射物是diffuse的
  • 把每个面片当做新的光源,计算每个间接光源反射到 p p p 点的能量为多少

    • 考虑在之前101中提到的对光源直接采样
    • 积分换元、间接光源的面片所覆盖的立体角上的积分变为直接对光源面片范围做积分
      在这里插入图片描述
    • 的是渲染方程中的 Visibility 项,即在当前的微元方向上,p、q点之间是否有障碍物。因为p的间接光计算并不只是算某一个间接光源,而是很多个分布在半球各个地方的间接光源。每个p点生成一个shadow map 这不仅不现实,甚至还不够。。半球上得多少张shadowmap才能覆盖啊?所以不好算,解决方式为: 不算

下面公式中,就体现了上面描述的过程,要注意的是

  • 公式是计算p点的着色结果, L i ( p , ω i ) L_i(p,ω_i) Li(p,ωi)才是次级光源反射过来的光
  • 因为我们假设所有次级光源的面片都是diffuse的,所以 L i = ρ π ⋅ Φ d A \displaystyle L_i=\frac{ρ}{π}·\frac{\Phi}{dA} Li=πρdAΦ ρ π \displaystyle\frac{ρ}{π} πρ为diffuse的BRDF, Φ d A \displaystyle \frac{\Phi}{dA} dAΦ为次级光源所接受到的irradiance
  • 论文中的公式分母的幂次错误,4应该改为2。(其实没错,闫老师吃键盘)
    在这里插入图片描述

到此,一个次级光源传递到着色点的能量就算出来了


如何计算有哪些次级光源能影响到目标着色点?—— 在光源处的shadow map上,取着色点附近的某一堆纹素所对应的场景的面片作为能够影响到着色点的次级光源

  • 依然不考虑可见性,即次级光源是否被某些障碍物挡住
  • 不考虑着色点所在面片的朝向
  • 不考虑次级光源与着色点的实际距离
  • 如下图所示,注意与课程中的符号不同,图中着色点为 x x x,其在shadow map上对应的点为p,而p点周围的纹素对应到场景中的次级光源面片为 x − 2 , x − 1 , x 1 , x 2 x_{-2},x_{-1},x_1,x_2 x2,x1,x1,x2
  • x − 1 x_{-1} x1为例,对应在shadow map上的纹素,记录的应该是个桌子,这桌子上的这个间接光源是根本不可能照亮x的
    在这里插入图片描述

2、Light Propagation Volumes(LPV)

直接光照还是照常计算,LPV方法来解决 实时间接光照计算。细节太多,代码实现比较难,下面记录主要思想

关键问题:快速查询到任何一个着色点的来自任何方向的间接光radiance(废话)

关键思想:radiance在空间中传播的过程中不会改变

关键方法:使用空间中的一个个3D的格子来传输从间接光源发射出来的radiance

把场景切分为一个个网格(简单的划分格子,并不涉及层次结构)如下图所示,红色部分就是间接光源反射出来的radiance。想要知道任何一个格子接收到的radiance是多少,应该怎么算?
在这里插入图片描述

算法步骤(4-pass)

  • 生成: 找到场景中接收到直接光照的次级光源Virtual Light Sources(VLS)(同RSM的第一步shadow map,多少光源就做多少张shadow map,最终采样一部分VLS即可)

  • 注入: 把场景预处理为3D格子(3D纹理),遍历每个格子,把这些次级光源注入最近的格子内。这些格子记录的是VLS向四面八方辐射出的能量分布,因此可以用SH基函数来压缩记录(通常选用4个来大概的表示)。既然用了SH函数,也就假设了次级光源面片为diffuse
    在这里插入图片描述

  • 传播(Propagation ): 从记录着VLS的格子上,往周围6个格子传播radiance(按分布情况进行分配), 下图所示依次为向右、左、上、下传播的情况,接收到能量的格子依然用SH来表示。重复所有格子的传播,直至稳定(通常迭代4~5次)。迭代结束后,空间中每个格子的能量分布情况就已知了
    在这里插入图片描述

  • 着色计算: 每个着色点所在格子的 radiance入射分布 已知,解一个渲染方程即可

算法缺陷

  • 如下所示,p点为VLS,它不应该照亮墙体的反面,但是在LPV算法下,只要这个墙比格子的划分粒度还小,则会被照亮。很简单,因为在LPV算法中认为,每个格子内的着色点所接收到的radiance分布一致。也就是背面的点因为跟p在同一个格子内,在着色计算时就会用p点的反射出去的radiance来计算着色,就会被照亮
    在这里插入图片描述
  • 因此不可以免的会有下面这种 Light leaking 现象,格子不可能无限的小,计算量受不了
    在这里插入图片描述

3、Voxel Global Illumination(VXGI)

与RSM一样,是2-pass算法
在这里插入图片描述

VXGI与前两个算法(RSM,LPV)的区别

  • 在RSM中,shadow map上的每个像素代表的都是场景中的次级光源表面。在VXGI中,整个场景完全 体素化,并且是树状带层级关系的
  • VXGI的第二趟是从相机出发,打到像素上,然后以锥形向外反射(cone tracing),锥形会相交到体素化的场景中的VLS(虚拟光源),这些体素对着色点的贡献就能算出来。此过程与其他算法的区别如下
    • RSM中做了很多假设,比如次级光源全部看做diffuse材质、不考虑实际次级光源到着色点距离等,因此RSM很不准确
    • LPV中的次级光源完成注入后,仅做 一次传输,即可得到 所有着色点 的入射radiance分布,快但不准
    • VXGI需要每个着色点向外进行锥形探测,因此速度会慢很多,但是着色结果比较准确

VXGI算法步骤

  • pass 1: Light pass
    • 找到哪些体素会被光源 直接照亮
    • 对于这些体素,存储入射光分布,以及本纹素内所有面片的法线分布。(注意区别于LPV只存入射分布)
    • 已知入射光分布方向,以及法线的分布方向,就能够算出不同材质(glossy diffuse)下的表面的 出射光方向分布。这样确实会比RSM直接假设次级表面为diffuse要准
    • 更高层级的体素,就统计他下面所有的小体素的入射、法线分布,形成对于当前层级的体素所包含的所有微表面的入射、法线分布,有点类似MIPMAP的思想
      在这里插入图片描述
  • pass 2: camera pass
    • 对于glossy表面来说,一根光线,反射后变成一个圆锥
    • 暴力一点就直接用椎体与场景所有的体素求交,每个体素都有入射光、法线分布,因此对于任意一个点的反射的radiance就能够算出来,将所有体素对于着色点方向的radiance加起来就成。这么暴力就很
    • 因为树状层级关系的存在,巧了不是,还就是MipMap的思想,根据圆锥越来越大的覆盖范围,直接查询树状结构存放的体素信息,直接查高层的体素,就很快
      在这里插入图片描述
  • 对于diffuse表面,则反射多个圆锥即可
    在这里插入图片描述

效果:非常不错,很接近与路径追踪的渲染结果了

  • 直接光照部分
    在这里插入图片描述
  • 体素可视化
    在这里插入图片描述
  • 每个体素存放的经过计算后的反射分布可视化(应该是吧。。不太确定哈)
    在这里插入图片描述
  • 间接光照渲染结果
    在这里插入图片描述
  • 最终全局光照结果
    在这里插入图片描述

VXGI大概是2012年发表的,效果不错,但是 开销太大

  • 场景的体素化,计算量太大,甚至需要预处理
  • 对于动态物体的实时体素化是很难算的
  • 这个算法的步骤,很类似于离线渲染中的Photon Mapping了,所以 确实慢


http://chatgpt.dhexx.cn/article/HTq1Ckuo.shtml

相关文章

lpv

测试了Light Propagation Volumes,全实时没有任何预处理的GI,而且可以适用任意场景。 文档很长,不过基本原理还是比较直白的: 生成reflect shadow map(rsm)。 将rsm信息用SH系数方式注入一个volumetexture中。 在vol…

操作系统经典 pv过桥问题

Semophere bridge1; Semophere mutexNS1,mutexSN1;//用于保护countNS,countSN int countNS0,countSN0; Semophere s11,s20;//用于交替通过 StoN(){while(1){P(mutexSN);countSN;//来车了v(mutexSN);p(mutexSN);if(countNS0){//对面无车,则直接通过P(bridge);通过countSN--;V…

C语言解决四人/多人过桥问题

参加笔试的时候遇到一道经典的算法题,四人过桥问题。当时没写出来😅。 四人过桥问题:在一个黑夜里,有四个人需要过桥,每次只能通过两人,其中一人必须拿着手电筒;但只有一个手电筒,所…

小明过桥问题

小明家必须要过一座桥。小明过桥最快要1秒,小明的弟弟最快要3秒,小明的爸爸最快要6秒,小明的妈妈最快要8秒,小明的爷爷最快要12秒。每次此桥最多可过两人&…

过桥问题

在一个夜黑风高的晚上&#xff0c;有n&#xff08;n < 50&#xff09;个小朋友在桥的这边&#xff0c;现在他们需要过桥&#xff0c;但是由于桥很窄&#xff0c;每次只允许不大于两人通过&#xff0c;他们只有一个手电筒&#xff0c;所以每次过桥的两个人需要把手电筒带回来…

过桥问题的通解

问题一,一个典型过桥问题: 小明一家5口人在夜晚过一座桥,小明过桥要1分钟,小明的弟弟过桥要3分钟,小明的爸爸过桥要6分钟,小明的妈妈过桥要8分钟,小明的爷爷过桥要12分钟;这座桥每次只能过2个人,因是夜晚,过桥时必须提着灯,小明有一只灯,点燃后30分钟会熄灭,问怎…

如何打开tdms文件?

https://www.zhihu.com/question/305029962/answer/1203851780v 下载地址 http://www.ni.com/example/27944/en/ 还有一个综述&#xff0c;写的挺好&#xff01; https://wenku.baidu.com/view/c62700e4aa00b52acec7ca09.html

转载:TDM协议

转自http://www.wangdali.net/i2s/ 1. PCM简介 PCM (Pulse Code Modulation) 是通过等时间隔(即采样率时钟周期)采样将模拟信号数字化的方法。图11为4 bit 采样深度的PCM数据量化示意图。 图11. 4-bit PCM的采样量化 PCM数字音频接口,即说明接口上传输的音频数据通过PCM…

02 - DDMS

目录 一. DDMS 是什么&#xff1f; 二. 工作原理 三. ddmlib 1.ddmlib简介 总结 一. DDMS 是什么&#xff1f; DDMS 的全称是DalvikDebug Monitor Service&#xff0c;是 Android 开发环境中的Dalvik虚拟机调试监控服务。提供测试设备截屏、查看特定进程正在运行的线程以及堆信…

LabVIEW将现有数据文件映射至TDMS数据文件格式

LabVIEW将现有数据文件映射至TDMS数据文件格式 在某些情况下&#xff0c;可能无法使用TDMS文件格式&#xff0c;例如客户或供应商指定必须使用某种格式存储数据。有些传统仪器可能会自动使用某种自定义格式提供数据输出文件。此外&#xff0c;已经用某种方式收集的传统测量数据…

Matlab打开LabVIEW的tdm/tdms文件

1. 下去NI官网下载 MATLAB TDM Example文件 。 网址&#xff1a;Reading TDM/TDMS Files with The MathWorks, Inc. MATLAB Software - NI Community 这里我两个文件都下载了&#xff0c;但是只打开了2020那个&#xff0c;能用我就没看sp2010那个是干嘛的。 2. 使用Matlab打…

Labview-关于TDMS文件逻辑的学习-从今天开始学习Labview

1. TDMS文件的逻辑格式 TDMS文件的逻辑格式遵循TDM三层结构&#xff0c;仍然是文件、通道组、通道三层。用户在使用时只需要关心这三层就行了。2. TDMS文件API TDMS文件格式基本上可以称为NI用在测试测量领域的通用数据文件格式&#xff0c;LabVIEW, CVI/LabWindows, Signal Ex…

[Matlab科学计算] Matlab打开Labview保存的TDMS文件

1. TDMS文件简单介绍 TDMS文件格式由三个层次结构级别组成&#xff1a;文件、组、通道。文件级别可包含任意数量的组&#xff0c;而每个组又可包含任意数量的通道。通过通道分组&#xff0c;用户可以选择如何组织数据以使其更易于理解。每​个​TDMS​文件​都​包含​两​种​…

JAVA解析TDMS文件

2023年更新&#xff1a; 没想到还有人关注&#xff0c;上传了最新代码 https://github.com/yc97/TDMSDecoder 该代码经过测试&#xff0c;基本没什么bug了 reference: http://www.eefocus.com/Junking/blog/12-07/281264_7bf69.html http://www.ni.com/white-paper/14252/zh…

LabVIEW写入可快速加载的TDMS文件

LabVIEW写入可快速加载的TDMS文件 TDMS文件格式的设计目的是在尽可能快地读写数据的同时仍保持足够的灵活性来适应采集过程中通道数量和采样率的变化。 但是数据读写速度快的文件未必可快速加载。 TDMS文件是一个完全的二进制文件&#xff0c;由多个部分数据段组成&#xff0c;…

LabVIEW TDMS连续写入内存增长

LabVIEW TDMS连续写入内存增长 每次执行TDMS写入VI时&#xff0c;内存&#xff08;RAM&#xff09;使用量都会略有增加。这是内存泄漏吗&#xff0c;如何防止内存使用量增加&#xff1f; 解答 此问题有几种可能的解决方案&#xff1a; TDMS文件的引用可能没有适当地关闭。对…

Matlab查看tdms文件

由于最近项目需要使用Labview开发解调设备&#xff0c;对于高速采集卡就需要使用tdms存储数据&#xff08;存储的数据量较大&#xff09;&#xff0c;而用matlab无法对tdms格式文件进行直接读取&#xff0c;所以查找一些相关博客&#xff0c;解决了读取的问题。&#xff08;以下…

Labview数据存储与读取——TDMS文件的创建与写入

Labview数据存储与读取——TDMS文件的创建与写入 你好&#xff0c;这是我在自学Labview编写软件过程中使用的一些功能。我在存储采集卡数据时&#xff0c;通过阅读大量他人的程序&#xff0c;发现TDM及TDMS文件十分适合波形数据的记录&#xff0c;TDMS文件比TDM文件在存储动态…

TDMS转EXCEL

NI官方有推出TDMS转EXCEL插件&#xff0c;安装后可直接用excel打开tdms文件。 下载链接&#xff1a;https://download.csdn.net/download/Kleds_Love/81168914 下载为iSO文件&#xff0c;右键→装载→管理员身份安装即可 安装完成后&#xff0c;直接双击tdms文件&#xff0c;…

计算TDMS文件的THD

1.用采集卡采集一路正弦信号&#xff0c;存为.tdms文件 2.将.tdms文件转成.csv文件或.txt文件或.xlsx文件&#xff0c;使MATLAB可以将数据导入工作空间 法1&#xff1a;将.tdms文件转成.csv文件&#xff08;依靠LabVIEW程序&#xff09; 法2&#xff1a;将.tdms文件转成.txt文件…