Unity-表面著色器示例
本頁上的表面著色器示例說明了如何使用內(nèi)置光照模型。如需查看如何實(shí)現(xiàn)自定義光照模型的示例,請(qǐng)參閱表面著色器光照示例。
簡單的著色器示例
我們將從一個(gè)非常簡單的著色器 (Shader) 開始,并在此基礎(chǔ)上加以豐富。下面的著色器將表面顏色設(shè)置為“白色”。它使用內(nèi)置的蘭伯特(漫射)光照模型。
Shader "Example/Diffuse Simple" { ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float4 color : COLOR; ? ? ? ?
? ?}; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = 1; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
以下是設(shè)置了兩個(gè)光源的模型:

紋理
一個(gè)全白的對(duì)象很無聊,所以讓我們添加一個(gè)紋理。我們將向著色器添加?Properties?代碼塊,這樣我們將在材質(zhì)中看到紋理選擇器。其他更改在下文中以粗體顯示。
?
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" ? ?
}

法線貼圖
我們來添加一些法線貼圖:
?
Shader "Example/Diffuse Bump" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_BumpMap ("Bumpmap", 2D) = "bump" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ?
? ? ?float2 uv_BumpMap; ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?sampler2D _BumpMap; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ?
? ? ?o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}

邊緣光照
現(xiàn)在,嘗試添加一些邊緣光照以突出游戲?qū)ο蟮倪吘?。我們將根?jù)表面法線和視圖方向之間的角度添加一些發(fā)射光照。為此,我們將使用內(nèi)置的表面著色器變量?viewDir
。
?
Shader "Example/Rim" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_BumpMap ("Bumpmap", 2D) = "bump" {} ? ? ? ?
? ?_RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0) ? ? ? ?
? ?_RimPower ("Rim Power", Range(0.5,8.0)) = 3.0 ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?float2 uv_BumpMap; ? ? ? ? ? ?
? ? ?float3 viewDir; ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?sampler2D _BumpMap; ? ? ? ?
? ?float4 _RimColor; ? ? ? ?
? ?float _RimPower; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ? ?
? ? ?o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); ? ? ? ? ? ?
? ? ?half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
? ? ?o.Emission = _RimColor.rgb * pow (rim, _RimPower); ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}

細(xì)節(jié)紋理
為獲得不同效果,讓我們添加一個(gè)與基礎(chǔ)紋理結(jié)合的細(xì)節(jié)紋理。細(xì)節(jié)紋理通常在材質(zhì)中使用相同的 UV,但使用不同平鋪,因此我們需要使用不同的輸入 UV 坐標(biāo)。
?
Shader "Example/Detail" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_BumpMap ("Bumpmap", 2D) = "bump" {} ? ? ? ?
? ?_Detail ("Detail", 2D) = "gray" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?float2 uv_BumpMap; ? ? ? ? ? ?
? ? ?float2 uv_Detail; ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?sampler2D _BumpMap; ? ? ? ?
? ?sampler2D _Detail; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ? ?
? ? ?o.Albedo *= tex2D (_Detail, IN.uv_Detail).rgb * 2; ? ? ? ? ? ?
? ? ?o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}

使用紋理棋盤格不一定有實(shí)際意義,但在此示例中可用于說明其作用:
屏幕空間中的細(xì)節(jié)紋理
屏幕空間中的細(xì)節(jié)紋理對(duì)于士兵頭部模型沒有實(shí)際意義,但是在這里可用于說明如何使用內(nèi)置的?screenPos
?輸入:
?
Shader "Example/ScreenPos" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_Detail ("Detail", 2D) = "gray" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?float4 screenPos; ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?sampler2D _Detail; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ? ?
? ? ?float2 screenUV = IN.screenPos.xy / IN.screenPos.w; ? ? ? ? ? ?
? ? ?screenUV *= float2(8,6); ? ? ? ? ? ?
? ? ?o.Albedo *= tex2D (_Detail, screenUV).rgb * 2; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
從上面的著色器刪除了法線貼圖,只是為了縮短代碼長度:

