![7c00ef830a57ba20a334597f1da5b44d.png](https://i-blog.csdnimg.cn/blog_migrate/ccff581f0249129cff1afec45c06966f.jpeg)
因为一直以来对BRDF的了解仅仅是大概知道
导致很多细节的控制力有限
所以干脆抽一个周末,好好动手把直接光部分的算法都做一遍,加深理解
间接光的部分核心是球谐算法和IBL, 以后有机会在仔细搞一遍间接光的部分需要的算法
这篇文章因为太长,并且太琐碎写的我欲生欲死, 后面几度不想写了
所以如果有任何错误请告诉我, 我会及时跟进修改
老规矩 先放上效果图:
![f34aeaf483f58bf0929f5866ce347338.png](https://i-blog.csdnimg.cn/blog_migrate/f121009238103275995abb09dd0ae3b2.jpeg)
GIT地址:
https://github.com/lingzerg/LingzergDemogithub.com概念 - PBR中的金属度, 粗糙度, 和 反射率-F0
PBR在实时渲染中一个比较典型的实现是基于Cook-Torrance BRDF,
光传输方程中的BRDF就是表达一束光照射在一个表面(微面元)上之后反射出去的比率
而微面元我觉得是体现在两个函数上: 法线分布函数 以及几何遮蔽函数
我们通过学习BRDF可以更加深入的理解PBR,对于工作中如何设计, 调整材质表现有很大帮助,
而在此之后, 还可以进一步学习实时渲染中其他不同的公式,例如BSSRDF
BRDF有三个参数构成了整个运算的基础
金属度, 粗糙度, 反射率-F0
我想尽量不要用代码和公式描述这三个东西,第一部分可以让美术看懂
第二部分, 在这个三个参数的描述之后, 我们可以讨论下BRDF
以及FDG的具体运算方式
并且在unity中以GGX那套公式为基础实现一套完整的直接光材质
至于微面元理论和辐射度量学可以单独再开一篇文章详细记录
金属度
金属度代表了有多少光子是直接被反射出去, 有多少光子被吸收后成了漫反射
金属度等于0的情况下, 光子会被完全吸收, 直接反射会变得非常弱, 只有漫反射
具体漫反射会有多弱? 我们会在F0的地方提到
金属度如果等于1的情况下, 所有的光子都会被反射出去, 会完全没有漫反射
并且当金属度等于1的情况下, base color就会成为反射率, 所以base color其实是不能乱设置的
我们常常可以看见一个表:
![cbf6a3b540cba03ba14d1b867e310d0f.png](https://i-blog.csdnimg.cn/blog_migrate/bb0c5e347575650d99f954ca46690e95.jpeg)
因为在高金属度的情况下F0和base color的这个关系, 所以高金属度的这个情况下,base color更加重要
那假如金属度等于0.5呢? 那么反射率就是 F0 和 Basecolor的平均值
同理, 你的反射率就由这三个东西决定
F0, baseColor , 而金属度决定更靠近那个值
![007844f96dd5d1d7a5c56bf2dee63e8c.png](https://i-blog.csdnimg.cn/blog_migrate/9983ee8de8ff74851e748b1519e21377.jpeg)
粗糙度
粗糙度代表表面的粗糙程度, 越粗糙的表面光的散射就会越厉害
![5dae0f2675dc6933048c8f8827b42a0a.png](https://i-blog.csdnimg.cn/blog_migrate/29bf8eea611df063320c3956455f43bd.jpeg)
还有一个额外的影响,就是越粗糙的表面可能会产生更多的遮蔽
所谓遮蔽是这个意思:
反射率-F0
F0就是反射率, 当我们90度直视一个表面的时候, 看到的光子回弹的比例
正如前面金属度提到的那样反射率基于F0和base color之间
所以base color设置多少就很重要了
在金属度等于1的情况,很容易分析, 漫反射等于0, 而F0就会等于base color
而在金属度等于0的情况下呢?
这时候F0就等于我们最开始设置的那个F0, 一般会设置为0.04, 甚至更高
大部分非金属的F0都很小, 例如0.04, 0.08
所以在UE中, 如果你给Specular设置成1, 那么F0的默认值就会是0.08
设置成0, 就是0,默认Specular应该是0.5, 也就是说F0等于0.04
![df119a5a10bd1ec03cd3bd4b0be1abd9.png](https://i-blog.csdnimg.cn/blog_migrate/dffc4cc1a34b944f15f63cd428719bb8.png)
unity中无法设置这个F0, 少了一个控制的维度, 可能需要我们手动添加, 后面我们会在代码中添加这个
PBR方程/BRDF函数
先看看光传输方程:
其实外面这个积分并不是BRDF的一部分
积分的意义在于计算这个角度上, 微面元反射出去全部的 irradiance, 毕竟还有环境光, 多光源
但是BRDF是定义给定入射方向上的辐射照度如何影响给定出射方向上的辐射率
说白了就是
有位大佬指点我, 说的很有道理
BRDF可以看成