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