立方體貼圖反射
下面的著色器將使用內(nèi)置?worldRefl
?輸入來進(jìn)行立方體貼圖反射。它與內(nèi)置的反射/漫射著色器非常類似:
?
Shader "Example/WorldRefl" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_Cube ("Cubemap", CUBE) = "" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ?
? ? ?float3 worldRefl; ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?samplerCUBE _Cube; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.5; ? ? ? ? ? ?
? ? ?o.Emission = texCUBE (_Cube, IN.worldRefl).rgb; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
因?yàn)樗鼘⒎瓷漕伾付?__Emission__,所以我們得到了一個(gè)非常閃亮的士兵:

如果您想做一些受法線貼圖影響的反射,需要稍微復(fù)雜一些:需要將?INTERNAL_DATA
?添加到?Input
?結(jié)構(gòu),并使用?WorldReflectionVector
?函數(shù)在寫入法線輸出后計(jì)算每像素反射矢量。
Shader "Example/WorldRefl Normalmap" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_BumpMap ("Bumpmap", 2D) = "bump" {} ? ? ? ?
? ?_Cube ("Cubemap", CUBE) = "" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?float2 uv_BumpMap; ? ? ? ? ? ?
? ? ?float3 worldRefl; ? ? ? ? ? ?
? ? ?INTERNAL_DATA ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?sampler2D _BumpMap; ? ? ? ?
? ?samplerCUBE _Cube; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.5; ? ? ? ? ? ?
? ? ?o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); ? ? ? ? ? ?
? ? ?o.Emission = texCUBE (_Cube, WorldReflectionVector (IN, o.Normal)).rgb; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
下面是一個(gè)進(jìn)行了法線貼圖的閃亮士兵:

通過世界空間位置進(jìn)行的切片
下面的著色器通過丟棄幾乎水平的環(huán)形中的像素來對(duì)游戲?qū)ο蟆扒衅?。為?shí)現(xiàn)此效果,它使用了基于像素世界位置的 Cg/HLSL 函數(shù)?clip()
。我們將使用內(nèi)置的表面著色器變量?worldPos
。
?
Shader "Example/Slices" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_BumpMap ("Bumpmap", 2D) = "bump" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?Cull Off ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?float2 uv_BumpMap; ? ? ? ? ? ?
? ? ?float3 worldPos; ? ? ? ?
? ?}; ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?sampler2D _BumpMap; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?clip (frac((IN.worldPos.y+IN.worldPos.z*0.1) * 5) - 0.5); ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ? ?
? ? ?o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); ? ? ?
} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}

使用頂點(diǎn)修改器進(jìn)行法線擠出
可以使用“頂點(diǎn)修改器”函數(shù)來修改頂點(diǎn)著色器中的傳入頂點(diǎn)數(shù)據(jù)。這可用于程序化動(dòng)畫和沿法線擠出等操作。表面著色器編譯指令?vertex:functionName
?將用于此目的,其中的一個(gè)函數(shù)采用?inout appdata_full
?參數(shù)。
以下著色器沿著法線按照材質(zhì)中指定的量移動(dòng)頂點(diǎn):
?
Shader "Example/Normal Extrusion" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_Amount ("Extrusion Amount", Range(-1,1)) = 0.5 ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert vertex:vert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ?
? ?}; ? ? ? ?
? ?float _Amount; ? ? ? ?
? ?void vert (inout appdata_full v) { ? ? ? ? ? ?
? ? ?v.vertex.xyz += v.normal * _Amount; ? ? ?
? ?} ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
沿著法線移動(dòng)頂點(diǎn)會(huì)產(chǎn)生一個(gè)肥胖的士兵:

