一、Phone光照模型
光照 = 環(huán)境光 + 漫反射 + 高光

1.環(huán)境光? Ambient
環(huán)境光 = 環(huán)境光顏色 乘以 環(huán)境光強(qiáng)度
float3 ambient = _LightColor0 * _AmbientStrength;

2.漫反射? Diffuse
漫反射 = 光線入射方向 點(diǎn)乘 法線方向,再乘以 漫反射光顏色 乘以 漫反射光強(qiáng)度
float3 diff = dot(i.normal, _WorldSpaceLightPos0) * _LightColor0 * _DiffStrength;

3.高光? Specular
高光 = 攝像機(jī)(觀察)方向 點(diǎn)乘 反射光方向, 再求這個值的x次方,x是高光系數(shù)(決定了高光的聚集)。最后再乘以高光顏色,乘以高光強(qiáng)度。
反射光方向 = 入射光 和 法線 方向,求反射方向。
float3 reflectDir = reflect(-_WorldSpaceLightPos0, i.normal);
float3 spec = pow(max(dot(i.viewDir, reflectDir),0.0), _SpecPow) * _LightColor0 * _SpecStrength;

二、Blinn-Phong光照模型
在Phone光照模型的基礎(chǔ)上,僅有一點(diǎn)區(qū)別。
在計(jì)算高光時,將反射光與攝像機(jī)(觀察)方向的夾角,改為了發(fā)現(xiàn)方向與 攝像機(jī)(觀察)方向和入射方向的中間向量的夾角。
相同條件下Blinn-Phong的高光范圍要比Phong更大,寫實(shí)效果Phong光照模型更好。但算法簡單,運(yùn)行速度快是Blinn-Phong光照模型的優(yōu)點(diǎn)。


三、Phone光照模型的Shader示例代碼
Shader "Unlit/LightShader"
{
? ? Properties
? ? {
? ? ? ? _MainTex ("Texture", 2D) = "white" {}
? ? ? ? _AmbientStrength("Ambient Strength", Range(0,1.0)) = 0.1
? ? ? ? _DiffStrength("Diff Strength", Range(0,1.0)) = 0.1
? ? ? ? _SpecPow("Spec Pow", Range(0,100)) = 10
? ? ? ? _SpecStrength("Spec Strength", Range(0,1.0)) = 0.1
? ? ? ? _Brightness("Brightness", Range(0,5)) = 1
? ? }
? ? SubShader
? ? {
? ? ? ? Tags { "LightMode"="ForwardBase" }
? ? ? ? LOD 100
? ? ? ? Pass
? ? ? ? {
? ? ? ? ? ? CGPROGRAM
? ? ? ? ? ? #pragma vertex vert
? ? ? ? ? ? #pragma fragment frag
? ??????????// make fog work
? ? ? ? ? ? #pragma multi_compile_fog
? ? ? ? ? ? #include "UnityCG.cginc"
? ? ? ? ? ? #include "UnityLightingCommon.cginc"
? ? ? ? ? ? struct appdata
? ? ? ? ? ? {
? ? ? ? ? ? ? ? float4 vertex : POSITION;
? ? ? ? ? ? ? ? float2 uv : TEXCOORD0;
? ? ? ? ? ? ? ? float3 normal : NORMAL;
? ? ? ? ? ? };
? ? ? ? ? ? struct v2f
? ? ? ? ? ? {
? ? ? ? ? ? ? ? float2 uv : TEXCOORD0;
? ? ? ? ? ? ? ? UNITY_FOG_COORDS(1)
? ? ? ? ? ? ? ? float4 vertex : SV_POSITION;
? ? ? ? ? ? ? ? float3 normal : NORMAL;
? ? ? ? ? ? ? ? float3 viewDir : TEXCOORD1;
? ? ? ? ? ? };
? ? ? ? ? ? sampler2D _MainTex;
? ? ? ? ? ? float4 _MainTex_ST;
? ? ? ? ? ? float _AmbientStrength;
? ? ? ? ? ? float _DiffStrength;
? ? ? ? ? ? float _SpecPow;
? ? ? ? ? ? float _SpecStrength;
? ? ? ? ? ? float _Brightness;
? ? ? ? ? ? v2f vert (appdata v)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? v2f o;
? ? ? ? ? ? ? ? o.vertex = UnityObjectToClipPos(v.vertex);
? ??????????????// o.uv = v.uv;
? ? ? ? ? ? ? ? o.uv = TRANSFORM_TEX(v.uv, _MainTex);
? ? ? ? ? ? ? ? o.normal = UnityObjectToWorldNormal(v.normal);
? ? ? ? ? ? ? ? o.viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
? ? ? ? ? ? ? ? UNITY_TRANSFER_FOG(o,o.vertex);
? ? ? ? ? ? ? ? return o;
? ? ? ? ? ? }
? ? ? ? ? ? fixed4 frag (v2f i) : SV_Target
? ? ? ? ? ? {
? ? ? ? ? ? ? ? float4 baseColor = tex2D(_MainTex, i.uv);
? ??????????????// ambient
? ? ? ? ? ? ? ? float3 ambient = _LightColor0 * _AmbientStrength;
? ??????????????//diffuse
? ? ? ? ? ? ? ? float3 diff = dot(i.normal, _WorldSpaceLightPos0) * _LightColor0 * _DiffStrength;
? ??????????????//specular
? ? ? ? ? ? ? ? float3 reflectDir = reflect(-_WorldSpaceLightPos0, i.normal);
? ? ? ? ? ? ? ? float3 spec = pow(max(dot(i.viewDir, reflectDir),0.0), _SpecPow) * _LightColor0 * _SpecStrength;
? ??????????????//final color
? ? ? ? ? ? ? ? fixed4 col = float4((spec + diff + ambient), 1.0) * baseColor * _Brightness;
? ??????????????// apply fog
? ? ? ? ? ? ? ? UNITY_APPLY_FOG(i.fogCoord, col);
? ? ? ? ? ? ? ? return col;
? ? ? ? ? ? }
? ? ? ? ? ? ENDCG
? ? ? ? }
? ? }
}