Games202(P6、P7)环境光照与PRT全局光照

news2024/11/26 20:38:52

P6、实时环境光照 RealTime Environment Mapping

不同于全局光照

(1) IBL

我的Blog:

  • QT with OpenGL(IBL-漫反射辐照)
  • IBL-镜面反射(预滤波篇)
  • IBL-镜面反射(LUT篇)
  • QT with OpenGL(IBL-镜面反射)

(2) Spherical Harmonics 球面谐波

我的Blog:

  • 球谐函数原理
  • 球谐函数在环境光照中的使用原理
  • 球谐函数实现环境光照漫反射实践

(3)Precomputed Radiance Transfer(PRT)【2002】

球谐函数近似环境光漫反射的问题:

  • 没有几何遮挡关系,没有阴影。
  • 只能处理Diffuse的物体

如何解决??引入了PRT。

在这里插入图片描述
PRT将Lighting部分拆成球面谐波基函数
L ( i ) ≈ ∑ l i B i ( i ) L(i)\approx \sum l_iB_i(i) L(i)liBi(i)

light transport部分进行预计算,出射方向已知的情况下,light transport也可以展开维一个球面谐波函数。
V ( i ) ρ ( i , o ) m a x ( 0 , n ⋅ i ) ≈ ∑ t i B i ( i ) V(i)\rho(i,o)max(0,n\cdot i)\approx \sum t_iB_i(i) V(i)ρ(i,o)max(0,ni)tiBi(i)

疑问:light transport与o(出射方向)无关,是不是代表着摄像机不可以转动?

  • 并不是,因为物体只有漫反射,而漫反射向球面各个方向散射的光照是相同的,也就是说,同一个着色点在各个方向上看过去的颜色是相同的。故摄像机转动也不影响计算的结果!!!

疑问:那什么是不可以动的?

  • light transport部分中包含了 V ( i ) V(i) V(i)项(可见性),也就是说一个着色点从四面八方是否被遮挡的条件是预计算好的。这标志这场景中进行预计算的物体,不可以再移动!

疑问:如果不变换环境光,是不是可以将 light transport 项和 lighting 项直接计算好值保存在着色点。这不就是给每个着色点预计算了所有的光照颜色吗?

  • 额!我觉得确实是这样!!!不如离线渲染预计算~~

如果材质为Diffuse物体,即BRDF为常数

如果BRDF为常量,PRT可近似为如下函数,我们将光照Visibility拆成两个积分分别计算(注意:这里并不是数学上严谨的,而是一种近似)
在这里插入图片描述
得到结果:
L ( o ) ≈ ρ ∑ l i ∫ Ω B i ( i ) V ( i ) m a x ( 0 , n ⋅ i ) d i L(o)\approx \rho \sum l_i \int_{\Omega} B_{i}(i)V(i)max(0,n\cdot i)di L(o)ρliΩBi(i)V(i)max(0,ni)di
这里将光照的球谐函数留在了Visibility项中
∫ Ω B i ( i ) V ( i ) m a x ( 0 , n ⋅ i ) d i \int_{\Omega}B_{i}(i)V(i)max(0,n\cdot i)di ΩBi(i)V(i)max(0,ni)di
这里Light Transport项乘以一个基函数的积分,就是Light Transport的函数投影到基函数上的系数,这个系数可以预计算。
而预计算的结果就是Basic Function给数量的数字。即: ∫ Ω B i ( i ) V ( i ) m a x ( 0 , n ⋅ i ) d i \int_{\Omega}B_{i}(i)V(i)max(0,n\cdot i)di ΩBi(i)V(i)max(0,ni)di为一个预计算的常数

优点:光源可以切换,只要光源被预计算过
问题:场景中所有预计算过的东西都不能动

Light Transport的预计算

使用球谐函数展开一个点特定视口下的可见性函数
在这里插入图片描述

注意:这里是每一个 Shadering Point,也就是说,对于每一个着色顶点都要记录一串球谐函数展开的可见性系数(一般存储25个数,也就是5阶;更高的阴影精度需要存储更高阶的系数)

PRT既可以解决阴影问题,还可以解决Glossy的BRDF的问题。

渲染结果

将大量的渲染时间放在渲染之前,在渲染时只需要获取数据进行简单计算就好。该算法在2002年那个年代,就可以做到100帧的运行速率,可以说速度是非常快的。
在这里插入图片描述

如果材质为Glossy(有光泽的)物体,BRDF不为常数

