球谐光照学习笔记

学习记录  以前遇到球谐,就只知道unity中可以直接用SH9函数获取结果,为什么要用这个来计算间接漫反射,为什么是3阶球谐。这些疑问学习后才逐渐了解。其数学推导的过程可能实际应用中不太会涉及,但是了解原理和过程还是挺值得学习的

 

跟着这位老师的思路学习的

球谐光照——辐照度照明 - 知乎

球谐函数是拉普拉斯方程分离径向后,角度部分通解的正交项

那么就需要了解球坐标系下的拉普拉斯方程分离变数的过程,将角度部分分离

 通过俩步分离变数 得到3个耦合的常微分方程

 

 

 用表示连带勒让德函数,所以之前球谐函数通解的复数形式就可以表示为

 

 前几次的球谐函数可以计算求得

 

 任何一个球面函数,可以以球谐函数作为基底进行广义傅里叶展开,就可以理解为球谐函数作为基函数,求傅里叶系数的过程,生成球谐系数的过程称为投影,根据生成的球谐系数来表示球面函数的过程称为重建

进行广义傅里叶展开,我们要求的就是广义傅里叶系数

 

 

 根据BRDF的反射等式,可以知道

 

 

 

 

 上面的俩等式非常重要,我们计算出光照函数和传递函数的球谐系数,通过俩种系数的内积就可以计算环境贴图对模型的漫反射光的贡献。

首先看传递函数的球谐系数,计算过程略过 根据连带勒让德函数正交性和奇偶性计算

 

 

 再结合之前的最终光照计算公式

 可以得知传递函数的球谐系数随次数增加衰减的非常快,重建低频信息的时候不需要很高的次数,这就是目前游戏引擎主流的3次9个球谐系数的做法。

到之前为止主要是说明球谐函数的计算过程和为什么游戏一般采用三阶球谐,由于论文中都给出了前几阶的球谐系数,一般直接拿来用就行。下面主要涉及到应用层面的是光照函数部分的球谐系数计算

然后是光照函数的球谐系数计算,将之前的式子转化为求和的形式

 

 

 那么,现在前三次球谐函数已知,纹素信息已知,我们需要求的就是纹素的立体角和根据纹素坐标计算法线的信息了。

下面部分的计算,Git有大佬已经实现了,算法基本一致的

GitHub - pieroaccardi/Unity_SphericalHarmonics_Tools: Two tools for Unity to deal with spherical harmonics

 首先是立体角的计算

 

 

 

 

然后是纹素和法线的对应关系

Cubemap Texture - OpenGL Wiki

可以理解为一个边长为2的立方体,坐标原点位于中点,每个轴值(-1,1)。坐标系为左手坐标系,然后需要计算的是每一个面的纹素的uv坐标对应在原点坐标系下的值来表示法线方向。需要注意的是cube的每一个面的uv零点的值是位于左上角的,定义如此。

上图的表示感觉不直观,还是git这个的实现比较直观,根据纹素位置的uv计算出(-1,1)的轴向的值。

 至此,球谐函数,纹素立体角和法线对应关系都知道了,就可以计算出光照函数的球谐系数了,环境图的RGB每个通道单独计算。

 

 实际的应用是拿一张HDR的环境图,然后用球谐函数通过上诉计算求得光照函数的球谐系数,然后再在材质中通过这27个系数和传递函数的球谐系数就可以内积计算球谐漫反射部分的信息。

知道了传递函数和光照函数的球谐系数和球谐函数,就可以通过这些信息来重建辐照度信息了。

 设

上式转化为

根据之前的传递函数的球谐系数计算出

 最终的漫反射光照为:

材质中使用上述计算还原即可

效果如下

压缩gif有噪点。。实际是没问题的

 比如我想要在引擎中还原一下SP的效果,那光照信息就全部来自那张环境图。而在游戏引擎中,角色周围的环境光照肯定是和角色所在的区域相关的,用一张死的环境图就不行了。

所以游戏引擎中就提供了环境探针来存贮一个区域内的环境信息,如unity的lightprobe每一个小球都记录了周围的环境信息,物体在多个ilghtprobe间移动的时候,球谐系数会在角色周围的四个lightprobe插值计算。插值计算相关这里有提到:

Light Probes 基本理论介绍_哔哩哔哩_bilibili

所以对于游戏的美术制作流程来说,想要引擎内效果和SP一模一样的话,那可能要考虑的就是角色在环境中的间接光照始终来源于一张固定的环境图,也有项目是这样做的。但是肯定还是需要Lightprobe这样根据游戏中的环境搭建的信息更好,这样像TOD之类的效果也可以通过多套球谐烘焙插值来实现。

除开间接光漫反射的球谐这部分,间接光的镜面反射部分也有很大一块内容值得学习,这里就不提及了。下图是保证引擎和SP效果基本对齐,用一张环境图来提供IBL信息的自定义PBR材质效果,左边UE,右边SP。

参考资料:

数学物理方法 5-1.1 球坐标系下拉普拉斯方程的分离变数_哔哩哔哩_bilibili

球谐光照——辐照度照明 - 知乎

https://cseweb.ucsd.edu/~ravir/papers/invlamb/josa.pdf

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在引擎中,我们使用了tools/sample.sh生成SAMPLE_NUM=1000000个采样点,采样点使用正太分布的随机数,DEGREE=3四阶(m = DEGREE 1)的球谐面来生成对应球谐基的因子。我们分别使用c和python两种语言来实现生成球谐因子的工具。 利用球谐函数就可以很好的解决这个问题,球谐函数的主要作用就是用简单的系数表示复杂的面函数。球谐光照实际上就是将周围的环境光采样成几个系数,然后渲染的时候用这几个系数来对光照进行还原,这种过程可以看做是对周围环境光的简化,从而简化计算过程。 在学习资料中,有一些关于球谐拟合的Python代码可以参考。这些资料包括《球谐函数及其作图 - python》、《Spherical Harmonic Lighting Program》、《Precomputed Radiance Transfer: Theory and Practice》、《Spherical Harmonics Lighting》、《Generating uniformly distributed numbers on a sphere》、《Analytic Spherical Harmonic Coefficients for Polygonal Area Lights》、《Unity Shader——球谐光照》和《unity SphericalHarmonicsL2》等。可以通过研究这些资料来了解如何在Python中进行球谐拟合。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【理论】球谐光照](https://blog.csdn.net/a1047120490/article/details/106325157)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值