UnityShader 初级篇(一)
Unity中的基础光照
这是我第一次学习Unity shader,先了解一下shader的基础光照。
环境光(ambient)
用于描述其他所有的间接光照
- 重点在描述间接光照,间接光照指光线在多个物体之间反射,最后进入相机
- 在标准光照模型中,使用一种环境光的部分来近似模拟间接光照,它通常是一个全局变量。所有物体都使用这个环境光
- Unity 中的环境光可在Windows->Lighting中找到,在shader中只需要通过Unity内置的UNITY_LIGHTMODEL_AMBIENT就可得到环境光的颜色和强度
自发光(emissive)
直接由光源发射进入摄像机,而不需要经过任何物体的反射
- 标准光照模型使用自发光来计算这个部分的贡献度
- 模拟自发光物体对周围物体的影响
- 大多数物体无自发光特性,因此多大部分的shader中都没有计算自发光部分,如果要计算自发光也非常简单,只需要在片元着色器输出最后的颜色之前,把材质的自发光颜色添加到输出颜色上即可
漫反射(diffuse)
漫反射光照是用于对那些被物体表面随机散射到各个方向的辐射度进行建模的,入射光线的角度很重要
- 漫反射光照符合兰伯特定律,反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。漫反射部分的计算,公式:
防止法线和光源方向点乘的结果为负值,使用最大值函数来将其截取到0.防止物体物体被后面来的光源照亮
这里选择世界坐标系下:
有个问题仍然存在。无法解决背光面明暗一样的缺点。为此,有一种改善技术这就是半兰伯特(Half Lambert)光照模型
广义的半兰伯特光照模型的公式如下:
半兰伯特光照模型没有使用max操作来防止n和I的点积为负值,而是对其结果进行了一次α倍的缩放再加上一个β大小的偏移。绝大多数情况下,α和β的值均为0.5,这样可把n和I的点积结果范围从[-1,1]映射到[0,1]范围内。对于模型的背光面,在原兰伯特光照模型中点积结果将映射到同一个值,即0值处;而在半兰伯特光照模型中,背光面也可以明暗变化。不同的点积结果会映射到不同的值上。
最终效果
高光反射(specular)
一种经验模型,不完全符合真实世界中的高光反射现象。可用于计算那些沿着完全镜面反射方向被反射的光线,可让物体看起来右光泽。
需要知道的信息较多,如表面法线、视角方向、光源方向、反射方向等。
重点在反射方向,可通过其他信息计算得到:
可以利用Phong模型来计算高光反射部分的:
CG提供了计算反射方向的函数reflect
Blinn-Phong 光照模型
与上述的Phong模型相比,Blinn提出了简单的修改方法来得到类似的结果。它的基本思想是,避免计算反射方向r,为此,Blinn模型引入一个新的矢量h,它通过对视角方向v和光照方向I相后再归一化得到的。即
Blinn模型计算高光反射的公式如下:
然后使用n和h之间的夹角计算,而非v和r之间的夹角