首先来看一下反射原理:首先通过L和N来求出R的向量,然后求出视角的向量V,最后将V和R点乘,可以求出光照强度。
承接上一篇,具体代码如下:
Shader "Custom/Vf Shader" {
properties{
_SpecularColor("SpecularColor",color)=(1,1,1,1)
_Shininess("Shininess",range(1,8))=4
}
SubShader {
PASS{
tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
float _Shininess;
float4 _SpecularColor;
struct v2f{
float4 pos:POSITION;
float4 col:COLOR;
};
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
float3 N=normalize(v.normal);
float3 L=normalize(_WorldSpaceLightPos0);
//float3 L2=mul(_World2Object,float4(L,0)).xyz;
//float ndotl=saturate(dot(N,L2));
N=mul(float4(N,0),_World2Object);
N=normalize(N);
float ndotl=saturate(dot(N,L));
float3 I=-WorldSpaceLightDir(v.vertex);
float3 R=reflect(I,N);
float3 V=WorldSpaceViewDir(v.vertex);
R=normalize(R);
V=normalize(V);
float specularScale=pow(saturate(dot(R,V)),_Shininess);
float3 wpos=mul(_Object2World,v.vertex);
o.col=_LightColor0*ndotl*specularScale*_SpecularColor;
o.col.rgb+=Shade4PointLights(unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
unity_LightColor[0].rgb,unity_LightColor[1].rgb,unity_LightColor[2].rgb,unity_LightColor[3].rgb,
unity_4LightAtten0,
wpos,N
) ;
return o;
}
float4 frag(v2f IN):COLOR{
return IN.col+UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
FallBack "Diffuse"
}
最后的效果如图:
接着来看一下BlinnPhong的原理,通过L和V得到H向量,然后将H向量和N向量点乘得到光照强度。BlinnPhong的计算速度更快,因为它少了反射向量的计算。
Shader "Custom/Vf Shader" {
properties{
_SpecularColor("SpecularColor",color)=(1,1,1,1)
_Shininess("Shininess",range(1,8))=4
}
SubShader {
PASS{
tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
float _Shininess;
float4 _SpecularColor;
struct v2f{
float4 pos:POSITION;
float4 col:COLOR;
};
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
float3 N=normalize(v.normal);
float3 L=normalize(_WorldSpaceLightPos0);
//float3 L2=mul(_World2Object,float4(L,0)).xyz;
//float ndotl=saturate(dot(N,L2));
N=mul(float4(N,0),_World2Object);
N=normalize(N);
float ndotl=saturate(dot(N,L));
float3 I=normalize(-WorldSpaceLightDir(v.vertex));
float3 V=normalize(WorldSpaceViewDir(v.vertex));
float3 H=I+V;
float specularScale=pow(saturate(dot(H,N)),_Shininess);
float3 wpos=mul(_Object2World,v.vertex);
o.col=_LightColor0*ndotl*specularScale*_SpecularColor;
o.col.rgb+=Shade4PointLights(unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0,
unity_LightColor[0].rgb,unity_LightColor[1].rgb,unity_LightColor[2].rgb,unity_LightColor[3].rgb,
unity_4LightAtten0,
wpos,N
) ;
return o;
}
float4 frag(v2f IN):COLOR{
return IN.col+UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
FallBack "Diffuse"
}