Unity Shader学习笔记(3)Unity Shader模板、结构、形式

发表于2017-12-29
评论0 3.1k浏览
本篇文章还是属于Unity Shader学习笔记中的打基础内容,让大家了解Unity Shader模板和机构,再就是Unity Shader形式中的三种着色器。

Unity Sahder的模板
模板名功能
Standard Surface Shader包含标准光照模型的表面着色器模板。
Unlit Shader产生一个不包含光照(但包含雾效)的基本的顶点/片元着色器。
ImageEffect Shader实现各种屏幕后处理效果的基本模版。
Compute Shader特殊的Shader,利用GPU的并行性来进行一些与常规渲染流水线无关的计算。

标准着色器模板信息

标签名功能
Default Maps默认纹理。
Surface shader点击‘Show generated code’,可以看到Unity在背后为表明着色器生成的顶点/片元着色器)。
Fixed function固定函数着色器(用于旧设备)。如果使用了同样会有一个按钮,用来查看生成的顶点/片元着色器。
Compiled code选择不同图像编程接口,编译成对应Shader代码。可以查看生成的底层汇编指令。
Cast shadows是否捕获阴影。
Render queue渲染队列优先级。
LODLevel of Detail,着色器的细节层次效果。
Ignore projector是否忽视投影(常用于半透明物体)。
Disable batching是否不使用批处理。
Properties属性列表。

Unity Sahder的结构

// 着色器名称
Shader "ShaderName" {
    // 属性 
    Properties {
        Name ("display name", PrpertyType) = DefaultValue
    }
    // 子着色器
    SubShader {
        // 可选的,标签(告诉Unity如何、何时渲染对象)k
        [Tags]
        // 可选的,状态设置(开关混合、深度测试,剔除模式,设置深度测试使用函数)
        [RenderSetup]
        // 完整渲染流程
        Pass {
            [Name]
            [Tags]
            [RanderSetup]
        }
    }
    //SubShader不能运行时执行(同时渲染阴影)
    Fallback "VertexLit"  
}


Properties

属性。不一定要在Properties语义块中声明,也可以在Cg中定义变量(可通过脚本向Shader传递)。 
作用:只是为了让这些属性显示在材质面板中。 
定义:Name ("display name", PrpertyType) = DefaultValue 
- Name:名字。在Shader中访问该变量时,要声明这个名字。 
- display name:显示的名字。即面板显示的标签名字。 
- PropertyType:属性类型。 
- DefaultValue:默认值。

样例

Properties {
    // Numbers and Sliders
    _Int ("Int", Int) = 2
    _Float ("Float", Float) = 1.5
    _Range("Range", Range(0.0, 5.0)) = 3.0
    // Colors and Vectors
    _Color ("Color", Color) = (1,1,1,1)
    _Vector ("Vector", Vector) = (2, 3, 6, 1)
    // Textures
    _2D ("2D", 2D) = "" {}
    _Cube ("Cube", Cube) = "white" {}
    _3D ("3D", 3D) = "black" {}
}


SubShader

子着色器。每一个Unity Shader文件可以包含多个SubShader语义块,但最少要有一个。Unity会扫描所有SubShader语义块,然后选择第一个能够在目标平台上运行的,如果都不支持,则会使用Fallback指定的Shader。 
定义: 
- Tags:标签,可选。 
- RenderSetup:状态,可选。 
- Pass:一次完整的渲染流程。可以在里面声明标签和状态。

状态设置(RenderSetup)

设置显卡的各种状态。如果需要应用到所有Pass块中,则在SubShader中设置。否则如双面渲染,第一个Pass剔除正面(Cull Front)来渲染背面,第二个Pass剔除背面(Cull Back)来渲染正面。

标签(Tags)

是键值对,都为字符串类型。用于告诉Unity:SubShader要怎么样以及合适渲染这个对象。 
结构:Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

注意:下面这些标签都只可以在SubShafer中声明,不可以在Pass块中声明。 

Pass语义块

Pass {
    [Name]          // 如 Name "MyPassName"
    [Tags]
    [RenderSetup]
    // Other code
}
  • Name:名称。
  • RenderSetup:同SubShader,还可以使用固定管线的着色器命令。
  • Tags:不同与Subshader的标签。

Pass块中的Tags 

其他标签: 
- UsePass:直接使用别的Shader的Pass块。在使用时必须使用大写形式如:UsePass "MyShader/MYPASSNAME"。 
- GrabPass:抓取屏幕,并将结果存储到一张纹理中,用于后序的Pass处理。

Fallback

如果以上的SubShader都不能用,就用这个最低级的Shader(Fallback "name"),或者直接丢弃(Fallback Off)。还会影响阴影的投射,内置Shader包含一个通用的Pass来处理。

Unity Sahder的形式

表面着色器(Surface Shader)

这是Unity自己创造的一种着色器代码类型,在背后会转换成对应的顶点/片元着色器,相当于再对顶点/片元着色器的抽象。定义在CGPROGRAMENDCG之间,而不是在Pass中。

#pragma surface surf Lambert        //  使用surf函数作为表面着色器,用Lambert光照模型
struct Input {
    float4 color : COLOR;
};
void surf (Input IN, inout SurfaceOutput o){
    o.Albedo = 1;
}

顶点/片元着色器(Vertex/Fragment Shader)

相比表面着色器更复杂,但更灵活。可以控制渲染的实现细节。同样定义在CGPROGRAMENDCG之间。

#pragma vertex vert             // 使用vert函数作为顶点着色器
#pragma fragment frag           // 使用frag函数作为片元着色器

固定函数着色器(Fixed Function Shader)

以上两种都是可编程管线,而对于一些旧设备,就不支持了,这时就要用固定函数着色器完成渲染,也只能完成一些简单的效果。定义在Pass块中。

Pass {
    Material {
        Diffuse [_Color]
    }
    Lighting On
}

Unity Shader学习笔记系列教程:

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引