Diffuse材质中提到,Light Transport项与出射方向无关,故是一个二维函数。
Glossy物体BRDF不仅仅与入射角度有关,还与出射角度有关。也就是说它是一个4维的函数。
在这里插入图片描述
这里的i被预计算了,计算结果为 l i l_i li T i ( o ) T_i(o) Ti(o)为预计算的与o有关的函数
然后我们将计算得到的 T i ( o ) T_i(o) Ti(o) 投影到关于 o o o 的球谐函数上。
在这里插入图片描述
最终我们可以得到一个球谐函数的系数矩阵!!!
在这里插入图片描述
计算出射光照公式变为
在这里插入图片描述
L L L提出来得到
∑ i ( ∑ j t i j B j ( o ) ) L i \sum_i \left( \sum_j t_{ij}B_j(o) \right)L_i i(jtijBj(o))Li

我们已知,再Diffuse下,一个着色点保存了可见性函数的球谐函数系数
而在Glossy下,一个着色点保存了与o有关的系数计算矩阵。
入射光照球谐系数BRDF可见性矩阵相乘得到的向量 ∑ l i t i j \sum l_it_{ij} litij,即为关于 o o o 的球谐函数的系数列表。
在这里插入图片描述
再将该系数与关于 o o o的基函数相乘求和,得到以o为出射角度的环境光镜面反射!
如果环境光照不变,我们可以将 light 项和 transport matrix项 直接计算好,得到一个关于o的基函数系数!

一般情况下,人们会使用3/4/5阶球谐基函数去近似。因此一个像素点需要存储 81/256/625 个系数

渲染结果

5万网格数,在2.2GHZ P4,ATI Radeon 8500上有3.6fps。
在现代GPU上,运行到100帧以上是没有问题的。
当金属度很高,反射接近于镜面时,PRT便解决不了这个问题了。
在这里插入图片描述

但到此为止,做的也仅仅是环境光照,直接光照的一种形式,而并不是有间接光照的全局光照

PRT引入全局光照

在这里插入图片描述
经过了第一次的预计算,现在每一个着色点都记录了BRDF&visibility项在球谐函数下的展开系数,我们可以通过将着色点这些着色点作为次级光源再次预计算。
若我们将直接光照的计算表示为 L 1 L_1 L1
L 1 ( x , ω ⃗ o ) = L e ( x , ω ⃗ o ) + ∫ Ω L ( x ′ , ω ⃗ i ) ρ ( x , ω ⃗ i , ω ⃗ o ) V ( x , x ′ ) G ( x , x ′ ) d ω ⃗ i L_1\left(x, \vec{\omega}_{o}\right)=L_{e}\left(x, \vec{\omega}_{o}\right)+\int_{\Omega} L\left(x^{\prime}, \vec{\omega}_{i}\right) \rho\left(x, \vec{\omega}_{i}, \vec{\omega}_{o}\right) V\left(x, x^{\prime}\right) G\left(x, x^{\prime}\right) d \vec{\omega}_{i} L1(x,ω o)=Le(x,ω o)+ΩL(x,ω i)ρ(x,ω i,ω o)V(x,x)G(x,x)dω i
那么光线弹射一次得到的次级光照 L 2 L_2 L2计算即为
L 2 ( x , ω ⃗ o ) = ∫ Ω L 1 ( x ′ , ω ⃗ i ) ρ ( x , ω ⃗ i , ω ⃗ o ) ( 1 − V ( x , x ′ ) ) G ( x , x ′ ) d ω ⃗ i L_2\left(x, \vec{\omega}_{o}\right)=\int_{\Omega} L_1\left(x^{\prime}, \vec{\omega}_{i}\right) \rho\left(x, \vec{\omega}_{i}, \vec{\omega}_{o}\right) (1-V\left(x, x^{\prime}\right) )G\left(x, x^{\prime}\right) d \vec{\omega}_{i} L2(x,ω o)=ΩL1(x,ω i)ρ(x,ω i,ω o)(1V(x,x))G(x,x)dω i
而次级光照中,被照射的点为变为单个着色点,光源变为着色点周围可能会弹射直接光照的片元。