每頂點(diǎn)計(jì)算的自定義數(shù)據(jù)
使用頂點(diǎn)修改器函數(shù),還可以在頂點(diǎn)著色器中計(jì)算自定義數(shù)據(jù),然后將數(shù)據(jù)按像素傳遞給表面著色器函數(shù)。此情況下使用相同的編譯指令?vertex:functionName
,但該函數(shù)應(yīng)采用兩個(gè)參數(shù):inout appdata_full
?和?out Input
。您可以在其中填寫除內(nèi)置值以外的任何輸入成員。
注意:以這種方式使用的自定義輸入成員不得包含以“uv”開頭的名稱,否則它們將無法正常工作。
下面的示例定義了一個(gè)在頂點(diǎn)函數(shù)中計(jì)算的自定義?float3 customColor
?成員:
?
Shader "Example/Custom Vertex Data" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert vertex:vert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?float3 customColor; ? ? ? ?
? ?}; ? ? ? ?
? ?void vert (inout appdata_full v, out Input o) {
? ? ?UNITY_INITIALIZE_OUTPUT(Input,o); ? ? ? ? ? ?
? ? ?o.customColor = abs(v.normal); ? ? ? ?
? ?} ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ? ? ?
? ? ?o.Albedo *= IN.customColor; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}
在此示例中,customColor
?設(shè)置為法線的絕對(duì)值:

更實(shí)際的用途可能是計(jì)算內(nèi)置輸入變量不提供的任何每頂點(diǎn)數(shù)據(jù);或優(yōu)化著色器計(jì)算。例如,可以在游戲?qū)ο蟮捻旤c(diǎn)處計(jì)算邊緣光照,而不是在表面著色器中按照每個(gè)像素進(jìn)行計(jì)算。
最終顏色修改器
可以使用“最終顏色修改器”函數(shù)來修改著色器計(jì)算的最終顏色。表面著色器編譯指令?finalcolor:functionName
?將用于此目的,其中的一個(gè)函數(shù)采用?Input IN, SurfaceOutput o, inout fixed4 color
?參數(shù)。
下面是一個(gè)簡單的著色器,它將色調(diào)應(yīng)用于最終顏色。這與僅對(duì)表面反照率顏色應(yīng)用色調(diào)不同:此色調(diào)還會(huì)影響來自光照貼圖、光照探針和類似額外來源的任何顏色。
?
Shader "Example/Tint Final Color" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_ColorTint ("Tint", Color) = (1.0, 0.6, 0.6, 1.0) ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert finalcolor:mycolor ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ?
? ?}; ? ? ? ?
? ?fixed4 _ColorTint; ? ? ? ?
? ?void mycolor (Input IN, SurfaceOutput o, inout fixed4 color){ ? ? ? ? ? ?
? ? ?color *= _ColorTint; ? ? ?
? ?} ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}

使用最終顏色修改器自定義霧效
使用最終顏色修改器(見上文)的常見情況是在前向渲染中實(shí)現(xiàn)完全自定義的霧效。霧效需要影響最終計(jì)算的像素著色器顏色,這正是?finalcolor
?修改器的功能。
下面是一個(gè)根據(jù)與屏幕中心的距離應(yīng)用霧效色調(diào)的著色器。此著色器將頂點(diǎn)修改器與自定義頂點(diǎn)數(shù)據(jù) (fog
) 和最終顏色修改器組合在一起。用于前向渲染附加通道時(shí),霧效需要淡化為黑色。此示例將解決這一問題并檢查是否有?UNITY_PASS_FORWARDADD
。
?
Shader "Example/Fog via Final Color" { ? ? ?
?Properties { ? ? ? ?
? ?_MainTex ("Texture", 2D) = "white" {} ? ? ? ?
? ?_FogColor ("Fog Color", Color) = (0.3, 0.4, 0.7, 1.0) ? ? ?
?} ? ? ?
?SubShader { ? ? ? ?
? ?Tags { "RenderType" = "Opaque" } ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?#pragma surface surf Lambert finalcolor:mycolor vertex:myvert ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ? ? ?
? ? ?half fog; ? ? ? ?
? ?}; ? ? ? ?
? ?void myvert (inout appdata_full v, out Input data)
? ?{ ? ? ? ? ? ?
? ? ?UNITY_INITIALIZE_OUTPUT(Input,data); ? ? ? ? ? ?
? ? ?float4 hpos = UnityObjectToClipPos(v.vertex); ? ? ? ? ?
? ? ?hpos.xy/=hpos.w; ? ? ? ? ? ?
? ? ?data.fog = min (1, dot (hpos.xy, hpos.xy)*0.5); ? ? ? ?
? ?} ? ? ? ?
? ?fixed4 _FogColor; ? ? ? ?
? ?void mycolor (Input IN, SurfaceOutput o, inout fixed4 color)
? ?{ ? ? ? ? ? ?
? ? ?fixed3 fogColor = _FogColor.rgb; ? ? ? ? ? ?
? ? ?#ifdef UNITY_PASS_FORWARDADD ? ? ? ? ? ?
? ? ?fogColor = 0; ? ? ? ? ? ?
? ? ?#endif ? ? ? ? ? ?
? ? ?color.rgb = lerp (color.rgb, fogColor, IN.fog); ? ? ? ?
? ?} ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ? ? ?
? ? ?o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ? ?
?} ? ? ?
?Fallback "Diffuse" ? ?
}

