今天把PBR和各种相关的光照总结一下吧,后续还会有补充
https://www.unrealengine.com/zh-CN/blog/gdcc2015-pbr
https://blog.csdn.net/poem_qianmo/article/details/88936992
https://zhuanlan.zhihu.com/p/33464301
https://zhuanlan.zhihu.com/p/49736244
https://en.wikipedia.org/wiki/Bidirectional_reflectance_distribution_function
https://github.com/wdas/brdf/downloads // 迪士尼 brdf官方demo
https://blog.csdn.net/poem_qianmo/article/details/100652463 // 几何遮蔽
https://learnopengl-cn.github.io/07%20PBR/01%20Theory/ // PBR opengl
https://learnopengl-cn.github.io/07%20PBR/01%20Theory/#_2 // learn OpenGL
尽量看官方源码,否则会有很多很多坑
PBR(Physicallly-Based-Rendering)
PBR就是BRDF + IBL
字面意思翻译就是 ,基于物理的渲染。这样的渲染更加真实,更加写实。
- 直接光源(Direct Light): 能直接发光的物体(太阳,灯,蜡烛…)
- 间接光源(InDirect Light): 仅仅反弹其他物体的光源(天光,照在物体上互相弹射的光)
-
金属: 可以反射70%-90%的入射光线。不同金属吸收不同波长的光线,导致返回的光线带有颜色
-
非金属: 可以反射4%的入射光线, 其余(折射, 吸收,漫反射),暗的吸收多,亮的吸收少
-
漫反射: 反射光线方向随机。
-
镜面反射: 反射光线方向为一个方向。
-
微表面理论: 有些被挡住产生阴影,视觉上会产生模糊的反射
双向反射分布函数BRDF
描述了入射光线经过某个表面反射后在出射方向的分布(因为眼从不同角度看,亮度是不同的。)
f
=
d
L
r
(
w
r
)
d
E
i
(
w
i
)
f = \cfrac{dL_r(w_r)}{dE_i(w_i)}
f=dEi(wi)dLr(wr)
L是辐亮度。E是辐照度,r是反射光,i是入射光
- 然后迪士尼原则的BRDF
f
(
l
,
v
)
=
d
i
f
f
u
s
e
+
D
(
θ
h
)
F
(
θ
d
)
G
(
θ
l
,
θ
v
)
4
c
o
s
θ
l
c
o
s
θ
v
f(l,v) = diffuse + \cfrac{D(\theta_h)F(\theta_d)G(\theta_l,\theta_v)}{4cos\theta_lcos\theta_v}
f(l,v)=diffuse+4cosθlcosθvD(θh)F(θd)G(θl,θv)
- D是微表面分布函数,主要负责反射specular peak 的形状 (法线分布)
- F为菲涅尔反射系数
- G为几何遮蔽
关于G项 也叫 V项
可以用一张图来说明
Unity是这样的效果,左图有几何遮蔽 + F + D,右图是只有 F 和 D项
虽然区别很微妙,但是左图更加真实
我们可以看到在smooth很小的情况下(也就是很粗糙的情况),微表面是被很多突起遮挡的,所以不会这么亮。
而右边的结果就不对了(对比来说)
代码在我的另一篇里
Lambert模型
I D = L ⋅ N = ∣ L ∣ ∣ N ∣ c o s θ = c o s θ I_D = L \cdot N = |L| |N|cos\theta = cos\theta ID=L⋅N=∣L∣∣N∣cosθ=cosθ
phong式光照
I
p
=
A
m
b
i
e
n
t
+
D
i
f
f
u
s
e
+
S
p
e
c
u
l
a
r
I_p = Ambient + Diffuse + Specular
Ip=Ambient+Diffuse+Specular
I
p
=
C
o
l
o
r
r
g
b
+
L
∗
N
+
(
R
∗
V
)
α
∗
i
I_p = Color_{rgb}+ L*N+ (R * V)^{\alpha}*i
Ip=Colorrgb+L∗N+(R∗V)α∗i
i是强度,a控制高光大小
bilin-phong式光照
相当于对phong式光照 的一个优化
I
p
=
C
o
l
o
r
r
g
b
+
L
∗
N
+
(
N
∗
H
)
α
∗
i
I_p = Color_{rgb}+ L*N+ (N * H)^{\alpha}*i
Ip=Colorrgb+L∗N+(N∗H)α∗i
fixed3 specular1 = _LightSpecColor.rgb * pow(max(0, dot(worldNormal, worldHalfDir)), _Shininess1 * 20) * _SpecIntensity1
halflambert
金属度和粗糙度
https://docs.blender.org/manual/en/latest/render/shader_nodes/shader/principled.html
https://blender.stackexchange.com/questions/229787/metallic-vs-specular
- 金属工作流 不能控制反光的颜色,但是比specular工作流更加物理真实和更省贴图空间
- 光泽度工作流可以控制反光的颜色,但是不那么物理真实,可以修改反光颜色,但是给艺术家更多的发挥空间
- 光泽度工作流的的算法,更像是diffuse + specular, 而金属度的反光是受diffuse影响的。
关于光照模型
PBR角色渲染多看看虚幻 Engine/shader下的shader,源码都有,或许能解决不少问题
UE4已经有很多成熟方案了,直接抄作业啊,当然也要蜂聚情况来看
如:\Engine\Shaders\Private\ShadingModels.ush
还有好多好东西都可以在这里找到