UnityShader 光照模型
**逐顶点兰伯特**
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = UnityObjectToWOrldNormal(v.normal);
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
fixed diff=saturate(dot(worldNormal, worldLight));
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * diff;
o.color = ambient + diffuse;
return o;
}
fixed4 frag(v2f i) :SV_Target{
return fixed4(i.color,1.0);
}
**逐像素兰伯特**
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal =UnityObjectToWOrldNormal(v.normal);
return o;
}
fixed4 frag(v2f i) :SV_Target{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed diff=saturate(dot(worldNormal, worldLight)) * 0.5 +0.5 ;
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * diff;
fixed3 color = ambient + diffuse;
return fixed4(color,1.0);
}
**逐像素半兰伯特**
fixed4 frag(v2f i) :SV_Target{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed diff=saturate(dot(worldNormal, worldLight)) * 0.5 +0.5 ;
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * diff;
fixed3 color = ambient + diffuse;
return fixed4(color,1.0);
}
**逐顶点高光**
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos=mul(_Object2World,v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal =UnityObjectToWOrldNormal(v.normal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed diffRate=saturate(dot(worldNormal, worldLightDir));
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * diffRate;
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(o.worldPos));
//normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
fixed SpecRate=pow(saturate(dot(viewDir, reflectDir)), _Gloss);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * SpecRate;
o.color = ambient + diffuse + specular;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(i.color, 1.0);
return col;
}
**逐像素高光**
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal =UnityObjectToWOrldNormal(v.normal);
o.worldPos=mul(_Object2World,v.vertex);
//mul(v.normal, (float3x3)unity_WorldToObject);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 worldNormal = normalize(i.worldNormal);
fixed diffRate=saturate(dot(worldNormal, worldLightDir));
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * diffRate;
//计算高光部分
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
fixed specRate= pow(saturate(dot(viewDir, reflectDir)), _Gloss);
fixed3 specular = _LightColor0.rgb * _Specular.rgb *specRate;
fixed3 color = ambient + diffuse + specular;
return fixed4(color, 1.0);
}
**Blin高光**
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 worldNormal = normalize(i.worldNormal);
fixed diffRate=saturate(dot(worldNormal, worldLightDir));
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * diffRate;
//计算高光部分
//fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
fixed3 halfDir=normalize(viewDir+worldLightDir);
fixed specRate= pow(saturate(dot(halfDir, worldNormal )), _Gloss);
fixed3 specular = _LightColor0.rgb * _Specular.rgb *specRate;
fixed3 color = ambient + diffuse + specular;
return fixed4(color, 1.0);
}
**菲涅尔反射**
//fresnel = fresnel基础值 + fresnel缩放量*pow( 1 - dot( N, V ), 5 )
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.normal = mul(v.normal, (float3x3)unity_WorldToObject);
o.lightDir = WorldSpaceLightDir(v.vertex);
o.viewDir = WorldSpaceViewDir(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float3 N = normalize(i.normal);
float3 L = normalize(i.lightDir);
float3 V = normalize(i.viewDir);
col.rgb *= saturate(dot(N, L)) * _LightColor0.rgb;
//菲尼尔公式
float fresnel = _fresnelBase + _fresnelScale*pow(1 - dot(N, V), _fresnelIndensity);
col.rgb += lerp(col.rgb, _fresnelCol, fresnel) * _fresnelCol.a;
return col;
}
**渐变纹理**
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _RampTex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambCol = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
fixed halfLambert = dot(worldNormal, lightDir) * 0.5 + 0.5;
//使用半兰伯特对渐变纹理进行采样
fixed3 color = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;
fixed3 diffCol= _LightColor0.rgb * color;
fixed3 halfDir = normalize(viewDir + lightDir);
fixed specRate= pow(max(0, dot(worldNormal, halfDir)), _Gloss);
fixed3 speCol = _LightColor0.rgb * _Specular.rgb *specRate;
return fixed4(ambCol + diffCol+ speCol , 1.0);
}
**使用立方体纹理实现反射效果**
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float3 lightDir = normalize(_WorldSpaceLightPos0);
float3 worldNormal = normalize(i.worldNormal);
float diff = max(0, dot(worldNormal, lightDir));
fixed4 diffuse = _Diffuse * _LightColor0 * diff;
float3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
float3 reflectLightDir = reflect(-viewDir, worldNormal);
//用反射向量采样立方体纹理
//fixed4 reflCol = texCUBE(_CubeMap, reflectLightDir);
//使用内置的宏采样
fixed4 skyData = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, reflectLightDir);
fixed3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR);
fixed4 reflCol = fixed4(skyColor.rgb, 1);
float3 halfDir = normalize(lightDir + viewDir);
fixed4 spec = pow(max(0, dot(halfDir, worldNormal)), _Shininess) * _LightColor0 * _SpecularColor;
float fresnel = _FresnelScale + (1 - _FresnelScale) * pow(saturate(1 - dot(viewDir, worldNormal)), 5);
fixed4 finalCol = lerp(diffuse, reflCol, saturate(fresnel)) + spec;
return finalCol;
}
unity内置的Lighting.cginc
兰伯特漫反射
inline fixed4 UnityLambertLight (SurfaceOutput s, UnityLight light)
{
fixed diff = max (0, dot (s.Normal, light.dir));
fixed4 c;
c.rgb = s.Albedo * light.color * diff;
c.a = s.Alpha;
return c;
}
Blin模型
inline fixed4 UnityBlinnPhongLight (SurfaceOutput s, half3 viewDir, UnityLight light)
{
half3 h = normalize (light.dir + viewDir);
fixed diff = max (0, dot (s.Normal, light.dir));
float nh = max (0, dot (s.Normal, h));
float spec = pow (nh, s.Specular*128.0) * s.Gloss;
fixed4 c;
c.rgb = s.Albedo * light.color * diff + light.color * _SpecColor.rgb * spec;
c.a = s.Alpha;
return c;
}