代码一(在物体空间下进行点乘计算实现漫反射):
Shader "Sbin/MyDiffuse"
{
SubShader
{
pass
{
tags{"LightMode" = "ForwardBase"} // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
struct v2f
{
float4 pos:POSITION;
fixed4 color : COLOR;
};
// 顶点函数
v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
// 法线和世界空间光源位置(归一化处理)
float3 N = normalize(v.normal);
float3 L = normalize(_WorldSpaceLightPos0);
// 将指向光源的向量从世界空间转换到物体空间
L = mul(_World2Object,float4(L,0)).xyz;
// 使用saturate将点乘结果限定在0-1之间
float ndotl = saturate(dot(N,L));
o.color = _LightColor0 * ndotl;
return o;
}
// 片源函数
fixed4 frag(v2f IN) :COLOR
{
return IN.color + UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
}
代码二(在世界空间下进行点乘计算实现漫反射,为了光照过渡平滑,将计算放在片源函数中):
Shader "Sbin/MyDiffuse"
{
SubShader
{
pass
{
tags{"LightMode" = "ForwardBase"} // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
struct v2f
{
float4 pos:POSITION;
fixed4 color : COLOR;
};
// 顶点函数
appdata_base vert(appdata_base v)
{
appdata_base o = v;
o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
return o;
}
// 片源函数
fixed4 frag(appdata_base IN) :COLOR
{
// 法线和世界空间光源位置(归一化处理)
float3 N = normalize(IN.normal);
float3 L = normalize(_WorldSpaceLightPos0);
// 将法线向量从物体空间转换到世界空间
N = mul(float4(N,0),_World2Object).xyz;
// 使用saturate将点乘结果限定在0-1之间
float ndotl = saturate(dot(N,L));
return _LightColor0 * ndotl + UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
}
代码三(增添点光源的效果):
Shader "Sbin/MyDiffuse2"
{
SubShader
{
pass
{
tags{ "LightMode" = "ForwardBase" } // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
struct v2f
{
float4 pos:POSITION;
fixed4 color : COLOR;
};
// 顶点函数
v2f vert(appdata_base v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
// 法线和世界空间光源位置(归一化处理)
float3 N = normalize(v.normal);
float3 L = normalize(_WorldSpaceLightPos0);
// 将法线向量从物体空间转换到世界空间
N = mul(float4(N,0),_World2Object).xyz;
// 使用saturate将点乘结果限定在0-1之间
float ndotl = saturate(dot(N,L));
o.color = _LightColor0 * ndotl;
float3 wpos = mul(_Object2World,v.vertex).xyz;
o.color.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;
}
// 片源函数
fixed4 frag(v2f IN) :COLOR
{
return IN.color + UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
代码四(增添镜面反射的效果):
Shader "Sbin/MySpecular"
{
properties
{
_SpecularColor("SpecularColor",color) = (1,1,1,1)
_Shininess("Shininess",range(1,64)) = 8
}
SubShader
{
pass
{
tags{ "LightMode" = "ForwardBase" } // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
float4 _SpecularColor;
float _Shininess;
struct v2f
{
float4 pos:POSITION;
fixed4 color : COLOR;
};
// 顶点函数
v2f vert(appdata_base v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
// 法线和世界空间光源位置(归一化处理)
float3 N = normalize(v.normal);
float3 L = normalize(_WorldSpaceLightPos0);
// 将法线向量从物体空间转换到世界空间
N = mul(float4(N,0),unity_WorldToObject).xyz;
// 漫反射
float ndotl = saturate(dot(N,L));
o.color = _LightColor0 * ndotl;
// 镜面反射
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);
o.color += _SpecularColor * specularScale;
return o;
}
// 片源函数
fixed4 frag(v2f IN) :COLOR
{
return IN.color + UNITY_LIGHTMODEL_AMBIENT;
}
ENDCG
}
}
}
代码五(手动计算镜面反射):
Shader "Sbin/MySpecular2"
{
properties
{
_SpecularColor("SpecularColor",color) = (1,1,1,1)
_Shininess("Shininess",range(1,64)) = 8
}
SubShader
{
pass
{
tags{ "LightMode" = "ForwardBase" } // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
float4 _SpecularColor;
float _Shininess;
struct v2f
{
float4 pos:POSITION;
fixed4 color : COLOR;
};
// 顶点函数
v2f vert(appdata_base v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
// 添加环境光
o.color = UNITY_LIGHTMODEL_AMBIENT;
// 求指向光源的向量和法向量
float3 L = normalize(WorldSpaceLightDir(v.vertex));
float3 N = UnityObjectToWorldNormal(v.normal);
// 漫反射
float ndotl = saturate(dot(N,L));
o.color += _LightColor0 * ndotl;
// 镜面反射
// 计算反射向量和指向摄像机的向量
float3 R = 2 * saturate(dot(N,L)) * N - L;
float3 V = WorldSpaceViewDir(v.vertex);
// 单位化
R = normalize(R);
V = normalize(V);
// 镜面反射强度
float specularScale = pow(saturate(dot(R,V)),_Shininess);
// 添加镜面反射
o.color += _SpecularColor * specularScale;
return o;
}
// 片源函数
fixed4 frag(v2f IN) :COLOR
{
return IN.color;
}
ENDCG
}
}
}
代码六(BlinnPhong模型通过半角向量H计算镜面反射):
Shader "Sbin/MySpecular2"
{
properties
{
_SpecularColor("SpecularColor",color) = (1,1,1,1)
_Shininess("Shininess",range(1,64)) = 8
}
SubShader
{
pass
{
tags{ "LightMode" = "ForwardBase" } // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
float4 _SpecularColor;
float _Shininess;
struct v2f
{
float4 pos:POSITION;
fixed4 color : COLOR;
};
// 顶点函数
v2f vert(appdata_base v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
// 添加环境光
o.color = UNITY_LIGHTMODEL_AMBIENT;
// 求指向光源的向量/法向量/指向摄像机的向量
float3 L = normalize(WorldSpaceLightDir(v.vertex));
float3 N = UnityObjectToWorldNormal(v.normal);
float3 V = normalize(WorldSpaceViewDir(v.vertex));
// 漫反射
float ndotl = saturate(dot(N,L));
o.color += _LightColor0 * ndotl;
// 镜面反射
// 求得半角向量
float3 H = normalize(L + V);
// 通过求H、N的点积求镜面反射强度
float specularScale = pow(saturate(dot(H,N)),_Shininess);
// 添加镜面反射
o.color += _SpecularColor * specularScale;
return o;
}
// 片源函数
fixed4 frag(v2f IN) :COLOR
{
return IN.color;
}
ENDCG
}
}
}
代码七(片源级漫反射光照):
Shader "Sbin/MyDiffuseFrag"
{
SubShader
{
pass
{
tags{"LightMode" = "ForwardBase"} // 添加passtag(支持环境光、直接光、顶点光)
CGPROGRAM
#pragma multi_compile_fwbase
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc" // 包含appdata_base结构体
#include "lighting.cginc" // 包含_LightColor0
struct v2f
{
float4 pos:POSITION;
float3 normal:NORMAL;
float4 vertex:COLOR;
};
// 顶点函数
v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.normal = v.normal;
o.vertex = v.vertex;
return o;
}
// 片源函数
fixed4 frag(v2f IN):COLOR
{
float3 N = UnityObjectToWorldNormal(IN.normal);
float3 L = normalize(WorldSpaceLightDir(IN.vertex));
// 环境光
fixed4 col = UNITY_LIGHTMODEL_AMBIENT;
float diffuseScale = saturate(dot(N,L));
col += _LightColor0 * diffuseScale;
return col;
}
ENDCG
}
}
}