1.什么是光照模型
光照模型(illumination model),也称为明暗模型,用于计算物体某点处的光强(颜色值),从算法理论基础而言,光照模型分为两类,一种是基于物理理论的,另一种是基于经验模型的。
基于物理理论的光照模型:偏重于使用物理的度量和统计方法,效果非常真实,但是计算复杂,实现起来也较为困难;
经验模型:是对光照的一种模拟,通过实践总结出简化的方法,简化了真实的光照计算,并且能达到很不错的效果
1.1为什么需要光照模型
现实世界的光照是极其复杂的,而且会受到诸多因素的影响,有限的计算能力无法完全模拟。
使用简化的光照模型对现实的情况进行近似,使得计算处理起来会更容易,并且令效果更符合需
这些光照模型就是基于我们对光的物理特性的理解。
2.局部光照模型
2.1局部光照模型的定义
局部光照模型只关心直接光照部分,即直接从光源发出并照射到物体表面并反射至摄像头的光线,对应下面左图的情况,右边的这种一束光线会经过多次反射才会反射到视线中的叫做全局光照
2.2局部光照模型的组成
局部光照模型满足叠加原理,可以基本将光线分为四个部分,漫反射,高光反射,环境光,自发光
2.3漫反射
什么是漫反射?
在光照模型的定义中,当光线从光源照射到模型表面时,光线均匀被反射到各个方向,这种现象就是漫反射。在漫反射的过程中,光线发生了发生了吸收和散射,而因此改变颜色和方向。
如何计算?
漫反射光照符合Lambert定律,反射光强与法线和光源方向之间的夹角的余弦值成正比
2.4高光反射
2.5环境光
2.6自发光
3.经典光照模型
3.1Lambert模型
无高光,可以做类似橡胶材质效果
3.2Phong模型
3.3Blinn-Phong模型
Phone模型和Blinn-Phone模型的区别
通过对Phone模型的公式和Blinn-Phone模型公式的对比,可以知道公式的不同之处在于使用了半角向量与法线的点积代替了反射向量与视线的点积结果.
半角向量的使用带来了什么变化?
1.计算更加简洁,半角向量比反射向量的计算更加简洁
2.当光源与视线都在物体表面之上时,半角向量与法线的角度永远不大于90度
设想一种情况,当材质的反光度非常低,因此物体被光线照射的大部分区域都会发生高光反射。这些区域中一部分高光部分的反射问量与视线的夹角超过了90度。
如果使用Phone模型就会导致高光区域一部分发生缺失。这是由于phone模型只考虑视线与光照分布在法线两侧的情况,当视线与光照在法线同侧时且高光反射对亮度有较影响时,就会发生断层。
4.代码实现Phong和Blinn-Phong
Shader "Custom/Specular"
{Properties{_SpecularColor("高光反射颜色",COLOR)=(1,1,1,1)_Diffuse("漫反射颜色",COLOR)=(1,1,1,1)_shinness("光泽度",Range(1,64))=8}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include"Lighting.cginc"fixed4 _Diffuse;fixed4 _SpecularColor;float _shinness;struct v2f{float4 pos:POSITION;float4 color:COLOR;};v2f vert (appdata_base v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);//将顶点转换到裁剪空间o.color=UNITY_LIGHTMODEL_AMBIENT;//环境光//float3 normal=normalize(v.normal);// float3 L=normalize(_WorldSpaceLightPos0).xyz;//normal=mul(float4(normal,0),unity_WorldToObject).xyz;//normal=normalize(normal);//漫反射部分float3 L=normalize(WorldSpaceLightDir(v.vertex)).xyz;float3 normal = UnityObjectToWorldNormal(v.normal);//float ndotl=saturate(dot(normal,L));//兰伯特模型float ndotl=0.5*(dot(normal,L))+0.5;//半兰伯特模型o.color+=ndotl*_LightColor0*_Diffuse;//高光反射部分//Phong模型/* float3 R=reflect(-L,normal);float3 V=WorldSpaceViewDir(v.vertex);R=normalize(R);V=normalize(V);o.color.rgb+=_LightColor0*_SpecularColor*pow(saturate(dot(R,V)),_shinness);*///Blinn-Phong 光照模型float3 V=WorldSpaceViewDir(v.vertex);V=normalize(V);float3 H=normalize(L+V);o.color.rgb+=_LightColor0*_SpecularColor*pow(saturate(dot(H,normal)),_shinness);return o;}fixed4 frag (v2f i) : COLOR{return i.color;}ENDCG}}
}