UnityShader入门精要第六章-基础光照模型原理总结
前言
开发中常常有一些画面表现上的需求,但苦于不会写Shader
,没办法实现,现在特地来学习相关原理知识。
UnityShader
入门精要的第六章前的内容已经很详尽了,在此不做记录。但第六章中的基础光照模型比较常见,这部分内容在GAMES101
中也有讲解,可见其重要性,在此记录一下。
标准光照模型(Blinn-Phong模型 )
最初的光照模型由Phong
提出,他把进入到摄像机的光照分为四个部分:自发光、高光反射、漫反射、环境光。
- 自发光:
emissive
,给定某个方向时,一个表面自身会向该方向散发多少辐射量。 - 漫反射:
diffuse
,光照某个表面时,该表面会向每个方向散发多少辐射量。 - 高光反射:
specular
,光照某个表面时,该表面会向完全镜面反射方向散发多少辐射量。 - 环境光:
ambient
,其他所有间接光照。
计算光照时,就由这四个部分做贡献,接下来介绍对应公式。
自发光
自发光计算最简单。它的贡献度(Cemissive
)就是该表面材质的自发光颜色(Memissive
)。
\[c_{emissive} = m_{emissive}
\]
漫反射
漫反射符合兰伯特定律。它的贡献度,即反射光线的强度(Cdiffuse
)与表面法线和光源方向之间夹角的余弦值成正比。
\[c_{diffuse} = (c_{light}·m_{diffuse})max(0, n·I)
\]
Clight
是光强,Mdiffuse
是该表面材质的漫反射颜色,n
是表面法线,I
是指向光源的单位矢量。这里对表面法线和指向光源的单位矢量点乘的结果做max
运算是为了将结果截取到0
,防止光源将物体的背后也照亮。
高光反射
这里的高光反射是一种经验模型,它并不完全符合现实世界的高光反射现象。
它的贡献度(Cspecular
)由四个参数计算得出,分别是入射光强(Clight
)、表面材质的高光反射系数(Mspecular
)、视角方向(v
)和反射方向(r
)。除此之外还可以加上材质的光泽度(Mgloss
)来控制高光区域的范围。
\[c_{specular} = (c_{light}·m_{specular})max(0, v·r)^{m_{gloss}}
\]
其中反射方向r
可以由表面法线(n
)和光照方向(I
)计算得出。
\[r = I - 2(n·I)n
\]
Blinn
对这里做了一些修改,他提出不再计算反射方向r
,而是改为:将视角方向v
和光照方向I
相加后做归一化,得到一个新矢量h
,然后使用h
和表面法线n
作点乘,以此替代Phonn
模型中的v·r
。
环境光
它的贡献度(Cambient
)一般为全局变量,由开发者自行设置。