<轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者
Shader Level of Detail (LOD),翻譯過來是什么“著色器的細節(jié)層次效果”。聽著好高端的樣子,這種夸張的翻譯也就只能放在那些作者自己都不知道寫的是什么的軟文里面。對于TA來說,Shader LOD其實就是根據(jù)設備性能的不同編譯不同版本的Shader。
這種編譯方式最早是為了適應不同時代的顯卡而準備的。主機端本來就不存在這個問題,而現(xiàn)在在PC端上想找到上古級別的顯卡也不太容易。所以目前這玩意兒最大的用途也就是為了適配高低配置不同的手機(以上為個人意見)。
使用Shader LOD,要編寫多個SubShader,格式大致如下:
Shader "YY/Cube"
{
?Properties {
??_Color ("Color", Color) = (1,1,1,1)
??_MainTex ("Albedo (RGB)", 2D) = "white" {}
??_Glossiness ("Smoothness", Range(0,1)) = 0.5
??_Metallic ("Metallic", Range(0,1)) = 0.0
?}
?SubShader
?{
??Tags { "RenderType"="Opaque" }
??LOD 200
??
??CGPROGRAM
??// Physically based Standard lighting model, and enable shadows on all light types
??#pragma surface surf Standard fullforwardshadows??// Use shader model 3.0 target, to get nicer looking lighting
??#pragma target 3.0??sampler2D _MainTex;
??struct Input
??{
???float2 uv_MainTex;
??};??half _Glossiness;
??half _Metallic;
??fixed4 _Color;??void surf (Input IN, inout SurfaceOutputStandard o)
??{
???// Albedo comes from a texture tinted by color
???fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
???o.Albedo = c.rgb;
???// Metallic and smoothness come from slider variables
???o.Metallic = _Metallic;
???o.Smoothness = _Glossiness;
???o.Alpha = c.a;
??}
??ENDCG
?}?SubShader
?{
??Tags { "RenderType"="Opaque" "IgnoreProjector"="True"}
??LOD 100
??UsePass "YY/BasicShaders/UNLIGHT"
?}?SubShader
?{
??Tags { "RenderType"="Opaque" "IgnoreProjector"="True"}
??LOD 50
??UsePass "YY/BasicShaders/UNLIGHTNOFOG"
?}?FallBack "Diffuse"
}
在腳本中給Shader.globalMaximumLOD賦值就可以改變Shader。個人推薦最好在初始化的時候做這一步。
小技巧就是給Pass的Name屬性賦值。這樣可以在LOD控制的時候做到代碼復用,非常方便。比如說上面代碼中UsePass "YY/BasicShaders/UNLIGHT" 和 UsePass "YY/BasicShaders/UNLIGHTNOFOG"。其源代碼如下:
Shader "YY/BasicShaders"
{
?Properties
?{
??_MainTex ("Texture", 2D) = "white" {}
?}
?SubShader
?{
??Tags { "RenderType"="Opaque" }
??Pass
??{
???//注意Name要寫在CGPROGRAM外面
???//注意Name所有的字母必須大寫
???Name "UNLIGHTNOFOG"
???CGPROGRAM
???#pragma vertex vert
???#pragma fragment frag
???#include "UnityCG.cginc"???struct appdata
???{
????fixed4 vertex : POSITION;
????fixed2 uv : TEXCOORD0;
???};???struct v2f
???{
????fixed2 uv : TEXCOORD0;
????fixed4 vertex : SV_POSITION;
???};???sampler2D _MainTex;
???fixed4 _MainTex_ST;
???
???v2f vert (appdata v)
???{
????v2f o;
????o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
????o.uv = TRANSFORM_TEX(v.uv, _MainTex);
????return o;
???}
???
???fixed4 frag (v2f i) : SV_Target
???{
????fixed4 col = tex2D(_MainTex, i.uv);
????return col;
???}
???ENDCG
??}??Pass
??{
???Name "UNLIGHT"
???CGPROGRAM
???#pragma vertex vert
???#pragma fragment frag
???// make fog work
???#pragma multi_compile_fog
???
???#include "UnityCG.cginc"???struct appdata
???{
????fixed4 vertex : POSITION;
????fixed2 uv : TEXCOORD0;
???};???struct v2f
???{
????fixed2 uv : TEXCOORD0;
????UNITY_FOG_COORDS(1)
????fixed4 vertex : SV_POSITION;
???};???sampler2D _MainTex;
???fixed4 _MainTex_ST;
???
???v2f vert (appdata v)
???{
????v2f o;
????o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
????o.uv = TRANSFORM_TEX(v.uv, _MainTex);
????UNITY_TRANSFER_FOG(o,o.vertex);
????return o;
???}
???
???fixed4 frag (v2f i) : SV_Target
???{
????// sample the texture
????fixed4 col = tex2D(_MainTex, i.uv);
????// apply fog
????UNITY_APPLY_FOG(i.fogCoord, col);
????return col;
???}
???ENDCG
??}
?}}
Name所有的字母必須大寫!Name所有的字母必須大寫!Name所有的字母必須大寫!重要的事兒要說三遍!另外需要注意的是默認的Standered材質(zhì)本身也是有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的多個版本"。這種方法可以全局設置也可以針對單獨的材質(zhì),可以和LOD配合使用。