線性霧效
Shader "Example/Linear Fog" { ?Properties { ? ?_MainTex ("Base (RGB)", 2D) = "white" {} ?} SubShader { ? ?
?Tags { "RenderType"="Opaque" } ? ?
?LOD 200 ? ? ? ?
?CGPROGRAM ? ?
?#pragma surface surf Lambert finalcolor:mycolor vertex:myvert ? ?
?#pragma multi_compile_fog ? ?
?sampler2D _MainTex; ? ?
?uniform half4 unity_FogStart; ? ?
?uniform half4 unity_FogEnd; ? ?
?struct Input {
? ?float2 uv_MainTex; ? ? ?
? ?half fog; ? ?
?}; ? ?
?void myvert (inout appdata_full v, out Input data) {
? ?UNITY_INITIALIZE_OUTPUT(Input,data); ? ? ?
? ?float pos = length(UnityObjectToViewPos(v.vertex).xyz); ? ? ?
? ?float diff = unity_FogEnd.x - unity_FogStart.x; ? ? ?
? ?float invDiff = 1.0f / diff; ? ? ?
? ?data.fog = clamp ((unity_FogEnd.x - pos) * invDiff, 0.0, 1.0);
?}
?void mycolor (Input IN, SurfaceOutput o, inout fixed4 color) {
? ?#ifdef UNITY_PASS_FORWARDADD
? ?UNITY_APPLY_FOG_COLOR(IN.fog, color, float4(0,0,0,0));
? ?#else UNITY_APPLY_FOG_COLOR(IN.fog, color, unity_FogColor); ? ? ?
? ?#endif ? ?
?} ? ?
?void surf (Input IN, inout SurfaceOutput o) { ? ? ?
? ?half4 c = tex2D (_MainTex, IN.uv_MainTex); ? ? ?
? ?o.Albedo = c.rgb;
? ?o.Alpha = c.a;
?}
?ENDCG
}
FallBack "Diffuse"
}
貼花
貼花通常用于在運(yùn)行時(shí)向材質(zhì)添加細(xì)節(jié)(例如,子彈沖擊力效果)。貼花在延遲渲染中特別有用,因?yàn)橘N花在照亮之前會(huì)改變 G 緩沖區(qū),因此可以節(jié)省開銷。
在常規(guī)情況下,貼花應(yīng)該在不透明對(duì)象之后渲染,并且不應(yīng)該是陰影投射物,如以下示例中的 ShaderLab“Tags”中所示。
Shader "Example/Decal" { ?
?Properties { ? ?
? ?_MainTex ("Base (RGB)", 2D) = "white" {} ?
?} ?
?SubShader { ? ?
? ?Tags { "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True" } ? ?
? ?LOD 200 ? ?
? ?Offset -1, -1 ? ? ? ?
? ?CGPROGRAM ? ?
? ?#pragma surface surf Lambert decal:blend ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?struct Input { ? ? ?
? ? ?float2 uv_MainTex; ? ?
? ?}; ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutput o) { ? ? ? ?
? ? ?half4 c = tex2D (_MainTex, IN.uv_MainTex); ? ? ? ?
? ? ?o.Albedo = c.rgb; ? ? ? ?
? ? ?o.Alpha = c.a; ? ? ?
? ?} ? ?
? ?ENDCG ? ?
?}
}