【UnityShader】Shader基础

材质

  材质是一个数据集,主要功能就是给渲染器提供数据和光照算法。

Unity Shader

  Unity Shader 是 Unity 为开发者提供的高层级的渲染抽象层。

Unity提供了 4 种 Unity Shader 模板

  • Standard Surface Shader
      包含了一个包含了标准光照模型的表面着色器模板;
  • Unlit Shader
      不包含光照(但包含雾效)的基本顶点/片元着色器;
  • Image Effect Shader
      为我们实现各种屏幕后处理效果提供了一个基本模板;
  • Compute Shader
      产生一个特殊的 Shader,这类 Shader 旨在利用 GPU 的并行性来进行一些常规渲染流水线无关的计算;

在Unity中需要配合使用材质和Unity Shader才能达到效果。常见的流程:

  1. 创建Unity Shader 和材质;
  2. 把 Unity Shader 赋给材质;
  3. 将材质赋给要渲染的对象;
  4. 在材质面板上调整 Unity Shader 属性(使用的纹理、漫反射系数等)来查看渲染效果;

ShaderLab

  Unity 提供的编写 Unity Shader 的一种说明性语言。

Unity Shader在 Inspector 面板中显示的内容

  • Default Maps
    指定该 Unity Shader 使用的默认纹理。当任何材质第一次使用该 Unity Shader 时,这些纹理就会自动被赋予到相应的属性上。
  • Surface shader
    是否是表面着色器。
  • Show generated code
    这个文件里将显示 Unity 在背后为该表面着色器生成的顶点/片元着色器。
  • Fixed function
    是否是固定函数着色器。
  • Compile and show code
    下拉列表可以让开发者检查该 Unity Shader 针对不同图像编程接口(例如 OpenGL、D3D9、D3D11等)最终编译成的 Shader 代码,直接单击该按钮可以查看生成的底层的汇编指令,可以利用这些代码来分析和优化着色器。
  • Cast shadows
    是否产生阴影
  • Render queue
    使用的渲染队列
  • LOD
    细节级别,可以在一个 shader 里写一出组 SubShader ,分别设置不同的 lod ,lod 越大的对应性能越好,越低的性能越差。就可以用设置 lod 的方法来控制游戏画面的渲染质量。在Unity3D->Project Setting->QualitySettings中的Maximum LODLevel可以设置最大LOD等级,Shader的LOD值是小于所设定的LOD值,才会被编译使用。Maximum LODLevel的等级可以设置7个级别,例如设置为1,则表示把最大LOD值设置为100,等级2,则最大LOD值为200,以此类推,若设置为0,则表示不进行LOD判断,任何LOD值的Shader都会被使用。
  • Ignore projector
    是否忽略投影
  • Disable batching
    是否关闭批处理

Unity Shader 的结构

// @1
Shader "Unlit/NewUnlitShader"
{
    // @2
    Properties
    {
        // @3
        _MainTex ("Texture", 2D) = "white" {}
        // 用于添加单选
		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0  
    }
    // @4
    SubShader
    {
        // @5 
        Tags { "RenderType"="Opaque" }
        // @6
        ZTest Always
        ZWrite Off
        // @7
        Pass
        {
       	 	// @8
        	Name "MyPassName"
            // @9
            Tags{"LightMode"="ForwardBase"}
            // @10
            Cull Off
            Blend SrcAlpha OneMinusSrcAlpha

			// @11
            CGPROGRAM
            @12
            sampler2D _MainTex;
            float4 _MainTex_ST;
            ENDCG
        }
    }
    // @13
    FallBack "Diffuse"
}
  • @1
    Shader 的名字,通过名字在材质面板的下拉列表中查找该shader。

  • @2
    Properties 是材质和 Unity Shader 的桥梁。
    Properties 语义块中包含了一系列的属性,这些属性将会出现在材质面板中。

  • @3
    _Name (“Display name”, Float) = 1
    解释:
      _Name 属性的名字,一般由下划线开始;
      Display name 显示在材质面板上的名字;
      Float 属性的类型;
      等号后面的为设置的默认值;

  Properties 语义块支持的属性类型

