本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。
这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。
========================================== 分割线 ==========================================
上一篇中,我们演示了如何使用自定义的光照模型进行渲染。这一次,我们将进一步看一下怎样对它做一些变化来得到更好的效果!
我们会列出两种方法:使用Half Lambert lighting model(半兰伯特光照模型)和使用一个ramp texture来控制diffuse shading。
Shader "Custom/BasicDiffuse" { Properties { _EmissiveColor ("Emissive Color", Color) = (1,1,1,1) _AmbientColor ("Ambient Color", Color) = (1,1,1,1) _MySliderValue ("This is a Slider", Range(0,10)) = 2.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf BasicDiffuse //We need to declare the properties variable type inside of the //CGPROGRAM so we can access its value from the properties block. float4 _EmissiveColor; float4 _AmbientColor; float _MySliderValue; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { //We can then use the properties values in our shader float4 c; c = pow((_EmissiveColor + _AmbientColor), _MySliderValue); o.Albedo = c.rgb; o.Alpha = c.a; } inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = max(0, dot (s.Normal, lightDir)); float4 col; col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2); col.a = s.Alpha; return col; } ENDCG } FallBack "Diffuse" }
inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = max(0, dot (s.Normal, lightDir)); // Add this line float hLambert = difLight * 0.5 + 0.5; float4 col; // Modify this line col.rgb = s.Albedo * _LightColor0.rgb * (hLambert * atten * 2); col.a = s.Alpha; return col; }
inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = max(0, dot (s.Normal, lightDir)); float hLambert = difLight * 0.5 + 0.5; float3 ramp = tex2D(_RampTex, float2(hLambert)).rgb; float4 col; col.rgb = s.Albedo * _LightColor0.rgb * (ramp); col.a = s.Alpha; return col; }
Shader "Custom/RampDiffuse" { Properties { _EmissiveColor ("Emissive Color", Color) = (1,1,1,1) _AmbientColor ("Ambient Color", Color) = (1,1,1,1) _MySliderValue ("This is a Slider", Range(0,10)) = 2.5 // Add this line _RampTex ("Ramp Texture", 2D) = "white"{} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf BasicDiffuse //We need to declare the properties variable type inside of the //CGPROGRAM so we can access its value from the properties block. float4 _EmissiveColor; float4 _AmbientColor; float _MySliderValue; // Add this line sampler2D _RampTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { //We can then use the properties values in our shader float4 c; c = pow((_EmissiveColor + _AmbientColor), _MySliderValue); o.Albedo = c.rgb; o.Alpha = c.a; } inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten) { float difLight = max(0, dot (s.Normal, lightDir)); float hLambert = difLight * 0.5 + 0.5; // Add this line float3 ramp = tex2D(_RampTex, float2(hLambert)).rgb; float4 col; // Modify this line col.rgb = s.Albedo * _LightColor0.rgb * (ramp); col.a = s.Alpha; return col; } ENDCG } FallBack "Diffuse" }
float3 ramp = tex2D(_RampTex, float2(hLambert)).rgb;