注意这里的差别:
L 2 L_2 L2中的visibility项变为了 1 − V ( x , x ′ ) 1-V(x,x') 1V(x,x)
这是因为次级光源正是来自那些被遮挡的部分。

次级光照计算的步骤

  1. 对于每个模型表面的着色点 x x x,计算他的直接光照(direct lighting)的传输函数 L 1 L_1 L1
  2. 从当前点 x x x 再发射多条射线,如果射线hit到其他三角形。
  3. 对于这个hit到的点,用三角形的重心坐标(barycentric coordinate)来对三角形每个顶点的transfer function的SH系数进行双线性插值求出hit点的transfer function的SH系数向量。
    • 如果该点为Diffuse物体:则该系数为一个向量,可以直接得到SH系数向量
    • 如果该点为Glossy物体:则该系数为一个矩阵,我们已知出射方向 o o o为该点指向渲染点的向量,故可以计算得到反射方向为 o o o的SH系数向量。
  4. 将得到的SH系数向量累加到着色点(次级光源照射点)
    • 若着色点为Diffuse物体,则直接将两个球谐函数系数向量相加。
    • 若着色点为Glossy物体,Glossy着色点存储了一个矩阵,因此我们需要将该球谐函数的向量与着色点的矩阵结合在一起,公式为【公式为自己推导,如果有错误,请指出纠正】
      ∑ i [ ( ∑ j t i j B j ( o ) ) + t i 次 ] L i \sum_i \left[\left( \sum_j t_{ij}B_j(o) \right) + t_{i次} \right]L_i i[(jtijBj(o))+ti]Li

      t i 次 = ∑ j t i j 次 B j ( o ) t_{i次} = \sum_j t_{ij次}B_j(o) ti=jtijBj(o)
      这样我们就可以直接计算两个矩阵的和了
      ⇒ t i j 次 = ∫ t i 次 B j ( o ) = t i 次 ∫ o 在全部反射方向积分 B j ( o ) d ( o ) \Rightarrow t_{ij次} = \int t_{i次}B_j(o) \\ = t_{i次}\int_{o在全部反射方向积分}B_j(o) d(o) tij=tiBj(o)=tio在全部反射方向积分Bj(o)d(o)
      我们通过如下图可看到, B j B_j Bj 已知,对 B j ( o ) B_j(o) Bj(o) 球面积分。
      在这里插入图片描述
      结果是,只有第1项和第7项有值,且结果为一个常数,用 B B B表示。因此可以化简为
      ⇒ t i j 次 = t i 次 ∫ ( B 1 ( o ) + B 7 ( o ) ) d ( o ) = t i 次 B \Rightarrow t_{ij次} = t_{i次}\int (B_1(o)+B_7(o)) d(o) = t_{i次}B tij=ti(B1(o)+B7(o))d(o)=tiB
      综上得出:若着色点为Glossy物体,Glossy着色点存储的矩阵变化为
      ⇒ t i j 次 + = t i 次 B \Rightarrow t_{ij次} += t_{i次}B tij+=tiB
      而这个B可近似为1。

本块内容参照了PRT完整讲解 https://zhuanlan.zhihu.com/p/609597945
并在其基础上 增加了 对于 Glossy物体间接光反射 计算!

PRT的问题

  • 场景中物体位置固定
  • 物体的材质固定
  • 需要大量的预计算
  • 需要存储大量的数据

一些解决方法

  • 使用其他的基函数(小波函数等)
  • 将BRDF也单独求球谐函数,将方程变成三个基函数求和积分
  • 不预计算,使用解析解解出来【在近10年内替代了PRT】

P7、全局光照

小波 Wavelet

将任意一个二维函数投影到小波对应的基函数上,可以发现大量的基函数的系数接近0.

这样我们就可以选取基函数中系数最大的多少个,做到有损压缩。

与SH(Spherical Harmonics )最大的区别是小波支持全频率的表示,既可以表示低频,也可以表示高频。

小波变换,对CubeMap中的每一个图单独做变换,将高频的信息留在周围三个区块,低频的东西留在左上图中。
在这里插入图片描述
然后对左上的图继续做小波变换,将高频取出,低频留在左上
在这里插入图片描述

SH与小波的区别

相同的存储量,小波可以得到更好的高频信息。
代价:小波不支持快速的旋转,不可以旋转光照。
在这里插入图片描述

RealTime Global Illumination(In 3D)实时全局光照(GI)

在实时全局光照中,一般指光线弹射两次的光照,即直接光照和一次的间接光照。
在这里插入图片描述

Reflective Shadow Maps(RSM)

一切被直接光照照到的物体,会作为次级光源。

问题1:哪些面片被直接照亮

使用ShadowMap就可以知道哪些面片被直接照亮

问题2:各个面片对P点的贡献分别是多少。

在这里插入图片描述
对渲染方程代入如上计算,得到如下结果
在这里插入图片描述
在上式中, L i ( q → p ) L_i(q\rightarrow p) Li(qp)可优化为如下函数
因为:
f r = ρ / π , ρ 为反射率 L i = f r ⋅ ϕ d A , ϕ 是直接光照的光强 f_r = \rho / \pi,\rho 为反射率\\ \quad\\ L_i = f_r \cdot \frac{\phi}{dA},\phi 是直接光照的光强 fr=ρ/πρ为反射率Li=frdAϕϕ是直接光照的光强
因此有次级光源光强
E p ( x , n ) = ϕ p m a x { 0 , d o t ( n p , ( x − x p ) } m a x { 0 , d o t ( n , x p − x ) } ∣ ∣ x − x p ∣ ∣ 2 E_p(x,n)=\phi_p \frac{max\{0,dot(n_p,(x-x_p)\}max\{0,dot(n,x_p-x)\}}{||x-x_p||^2} Ep(x,n)=ϕp∣∣xxp2max{0,dot(np,(xxp)}max{0,dot(n,xpx)}

L 0 = E p ( x , n ) ∗ f r ( p , p → q , w o ) L_0 = E_p(x,n) * f_r(p,p\rightarrow q,w_o) L0=Ep(x,n)fr(p,pq,wo)

其他近似

  1. 不考虑Visbility项,认为次级光源不会被遮挡。
  2. 不对所有次级光源采样,只对该点在ShadowMap中周围的部分像素采样。

ShadowMap记录值

  1. 深度
  2. 世界坐标
  3. 法线
  4. 次级光源强度 ϕ \phi ϕ

特点与效果

对于特定情况效果比较好,如手电筒(用RSM做手电筒!!!?)
好处:非常好写,第一个Path生成RSM,第二个path用眼睛看向场景。
问题:

  1. 直接光源较多时,间接光源也会成倍增多
  2. 不会计算反射光的可见性检查
  3. 次级光源效果和运行速度,会根据采样率的不同的不同

如何实现

第一步,先找到哪些物体表面能够被直接照亮,使用ShadowMap,认为每一个ShadowMap的像素就是一个次级光源。
第二步,次级光源如何贡献到点P:我们认为所有的反射物(次级光源),都是Diffuse的

RSM

与离线渲染中的VPL方式是比较相似的,RSM是硬件加速版本的VPL(Virtual Point Light 虚拟点光源)。

Light Propagation Volumes(LPV)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/993050.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React refers to UMD global, but the current file is a module vite初始化react项目

vite搭建react项目 初始化项目 npm create vite 在执行完上面的命令后,npm 首先会自动下载create-vite这个第三方包,然后执行这个包中的项目初始化逻辑。输入项目名称之后按下回车,此时需要选择构建的前端框架: ✔ Project na…

机器人连续位姿同步插值轨迹规划—对数四元数、b样条曲线、c2连续位姿同步规划

简介:Smooth orientation planning is benefificial for the working performance and service life of industrial robots, keeping robots from violent impacts and shocks caused by discontinuous orientation planning. Nevertheless, the popular used quate…

Python对象序列化

迷途小书童的 Note 读完需要 7分钟 速读仅需 3 分钟 大家好,我是迷途小书童! 在 Python 开发中,我们经常需要将对象数据保存到磁盘,或者通过网络传输对象信息。这时就需要序列化,Pickle 库为我们提供了极为方便的对象序…

Python基础篇(18):模块与包

一、as 关键字的使用 1、as 关键字的作用:给导入的模块取别名 import 测试1 as Test_1 import 测试2 as Test_2Test_1.say_hello() Test_2.say_hello() 二、if __name__ __main__ 1、作用 测试当前模块所编写的代码块,根据业务自主选择需要运行的代…

433MHz芯片在遥控应用市场中的优点

当涉及到简单的无线射频通信,433MHz芯片成为一种经济实惠且广泛应用的选择。以下是关于433MHz芯片的重点信息: 工作原理:433MHz芯片的工作原理是将数字信号转化为射频信号,并通过无线信道进行传输。在接收端,射频信号再…

关于Windows11系统,使用适用于Android的windows子系统 ,安装应用后无法连接网络的问题

–by 旧人旧梦旧时光 最近在使用win11自带的android模拟器时遇到了应用无法连接网络的问题,现在得到了解决,记录一下。 经过思考,发现是由于之前无意打开了这个选项,导致的应用无法连接网络,因此,把该选项…

Topaz Photo AI for Mac(AI人工智能降噪放大软件)

Topaz Photo AI是一款专业的照片处理软件,它利用深度学习和人工智能技术,提供了强大的图像增强和修复功能。无论你是想改善照片的质量,还是想给照片添加特效和艺术效果,Topaz Photo AI都能帮助你实现。 Topaz Photo AI还具备强大…

【uni-app】—3.新建一个uni-app项目

一、新建uni-app项目 1. 打开HBuilder X 2. 新建项目 3. 配置项目信息 4. 安装Sass 插件 (因为项目需要) 这里需要登录,自行用邮箱注册登录,再下载安装插件,安装完成如下 二、项目目录扩展 1. 初始化项目目录 2. 扩…

Grafana 图表配置快速入门

Grafana图表配置 文章目录 Grafana图表配置panel图表配置预览区数据设置区查询设置区转换设置区告警设置区 图表设置区Setting设置Visualization 可视化Display 显示Axes 轴legend 图例Thresholds 阈值 参考 panel图表配置 预览区:用来预览设置的图表。数据设置区&…

【数据分析入门】【淘宝电商API接入与电商数据分析】初识Web API(一)

今天开始我们将学习如何使用Web应用变成借口(API)自动请求网站到特定信息而不是整个网站,再对这些信息进行可视化。由于这样编写到程序始终使用最新到数据来生成可视化,因此即便数据瞬息万变,它呈现到信息也都是最新的。比如,我们…

算法训练营day48|动态规划 part09:打家劫舍(LeetCode 198.打家劫舍、213.打家劫舍II、337.打家劫舍 III)

文章目录 198.打家劫舍思路分析代码实现思考总结 213.打家劫舍II思路分析代码实现 337.打家劫舍 III思路分析代码实现思考总结 198.打家劫舍 题目链接🔥🔥 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响…

NSQ和KAFKA的使用入门

【nsq vs kafka】https://zhuanlan.zhihu.com/p/46421050 【kafka】https://juejin.cn/post/6844903495670169607 NSQ 分布式内存消息队列 优势: NSQ提倡分布式和分散的拓扑,没有单点故障,支持容错和高可用性,提供可高的消息交…

如何理解Java中的自动拆箱和自动装箱?

个人主页:金鳞踏雨 个人简介:大家好,我是金鳞,一个初出茅庐的Java小白 目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作 我的博客&am…

亚运会:举办次数最多的是泰国,观众满意度衡量赛事成功情况

本文由群狼调研(长沙第三方评估)整理出品,欢迎转载,请注明出处。8日起至9月20日,杭州第19届亚运会火炬传递启动,杭州亚运会是放开后的首个盛会,亚洲的健儿齐集于此,同场竞技&#xf…

【C++入门】C语言的不足之处

概要 C入门主要讲的是C语言的一些不足,C作为补充,来补充C的不足之处 C的关键字有63个,C语言有32个(作为了解,不需要专门记) 变量的命名规则: 变量名必须以字母或下划线开头。变量名只能包含字…

httprunner环境变量

前言 我的上一篇文章讲了httprunner的基本介绍,这篇文章呢主要来给大家介绍httprunner中的环境变量。 一般来说,在进行实际应用的开发过程中,应用会拥有不同的运行环境,通常会有以下环境: 本地开发环境测试环境生产…

Flask狼书笔记 | 07_留言板

文章目录 7 留言板7.1 使用包组织代码7.2 Web开发流程7.3 使用Bootstrap-Flask7.4 Flask-Moment本地化日期和时间7.5 使用Faker生成虚拟数据7.6 Flask_DebugToolbar调试程序7.7 Flask配置的两种组织形式小结 7 留言板 这是一个简单的程序,涉及到的大部分是之前所学…

windows弹出交互式服务检测一键取消bat脚本

现象 脚本命令 新建一个bat文件,将下面的脚本拷贝进去,保存,双击即可 禁用服务:重启电脑的时候不会启动 停止服务:立即停止服务,马上生效的 sc config UI0Detect start disabled net stop UI0Detect

AQS同步队列和等待队列的同步机制

理解AQS必须要理解同步队列和等待队列之间的同步机制,简单来说流程是: 获取锁失败的线程进入同步队列,成功的占用锁,占锁线程调用await方法进入条件等待队列,其他占锁线程调用signal方法,条件等待队列线程进…

攻防世界题目练习——Crypto密码难度1(一)

题目目录 1. base642. Caesar3. Morse4. Broadcast5. hidden key6. [简单] 初识RSA7. 简单的LFSR8. baigeiRSA 1. base64 下载文件,打开是一个txt文件,解密工具base64解码,如图: 2. Caesar 打开文件看到字符如下: …