Unity-表面著色器光照示例
本頁(yè)提供了表面著色器中的自定義表面著色器光照模型的示例。要進(jìn)一步了解常規(guī)表面著色器指南,請(qǐng)參閱表面著色器示例。
因?yàn)開(kāi)_延遲光照__與一些自定義的每材質(zhì)光照模型不兼容,所以下面的大多數(shù)示例都使著色器僅編譯到__前向渲染__。
漫射
以下是使用內(nèi)置蘭伯特光照模型的著色器示例:
Shader "Example/Diffuse Texture" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ?
? ?}; ? ? ? ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
以下是有紋理和沒(méi)有紋理的外觀(在場(chǎng)景中使用一個(gè)方向光):
?


以下示例顯示了如何通過(guò)編寫(xiě)自定義光照模型(而不是使用內(nèi)置蘭伯特模型)來(lái)實(shí)現(xiàn)相同的結(jié)果。
為此,您需要使用許多表面著色器光照模型函數(shù)。下面是一個(gè)簡(jiǎn)單的蘭伯特光照模型。請(qǐng)注意,只有CGPROGRAM
?部分發(fā)生變化;周?chē)闹鞔a完全相同:
? ?
Shader "Example/Diffuse Texture" { ? ? ? ? ? ?
?Properties { ? ? ? ? ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ? ? ?
?} ? ? ? ? ? ?
?SubShader { ? ? ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ? ? ?
? ?CGPROGRAM ? ? ? ? ? ? ?
? ?#pragma surface surf SimpleLambert ? ? ? ? ? ? ? ?
? ?half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
? ? ?half NdotL = dot (s.Normal, lightDir); ? ? ? ? ? ? ? ? ?
? ? ?half4 c; ? ? ? ? ? ? ? ? ?
? ? ?c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten);
? ? ?c.a = s.Alpha; ? ? ? ? ? ? ? ? ?
? ? ?return c; ? ? ? ? ? ? ?
? ?} ? ? ? ? ? ? ?
? ?struct Input { ? ? ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ?}; ? ? ? ? ? ? ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ? ? ? ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ? ?
? ?} ? ? ? ? ? ?
? ?ENDCG ? ? ? ? ? ?
?} ? ? ? ? ? ?
?Fallback "Diffuse" ? ? ? ?
}
這個(gè)簡(jiǎn)單的漫射光照模型使用了?LightingSimpleLambert
?函數(shù)。它通過(guò)以下方式計(jì)算光照:計(jì)算表面法線和光線方向之間的點(diǎn)積,然后應(yīng)用光衰減和顏色。
漫射環(huán)繞
以下示例顯示了__環(huán)繞漫射__,這是對(duì)__漫射__光照的修改,其中光照“環(huán)繞著”對(duì)象的邊緣。它對(duì)于模擬次表面散射效果很有用。只有?CGPROGRAM
?部分發(fā)生變化,這里同樣省略了周?chē)闹鞔a:
? ?
...ShaderLab code... ? ? ? ?
CGPROGRAM ? ? ? ?
#pragma surface surf WrapLambert ? ? ? ?
half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) {
?half NdotL = dot (s.Normal, lightDir); ? ? ? ? ? ?
?half diff = NdotL * 0.5 + 0.5; ? ? ? ? ? ?
?half4 c; ? ? ? ? ? ?
?c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten);
?c.a = s.Alpha; ? ? ? ? ? ?
?return c; ? ? ? ?
} ? ? ? ?
struct Input { ? ? ? ? ? ?
?float2 uv_MainTex; ? ? ? ?
}; ? ? ? ? ? ?
sampler2D _MainTex; ? ? ? ? ? ?
void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
} ? ? ? ?
ENDCG ? ? ? ?
?...ShaderLab code...
以下是有紋理和沒(méi)有紋理的外觀(在場(chǎng)景中使用一個(gè)方向光):
?