类型 默认的定义语法 例子
Int number _Count(“Count”,Int) = 2
Float number _Count(“Count”,Float) = 2.0
Range number _Range(“Range”,Range(0.0, 5.0)) = 3.0
Color (number,number,number,number) _Color(“Color”,Color) = (1,1,1,1)
Vector (number,number,number,number) _Vector(“Vector”,Vector) = (2,3,4,5)
2D “defaulttexture”{} _2D(“2D”,2D) = “”{}
Cube “defaulttexture”{} _Cube(“Cube”,Cube) = “white”{}
3D “defaulttexture”{} _3D(“3D”,3D) = “black”{}
  • @4
    每个 Unity Shader 文件最少包含一个 SubShader 语义块。当 Unity 需要加载这个 Unity Shader 时,Unity 会扫描所有的 SubShader 语义块,然后选择第一个能够在目标平台上运行的 SubShader。如果都不支持的话,Unity 就会使用 FallBack 语义指定的 Unity Shader。Unity 提供这种语义的原因在于,不同的显卡具有不同的能力。

  • @5
    SubShader 的标签类型(这些标签仅可以在 SubShader 中声明,而不可以在 Pass 块中声明)

类型 默认的定义语法 例子
标签类型 说明 例子
Queue 控制渲染顺序,指定该物体属于哪个渲染队列,通过这种方式可以保证所有的透明物体可以在所有不透明物体后面被渲染,也可以自定义使用的渲染队列来控制物体的渲染顺序 Tags{“Queue”=“Transparent”}
RenderType 对着色器进行分类,例如这是一个不透明的着色器或者是一个透明的着色器等,这可以被用于着色器替换(Shader Replacement)功能 Tags{“RenderType”=“Opaque”}
DisableBatching 一些SubShader在使用 Unity 的批处理功能时会出现问题,例如使用模型空间下的坐标进行顶点动画,这时可以通过该标签来直接指明是否对该 SubShader 使用批处理 Tags{“DisableBatching”=“True”}
ForceNoShadowCasting 控制使用该 SubShader 的物体是否会投射阴影 Tags{“ForceNoShadowCasting”=“True”}
IgnoreProjector 如果该标签值为“True”,那么使用该 SubShader 的物体将不会受 Projector影响。通常用于半透明物体 Tags{“IgnoreProjector”=“True”}
CanUseSpriteAtlas 当该 SubShader 适用于精灵(Sprite)时,将该标签设置“False” Tags{“CanUseSpriteAtlas”=“False”}
PreviewType 指明材质面板将如何预览材质。默认情况下,材质将显示为一个球形,我们可以通过把该标签的值设置为"Plane" “SkyBox” 来改变预览类型
  • @6
    ShaderLab 提供了一系列渲染状态的设置指令,这些指令可以设置显卡的各种状态。ShaderLab 常见的渲染状态设置选项
类型 默认的定义语法 例子
状态名称 设置指令 解释
Cull Cull Back/Front/Off 设置剔除模式:剔除背面/正面/关闭剔除
ZTest ZTest Less Greater/LEqual/GEqual/Equal/NotEqual/Always 设置深度测试时使用的函数
ZWrite ZWrite On/Off 开启/关闭深度写入
Blend Blend SrcFactor DesFactor 开启并设置混合模式
  • @7
    每个Pass 定义了一次完整的渲染流程。如果 Pass 的数目过多,往往会造成渲染性能的下降。

  • @8
    [name] 定义该 Pass 的名称,通过这个名字,其他 Unity Shader 可以使用 ShaderLab 的 UsePass 命令来直接使用该 Pass。注意:由于 Unity 内部会把所有 Pass 的名称转换成大写字母的表示,因此,在使用 UsePass 命令时必须使用大写形式的名字。例如“ UsePass “Common/MYPASSNAME”

  • @9
    Pass 的标签类型,它的标签不同于 SubShader 的标签。这些标签也是用于告诉渲染引擎我们希望怎样来渲染该物体。

