Unity中Shader LOD控制
Shader Level of Detail (LOD),翻譯過來是什麼「著色器的細節層次效果」。聽著好高端的樣子,這種誇張的翻譯也就只能放在那些作者自己都不知道寫的是什麼的軟文裡面。對於TA來說,Shader LOD其實就是根據設備性能的不同編譯不同版本的Shader。
這種編譯方式最早是為了適應不同時代的顯卡而準備的。主機端本來就不存在這個問題,而現在在PC端上想找到上古級別的顯卡也不太容易。所以目前這玩意兒最大的用途也就是為了適配高低配置不同的手機(以上為個人意見)。
使用Shader LOD,要編寫多個SubShader,格式大致如下:
Shader "YY/Cube" n{ntProperties {ntt_Color ("Color", Color) = (1,1,1,1)ntt_MainTex ("Albedo (RGB)", 2D) = "white" {}ntt_Glossiness ("Smoothness", Range(0,1)) = 0.5ntt_Metallic ("Metallic", Range(0,1)) = 0.0nt}ntSubShadernt{nttTags { "RenderType"="Opaque" }nttLOD 200nttnttCGPROGRAMntt// Physically based Standard lighting model, and enable shadows on all light typesntt#pragma surface surf Standard fullforwardshadowsnntt// Use shader model 3.0 target, to get nicer looking lightingntt#pragma target 3.0nnttsampler2D _MainTex;nnttstruct Input ntt{ntttfloat2 uv_MainTex;ntt};nntthalf _Glossiness;ntthalf _Metallic;nttfixed4 _Color;nnttvoid surf (Input IN, inout SurfaceOutputStandard o) ntt{nttt// Albedo comes from a texture tinted by colorntttfixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;nttto.Albedo = c.rgb;nttt// Metallic and smoothness come from slider variablesnttto.Metallic = _Metallic;nttto.Smoothness = _Glossiness;nttto.Alpha = c.a;ntt}nttENDCGnt}nntSubShadernt{nttTags { "RenderType"="Opaque" "IgnoreProjector"="True"}nttLOD 100nttUsePass "YY/BasicShaders/UNLIGHT"nt}nntSubShadernt{nttTags { "RenderType"="Opaque" "IgnoreProjector"="True"}nttLOD 50nttUsePass "YY/BasicShaders/UNLIGHTNOFOG"nt}nntFallBack "Diffuse"n}n
在腳本中給Shader.globalMaximumLOD賦值就可以改變Shader。個人推薦最好在初始化的時候做這一步。
小技巧就是給Pass的Name屬性賦值。這樣可以在LOD控制的時候做到代碼復用,非常方便。比如說上面代碼中UsePass "YY/BasicShaders/UNLIGHT" 和 UsePass "YY/BasicShaders/UNLIGHTNOFOG"。其源代碼如下:
Shader "YY/BasicShaders"n{ntPropertiesnt{ntt_MainTex ("Texture", 2D) = "white" {}nt}ntSubShadernt{nttTags { "RenderType"="Opaque" }nttPassntt{nttt//注意Name要寫在CGPROGRAM外面nttt//注意Name所有的字母必須大寫ntttName "UNLIGHTNOFOG"ntttCGPROGRAMnttt#pragma vertex vertnttt#pragma fragment fragnttt#include "UnityCG.cginc"nnntttstruct appdatanttt{nttttfixed4 vertex : POSITION;nttttfixed2 uv : TEXCOORD0;nttt};nntttstruct v2fnttt{nttttfixed2 uv : TEXCOORD0;nttttfixed4 vertex : SV_POSITION;nttt};nntttsampler2D _MainTex;ntttfixed4 _MainTex_ST;ntttntttv2f vert (appdata v)nttt{nttttv2f o;ntttto.vertex = mul(UNITY_MATRIX_MVP, v.vertex);ntttto.uv = TRANSFORM_TEX(v.uv, _MainTex);nttttreturn o;nttt}ntttntttfixed4 frag (v2f i) : SV_Targetnttt{nttttfixed4 col = tex2D(_MainTex, i.uv);nttttreturn col;nttt}ntttENDCGntt}nnnttPassntt{ntttName "UNLIGHT"ntttCGPROGRAMnttt#pragma vertex vertnttt#pragma fragment fragnttt// make fog worknttt#pragma multi_compile_fogntttnttt#include "UnityCG.cginc"nnntttstruct appdatanttt{nttttfixed4 vertex : POSITION;nttttfixed2 uv : TEXCOORD0;nttt};nntttstruct v2fnttt{nttttfixed2 uv : TEXCOORD0;nttttUNITY_FOG_COORDS(1)nttttfixed4 vertex : SV_POSITION;nttt};nntttsampler2D _MainTex;ntttfixed4 _MainTex_ST;ntttntttv2f vert (appdata v)nttt{nttttv2f o;ntttto.vertex = mul(UNITY_MATRIX_MVP, v.vertex);ntttto.uv = TRANSFORM_TEX(v.uv, _MainTex);nttttUNITY_TRANSFER_FOG(o,o.vertex);nttttreturn o;nttt}ntttntttfixed4 frag (v2f i) : SV_Targetnttt{ntttt// sample the texturenttttfixed4 col = tex2D(_MainTex, i.uv);ntttt// apply fognttttUNITY_APPLY_FOG(i.fogCoord, col);nttttreturn col;nttt}ntttENDCGntt}nt}nnnnn}n
Name所有的字母必須大寫!Name所有的字母必須大寫!Name所有的字母必須大寫!重要的事兒要說三遍!n
另外需要注意的是默認的Standered材質本身也是有LOD層級的,修改的時候小心別把Standerd效果給改動了。以下是Built-in shader LOD的使用方法:
Built-in shaders in Unity have their LODs set up this way:
- VertexLit kind of shaders = 100
- Decal, Reflective VertexLit = 150
- Diffuse = 200
- Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
- Bumped, Specular = 300
- Bumped Specular = 400
- Parallax = 500
- Parallax Specular = 600
Unity中編譯多版本Shader還可以使用multi_compile。具體可自行百度"使用multi_compile編譯Shader的多個版本"。這種方法可以全局設置也可以針對單獨的材質,可以和LOD配合使用。
推薦閱讀:
※Shader model 5.0 的片段著色器能不能得到該片段所在的三角圖元實際光柵化後有多少像素?
※Shader(四)邊緣發光和卡通光照
※一個簡單有趣的「黑洞」效果