Unity Shader 的结构与语义

Unity Shader 与材质球(Material)

在unity中,我们需要将材质球(Material)和Shader配合使用才能达到所需要的效果。一般的流程是:
1. 创建一个材质球(Material)。
2. 创建一个Shader文件,并且把它赋给上一步的材质球。
3. 把材质球贴给所需要渲染的对象。
4. 调整材质中的Shader属性,达到效果。

Unity Shader结构

首先我们新建一个unity Shader(Unit Shader),打开之后就是以下的情况。

Shader "Unlit/NewUnlitShader"    //此处为unityShader所在的文件夹
{
    Properties    //属性
    {
        _MainTex ("Texture", 2D) = "white" {}
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(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
        }
    }
    FallBack "Diffuse"
}

首先第一行的名称。该名称表示Shader文件会出现在材质面板下拉列表里。例如该Shader文件就在Unlit文件夹下

unity 运行时材质球属性 unity材质球怎么做_unity

unity 运行时材质球属性 unity材质球怎么做_unity 运行时材质球属性_02

1. Properties

Properties语义块包含了一系列属性,这些属性会出现在材质面板中,在subShader语句块中用到的属性需要在Properties中先定义。以下是Properties中一些常用的属性类型和定义。

_Int("Int",Int) = 2 --变量名("变量名称",类型) = 初始值
_MainTex ("Texture", 2D) = "white" {}
_Diffuse ("Diffuse",Color) = (1,1,1,1)
_BumpMap ("Normal Map",2D) = "white"{}
_BumpScale ("BumpScale",float) = 1
_OutLineColor ("OutLineColor",Color) = (0,0,0,0)
_OutLine ("OutLine",Range(0,0.1)) = 0.0025
_Step ("Step",Range(1,30)) = 3.85
_ToonEffect ("ToonEffect",float) = 0.5
//_SnowLevel("SnowLevel",Range(0,0.1)) = 0.05
_SnowColor ("SnowColor",Color) = (1,1,1,1)
_SnowDir("SnowDir",Vector) = (0,1,0)
类型:
    float =  1.0
    range(0,10) = 1    --一个范围
    color   = rgba
    vector = (1,1,1,1)
    2D = "white" {}
    cube = "white"{}    --一般用于创建天空盒子
    3D = "black"{}

2. subShader

每个Unity Shader文件可以包含多个subShader语义块。但是最少要有一个。subShader语义块是当unity需要加载这个shader文件时,他会扫描所有的subShader语义块,从中找到第一个能在目标平台上运行的subshader,如果找不到的话,unity会使用FallBack语义指定的Shader (FallBack语义块就是这个作用)
subShader中一般包含了以下三个定义

//可选
Tags {
     "Queue" = "Transparent"    //渲染顺序
    "RenderType" = "Opaque"    //着色器替换功能
    "DisableBatching" = "True"    //关闭合批
    "ForceNoShadowCasting" = "True"  //是否投射阴影
    "IgnoreProjector" = "True" //受不受Projector影响通常用于透明物体
    "CanUseSpriteAltas" = "False" //是否是用于图片的shader
    "PrevoewType" = "Plane"  //用作shader面板预览的类型
}
//可选
[RanderSetup]    //渲染设置
Cull off/back/front  //不切,不渲染背面,不渲染前面
Ztest Always/less Greater/LEqual/GEqual/Equal/NotEqual   //深度测试
Zwrite off/on   //深度写入
Blend SrcFactor/DstFactor  //混合
LOD 100  //不同情况使用不同的LOD,提升性能

//Pass通道,可以有多个pass通道。但是不推荐,每个pass通道会多出DrawCall。
Pass{
	//other passes
}

3. Pass语义块

Pass{
    Name "Default"  //pass通道名称,用于其他pass调用
    Tags{    //比外面的多出两个类型,但是默认调外面的
        "LightMode" = "ForwardBase"//定义该pass通道在unity渲染流水中的角色
        "RequireOptions" = "SoftVegetation"//一般不用,表示满足某些条件时才调用该pass通道
    }
    //cg语言所写的代码,
    CGPROGRAM
        //代码
    ENDCG
    }
Pass{
	using DEFAULT   //一定要全大写
}

Unity Shader 语义

1.顶点着色器输入语义(Pass通道中默认的 vert() 方法)

1. POSITION :模型空间中的顶点位置,一般为float4
 2. NORMAL :顶点法线,一般为float3类型
 3. TANGENT :顶点切线,一般为float4类型
 4. TEXCOORDn :该顶点的纹理坐标,TEXCOORD0表示第一组坐标纹理,以此类推,通常为float2,float4类型
 5. COLOR :顶点颜色,通常是fixed4或float4类型

2.顶点着色器输出语义(Pass通道中默认的 frag() 方法)

1. SV_POSITION :裁剪空间中的顶点坐标,结构体中必须包含一个用该语义修饰的变量。
1. COLOR0 :通常用于输出第一组顶点颜色,不是必须。
1. COLOR1 :第二组顶点颜色,不是必须。
1. TEXCOORD0-TEXCOORD7 :输出纹理坐标,不是必须。

3.片元着色器输出语义

  1. SV_TARGET :输出值将会存储到渲染目标(render target)中