类型 默认的定义语法 例子
标签类型 说明 例子
LightMode 定义改 Pass 在Unity的渲染流水线中的角色 Tags{“LightMode”=“ForwardBase”}
RequireOptions 用于指定当满足某些条件时才渲染该 Pass,它的值是一个由空格分隔的字符串,目前,Unity 支持的选项有:SoftVegetation Tags{“Require”=“SoftVegetation”}
  • @10
    同@6

  • @11
    CGPROGRAM 和 ENDCG 之间的代码是使用 CG/HLSL 编写的,也就是说,我们需要把 CG/HLSL 语言嵌套在ShaderLab 语言中。

  • @12
    定义和 Properties 中属性类型相匹配的变量。注意:即使不在Properties中声明属性,也可以直接在CG中定义变量.

  • @13
    FallBack
    例如:FallBack “name” 或者 FallBack Off
    当上面所有的 SubShader 在这块显卡上都不能运行,那就使用 FallBack 指定的。FallBack 还会影响阴影的投射。在渲染阴影纹理时,Unity会在每个Unity Shader 中寻找一个阴影投射的 Pass。通常情况下,我们不需要自己专门实现一个 Pass,这是因为 FallBack 使用的内置 Shader中包含了这样一个通用的pass,因此,为每个Unity Shader 正确设置 FallBack是非常重要的。

  • 其他
    特殊的 Pass
    UsePass:可以使用该命令来复用其他 Unity Shader 中的 Pass。
    GrabPass:该 Pass 负责抓取屏幕并将结果存储在一张纹理中,以用于后续的 Pass 处理。

ShaderLab 其他语义

  1. 自定义材质面板的编辑页面,使用 CustomEditor 来扩展编辑页面;
  2. 使用 Category 语音来对 UnityShader 中的命令进行分组。

表面着色器

  • Unity 自己创造的一种着色器代码类型,它需要的代码量很少,Unity 在背后做了很多工作,但渲染的代价比较大;
  • 当给 Unity 提供一个表面着色器的时候,它在背后仍旧把它转换成对应的顶点/片元着色器;
  • 表面着色器被定义在 SubShader 语义块,而非 Pass 语义块中的 CGPROGRAM 和 ENDCG 之间。原因是,表面着色器不需要开发者关心使用多少个 Pass,每个 Pass 如何渲染等问题,Unity 会在背后为我们做好这些事情。
	Shader "Custom/NewSurfaceShader"
	{
	    Properties
	    {
	    }
	    SubShader
	    {
	        Tags { "RenderType"="Opaque" }
	        CGPROGRAM
	        #pragma surface surf Lambert
	        struct Input
	        {
	            分loat color : COLOR;
	        };
	        void surf (Input IN, inout SurfaceOutput o)
	        {
	           o.Albedo = 1;
	        }
	        ENDCG
	    }
	    FallBack "Diffuse"
	}

顶点/片元着色器

  • 在 Unity 中我们可以使用 CG/HLSL 语言来编写顶点/片元着色器,它们更加复杂,但灵活性更高。
	Shader "Unlit/NewUnlitShader"
	{
	    Properties
	    {
	    }
	    SubShader
	    {
	        Tags { "RenderType"="Opaque" }
	        Pass
	        {
	            CGPROGRAM
	            #pragma vertex vert
	            #pragma fragment frag

	            float4 vert(float4 v : POSITION):SV_POSITION
	            {
					return UnityObjectToClipPos(v);
	            }

	            fixed4 frag (v2f i) : SV_Target
	            {
	                return fixed4(1,1,1,1);
	            }
	            ENDCG
	        }
	    }
	}
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读