当前位置:首页 > 编程开发

Unity中Shader LOD控制

webgou9年前 (2018-03-31)编程开发55

 文章来自https://zhuanlan.zhihu.com/p/21316674 

 

这一部分算是比较简单的内容,与其说是技术相关,不如说是新项目美术前期规划方面的准备。前期地基打的越牢,后面的工作越轻松。
  Shader Level of Detail (LOD),翻译过来是什么“着色器的细节层次效果”。听着好高端的样子,这种夸张的翻译也就只能放在那些作者自己都不知道写的是什么的软文里面。对于TA来说,Shader LOD其实就是根据设备性能的不同编译不同版本的Shader。
  这种编译方式最早是为了适应不同时代的显卡而准备的。主机端本来就不存在这个问题,而现在在PC端上想找到上古级别的显卡也不太容易。所以目前这玩意儿最大的用途也就是为了适配高低配置不同的手机(以上为个人意见)。
  使用Shader LOD,要编写多个SubShader,格式大致如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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"。其源代码如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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材质本身也是有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配合使用。

扫描二维码推送至手机访问。

版权声明:本文由知了博客发布,如需转载请注明出处。

本文链接:https://www.webgou.info/?id=628

标签: unity
分享给朋友:

“Unity中Shader LOD控制” 的相关文章

Android平台值得关注的开源项目

Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用。下面推荐几个应用开源项目,这些项目不仅提供了优秀的创意,也可以直接掌握 Android内核的接口使用:1.Android团队提供的示例项目...…

ATL处理函数跳转的思考

今天,分析MFC与WTL的消息映射,比较难理解的有下面两点: 1.MFC,AfxCbtFilterHook转到AfxWndProc, 2.WTL(ATL),CWndProcThunk把窗口指针跳转到WindowProc,并把hWnd改成窗口指针.…

flash 3d下载地址

away3d: svn:http://away3d.googlecode.com/svn/trunk www.away3d.com网站打不开,应该下载不了 pvp3d: http://papervision3d.googlecode.com/svn/trunk/ sandy: http://www.…

FM 中的 RDS 功能

 从网上搜来的字面解释是:RDS是英国BBC广播公司开发的一种特殊的无线电广播,称”无线数据广播系统“(Radio Data System),它是在调频广播发射信号中利用副载波把电台名称、节目类型、节目内容及其它信息以数字形式发送出去。通过具有RDS功能的调谐器就…

ServerSocketChannel

http://diary.51.com/diary/diary_add.php?groupid=103706呵呵,我来告诉你吧,至于例子代码在我的回答记录中有。你自己翻来去看,是用nio给一个学生写的BBS聊天室。在用nio通讯的过程我用以下情景给你模拟: 1. 学校(ServerSocketCha…

通往WinDbg的捷径(二)

 保存 dumps 在 我们调试不容易重现的问题时,可能想把应用程序状态的快照(内存内容,打开名柄的列表,等等)保存起来,以便日后分析。例如,当我怀疑当前的状态可能包含 我试图解决的问…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。