卡通漸變 (Toon Ramp)
以下示例顯示了一個(gè)“漸變”光照模型,該模型使用紋理漸變來(lái)定義表面如何響應(yīng)光源和法線之間的角度。這可以用于各種效果,并且在與__卡通__光照一起使用時(shí)尤其有效。
? ?
...ShaderLab code... ? ? ? ?
CGPROGRAM ? ? ? ?
#pragma surface surf Ramp ? ? ? ?
sampler2D _Ramp; ? ? ? ?
half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten) { ? ? ? ? ? ?
?half NdotL = dot (s.Normal, lightDir); ? ? ? ? ? ?
?half diff = NdotL * 0.5 + 0.5; ? ? ? ? ? ?
?half3 ramp = tex2D (_Ramp, float2(diff)).rgb; ? ? ? ? ? ?
?half4 c; ? ? ? ? ? ?
?c.rgb = s.Albedo * _LightColor0.rgb * ramp * atten; ? ? ? ? ? ?
?c.a = s.Alpha; ? ? ? ? ? ?
?return c; ? ? ? ?
} ? ? ? ?
struct Input { ? ? ? ? ? ?
?float2 uv_MainTex; ? ? ? ?
}; ? ? ? ? ? ?
sampler2D _MainTex; ? ? ? ? ? ?
void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
} ? ? ? ?
ENDCG ? ? ? ?
?...ShaderLab code...
以下是有紋理和沒(méi)有紋理的外觀(在場(chǎng)景中使用一個(gè)方向光):
?

簡(jiǎn)單鏡面反射
以下示例顯示了一個(gè)簡(jiǎn)單的鏡面反射光照模型,類(lèi)似于內(nèi)置的 BlinnPhong 光照模型。
? ?
...ShaderLab code... ? ? ? ?
CGPROGRAM ? ? ? ?
#pragma surface surf SimpleSpecular ? ? ? ?
half4 LightingSimpleSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{ ? ? ? ? ? ?
?half3 h = normalize (lightDir + viewDir); ? ? ? ? ? ?
?half diff = max (0, dot (s.Normal, lightDir)); ? ? ? ? ? ?
?float nh = max (0, dot (s.Normal, h)); ? ? ? ? ? ?
?float spec = pow (nh, 48.0); ? ? ? ? ? ?
?half4 c; ? ? ? ? ? ?
?c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * atten;
?c.a = s.Alpha; ? ? ? ? ? ?
?return c; ? ? ? ?
} ? ? ? ?
struct Input { ? ? ? ? ? ?
?float2 uv_MainTex; ? ? ? ?
}; ? ? ? ? ? ?
sampler2D _MainTex; ? ? ? ? ? ?
void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
} ? ? ? ?
ENDCG ? ? ? ?
?...ShaderLab code...
以下是有紋理和沒(méi)有紋理的外觀(在場(chǎng)景中使用一個(gè)方向光):
?

