实现漫反射,首先得需要漫反射的实现原理。
漫反射的光包括物体表面漫反射的光和环境光,即:
AmbientLight+Diffuse
另外需要了解光照的反光原理,如图:
最后用一段代码来实现,首先,要有光照模式,以及Unity3D内生的一些函数。关照模式通过标签tags来添加,内生的一些函数通过include来添加。代码如下:
Shader "Custom/Vf Shader" {
SubShader {
PASS{
tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
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));
o.col=_LightColor0*ndotl;
return o;
}
float4 frag(v2f IN):COLOR{
return IN.col+UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
FallBack "Diffuse"
最后,可以通过调节环境光影响效果。
如果想得到Unity3D内建的shader的diffuse的效果,还需要修改一下以上的代码,需要把法向量在稍作修改。
Shader "Custom/Vf Shader" {
SubShader {
PASS{
tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
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));
o.col=_LightColor0*ndotl;
return o;
}
float4 frag(v2f IN):COLOR{
return IN.col+UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
FallBack "Diffuse"
}
如果是点光源,发现上述代码依然存在问题,上述代码只能被平行光影响,所以需要用到Unity3D的内建函数:Shade4PointLights
Shader "Custom/Vf Shader" {
SubShader {
PASS{
tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
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 wpos=mul(_Object2World,v.vertex);
o.col=_LightColor0*ndotl;
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"
}