自定義 GI
我們將從一個(gè)模仿 Unity 內(nèi)置 GI 的著色器開(kāi)始:
? ?
Shader "Example/CustomGI_ToneMapped" { ? ? ? ?
?Properties { ? ? ? ? ? ?
? ?_MainTex ("Albedo (RGB)", 2D) = "white" {} ? ? ? ?
?} ? ? ? ?
?SubShader { ? ? ? ? ? ?
? ?Tags { "RenderType"="Opaque" } ? ? ? ? ? ? ? ? ? ?
? ?CGPROGRAM ? ? ? ? ? ?
? ?#pragma surface surf StandardDefaultGI ? ? ? ? ? ? ? ?
? ?#include "UnityPBSLighting.cginc" ? ? ? ? ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ? ? ? ? ?
? ?inline half4 LightingStandardDefaultGI(SurfaceOutputStandard s, half3 viewDir, UnityGI gi)
? ?{ ? ? ? ? ? ? ? ?
? ? ?return LightingStandard(s, viewDir, gi); ? ? ? ? ? ?
? ?} ? ? ? ? ? ? ? ?
? ?inline void LightingStandardDefaultGI_GI(SurfaceOutputStandard s,UnityGIInput data,inout UnityGI gi)
? ?{ ? ? ? ? ? ? ? ?
? ? ?LightingStandard_GI(s, data, gi); ? ? ? ? ? ?
? ?} ? ? ? ? ? ? ? ?
? ?struct Input { ? ? ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ?}; ? ? ? ? ? ? ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutputStandard o) {
? ? ?o.Albedo = tex2D(_MainTex, IN.uv_MainTex);
? ?} ? ? ? ? ? ? ? ?
? ?ENDCG ? ? ? ? ? ?
?} ? ? ? ? ? ?
?FallBack "Diffuse" ? ? ? ?
}
現(xiàn)在,讓我們?cè)?GI 上添加一些色調(diào)映射:
? ?
Shader "Example/CustomGI_ToneMapped" { ? ? ? ?
? Properties { ? ? ? ? ? ?
? ? _MainTex ("Albedo (RGB)", 2D) = "white" {} ? ? ? ? ? ?
? ? _Gain("Lightmap tone-mapping Gain", Float) = 1 ? ? ? ? ? ?
? ? _Knee("Lightmap tone-mapping Knee", Float) = 0.5
? ? _Compress("Lightmap tone-mapping Compress", Float) = 0.33 ? ? ? ?
? } ? ? ? ?
? SubShader { ? ? ? ? ? ?
? ? Tags { "RenderType"="Opaque" } ? ? ? ? ? ? ? ? ? ?
? ? CGPROGRAM ? ? ? ? ? ?
? ? #pragma surface surf StandardToneMappedGI ? ? ? ? ? ? ? ?
? ? #include "UnityPBSLighting.cginc" ? ? ? ? ? ? ? ?
? ? half _Gain; ? ? ? ? ? ?
? ? half _Knee; ? ? ? ? ? ?
? ? half _Compress; ? ? ? ? ? ?
? ? sampler2D _MainTex; ? ? ? ? ? ? ? ?
? ? inline half3 TonemapLight(half3 i) { ? ? ? ? ? ? ? ?
? ? ? i *= _Gain; ? ? ? ? ? ? ? ?
? ? ? return (i > _Knee) ?(((i - _Knee)*_Compress) + _Knee) : i; ? ? ? ? ? ?
? ? } ? ? ? ? ? ? ? ?
? ? inline half4 LightingStandardToneMappedGI(SurfaceOutputStandard s, half3 viewDir, UnityGI gi) ? ? ? ? ? ?
? ? { ? ? ? ? ? ? ? ?
? ? ? return LightingStandard(s, viewDir, gi); ? ? ? ? ? ?
? ? } ? ? ? ? ? ? ? ?
? ? inline void LightingStandardToneMappedGI_GI(SurfaceOutputStandard s,UnityGIInput data,inout UnityGI gi){
? ? ? LightingStandard_GI(s, data, gi);
? ? ? gi.light.color = TonemapLight(gi.light.color);
? ? ? #ifdef DIRLIGHTMAP_SEPARATE
? ? ? #ifdef LIGHTMAP_ON
? ? ? gi.light2.color = TonemapLight(gi.light2.color);
? ? ? #endif
? ? ? #ifdef DYNAMICLIGHTMAP_ON ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? gi.light3.color = TonemapLight(gi.light3.color); ? ? ? ? ? ? ? ? ? ?
? ? ? #endif ? ? ? ? ? ? ? ?
? ? ? #endif ? ? ? ? ? ? ? ?
? ? ? gi.indirect.diffuse = TonemapLight(gi.indirect.diffuse);
? ? ? gi.indirect.specular = TonemapLight(gi.indirect.specular); ? ? ? ? ? ?
? ? } ? ? ? ? ? ? ? ?
? ? struct Input { ? ? ? ? ? ? ? ?
? ? ? float2 uv_MainTex; ? ? ? ? ? ?
? ? }; ? ? ? ? ? ? ? ? ? ?
? ? void surf (Input IN, inout SurfaceOutputStandard o) {
? ? ? o.Albedo = tex2D(_MainTex, IN.uv_MainTex); ? ? ? ? ? ? ? ?
? ? } ? ? ? ? ? ? ? ?
? ? ENDCG ? ? ? ? ? ?
? } ? ? ? ? ? ?
? FallBack "Diffuse" ? ? ?
}