美文网首页
Shader笔记——ShaderLab

Shader笔记——ShaderLab

作者: 莫忘初心_倒霉熊 | 来源:发表于2021-10-25 22:52 被阅读0次

    在Unity中,所有的Shader程序都是使用名为“ShaderLab”的声明性语言进行编写的。ShaderLab语法不区分大小写。

    1.1 Shader的组织结构

    Shader的大致结构如下:

    Shader "Name"
    {
        Properties
        {
            //开放到材质面板的属性
        }
        SubShader
        {
            //顶点-片段着色器或者表面着色器或者固定函数着色器
        }
        SubShader
        {
            //更加精简的版本
            //为了在旧的图形设备上运行
        }
        Fallback "Name"
    }
    
    1. Shader中可以编写多个SubShader,但至少需要一个。在应用程序运行过程中,GPU会先检测第一个SubShader能否正常运行,如果不能正常运行就会在检测第二个,依次类推。
    2. 假如当前GPG的硬件版本太旧,以至于所有的SubShader都无法正常运行,则执行最后的Fallback命令,运行指定的一个基础着色器。
    3. 如果编写的是Vertex-Fragment Shader,每个SubShader还会包含一个或多个Pass。如果某个SubShader能够在当前GPU上运行,那么该SubShader内的所有Pass会依次执行,每个Pass的输出结果会以指定的方式与上一步的结果进行混合,最终输出。
    4. 如果编写的是Surface Shader,着色器的代码也是包含在SubShader中,但是Surface Shader不会在嵌套Pass。系统在编译编译Surface Shader时会自动生成多个对应的Pass,最终编译出来的Shader本质上就是Vertex-Fragment Shader。

    1.2 Shader的名称

    Shader程序的第一行代码用来声明该Shader的名称以及所在的路径。如:

    Shader "Custom/Simple Shader"
    
    Shader选择面板

    1.3 Properties

    Unity可以通过Properties代码块将不同类型的变量或贴图资源开放给开发者,以便可以在材质面板中调节。
    Unity Shader的属性主要分为三大类:数值,颜色和向量,纹理贴图,语法定义如下:

    _Name("Display Name",type)=defaultValue[{option}]
    

    (1)_Name:属性的名字。通常在名字的最前加一个下划线,后续在整个Shader中都将使用这个名称来获取该属性。
    (2)Display Name:在材质面板中显示出来的名称。
    (3)type:属性的类型。
    (4)defaultValue:将Shader指定给材质的时候初始化的默认值。

    所有类型属性汇总如下:

        Properties
        {
            // 浮点类型 
            _MyFloat ("Float Property", Float) = 1 
            // 范围类型
            _MyRange ("Range Property", Range(0, 1)) = 0.1 
            // 颜色类型   
            // 数值范围是[0,1]
            _MyColor ("Color Property", Color) = (1, 1, 1, 1) 
            //向量类型
            _MyVector ("Vector Property", Vector) = (0, 1, 0, 0) 
            // 2D贴图类型   
            // 默认值可以为空字符串,也可以是表示颜色的字符串如:"white","black","gray","bump"
            // "bump"通常用于法线贴图的默认值
            _MyTex ("Texture Property", 2D) = "white" {} 
            // 立方体贴图类型
            // 默认值使用gray(RGBA:0.5,0.5,0.5,0.5)
            _MyCube ("Cube Property", Cube) = "" {} 
            // 3D贴图类型
            // 默认值使用gray(RGBA:0.5,0.5,0.5,0.5)
            _My3D ("3D Property", 3D) = "" {} 
        }
    
    不同属性类型的显示样式

    在Unity5.0之前的版本,纹理属性可以在花括号内添加属性,用于控制固定函数纹理坐标的生成。但是该功能在Unity5.0及以后版本已经移除,所以直接加上一对空的花括号即可。

    虽然Properties在参数调节过程中提供了便利,但是这部分代码在Shader中并不是必须的。如果不需要开放参数,完全可以在Shader中省略Properties这部分代码。

    1.4 SubShader

    SubShader大致结构如下:

        SubShader
        {
            // 标签
            Tags{"TagName1" = "Value1" "TagName2" = "Value2"}
            // 渲染状态
            Cull Back
    
            pass
            {
                // 第一个Pass
            }
            pass
            {
                // 第二个Pass
            }
        }
    

    每个SubShader都可以设置一个或多个标签(Tags)和渲染状态(States),然后定义至少一个Pass。在SubShader中设置的渲染状态会影响到该SubShader中所有的Pass,如果想要某些状态不影响其他Pass,可以针对某个Pass单独设置渲染状态,不过需要注意,部分渲染状态在Pass中并不支持。

    1.4.1 SubShader的标签

    SubShader通过标签来确定什么时候以及如何对物体进行渲染,标签通过键值对的形式进行声明,没有数量限制,语法如下:

    Tags{"TagName1" = "Value1" "TagName2" = "Value2"}
    

    1. 渲染队列 Queue
    在SubShader中可以使用Queue标签确定物体的渲染顺序,如下Unity预先定义的五中渲染队列:

    队列名称 描述 队列号
    Background 最先执行渲染,一般用来绘制Skybox或者背景 1000
    Geometry 非透明的几何体通常使用这个队列,当没有声明渲染队列的时候,Unity会默认使用这个队列 2000
    AlphaTest Alpha Test的几何体都是用这个队列,之所以从Geometry队列单独拆分出来,是因为当所有实体都绘制完之后在绘制Alpha Test会更高效 2450
    Transparent 在这个队列的几何体按由远及近的顺序进行绘制,所有进行Alpha Blend的几何体都应该使用这个队列,如玻璃材质,粒子特效 3000
    Overlay 用于叠加渲染的效果,如镜头光晕,放到最后渲染 4000

    也可以自己指定一个队列,如:

    Tags { "Queue" =  "Geometry + 1" }
    

    也可以在材质面板中进行设置,如图:

    材质设置面板中的渲染队列
    2. 渲染类型 RenderType
    RenderType标签可以将Shader划分为不同的类别,用于后期进行Shader替换或者产生摄像机的深度纹理。如下:
    类别说明 描述
    Opaque 用于普通Shader,如:不透明,自发光,反射,地形Shader
    Transparent 用于半透明Shader,如:透明,粒子
    TransparentCutout 用于透明测试Shader,如:植物叶子
    Background 用于Skybox Shader
    Overlay 用于GUI纹理,Halo,Flare Shader
    TreeOpaque 用于地形系统中的树干
    TreeTransparentCutout 用于地形系统中的树叶
    TreeBillboard 用于地形系统中的Billboarded树
    Grass 用于地形系统中的草
    GrassBillboard 用于地形系统中的Billboarded草

    3. 禁用批处理 DisableBatching
    当使用批处理(Batching)的时候,几何体会被变换到世界空间,模型空间会被丢弃。这会导致某些使用模型空间顶点数据的Shader最终无法实现所希望的效果。而开启DisableBatching(禁用批处理)可以解决这个问题。
    禁用批处理标签有三个数值可以使用:
    (1)"DisableBatching"="True":总是禁用批处理。
    (2)"DisableBatching"="False":不禁用批处理,这是默认值。
    (3)"DisableBatching"="LODFading":当LOD效果激活的时候才会禁用批处理,主要用于地形系统上的树。
    4. 禁用阴影投射 ForceNoShadowCasting
    在游戏中,有很多特效类的物体并不需要对其他物体产生投影,这个时候可以将ForceNoShadowCasting标签设置为True。
    5. 忽略投影机 IgnoreProjector
    如果不希望物体受到Projector(投影机)的投射,可以将IgnoreProjector标签设置为True。一般半透明的Shader都会开启这个标签。
    6. 其他标签
    除此之外,Unity还提供了很多不常用的标签,如CanUseSpriteAtlas,PreviewType等。请看Unity官方文档关于SubShader标签这一部分的内容。

    1.4.2 Pass的渲染状态

    如果想某些Pass的渲染状态不影响到其他Pass,可以在该Pass中单独设置渲染状态。并且这些渲染状态在SubShader中同样被允许使用,但是会影响到该SubShader中所有Pass。

    渲染状态 数值 作用
    Cull Cull Back|Front|Off 设置多边形的剔除方式,有背面剔除,正面剔除,不剔除,默认为Back
    ZTest ZTest LEqual|GEqual|Equal|NotEqual|Less|Greater|Always 设置深度测试的对比方式,默认为LEqual
    ZWrite ZWrite On|Off 设置是否写入深度缓存,默认为On
    Blend Blend sourceBlendMode destBlendMode 设置渲染图像的混合方式
    ColorMask ColorMask RGB|A|0|或者R,G,B,A的任意组合 设置颜色通道的写入蒙版,默认模板为RGBA,当设置为0时,则无法写入任何颜色

    其他低频使用的渲染状态请阅读Unity官方文档里关于Pass的渲染状态这一部分内容。

    1.5 Fallback

    Fallback在所有SubShader之后进行定义。当所有SubShader都不能在当前显卡上运行的时候,就会运行Fallback定义的Shader。语法如下:

    Fallback "name"
    

    最常用于Fallback的Shader为Unity内置的Diffuse。
    可以使用Fallback Off或者直接什么都不写,来关闭Fallback功能。

    相关文章

      网友评论

          本文标题:Shader笔记——ShaderLab

          本文链接:https://www.haomeiwen.com/subject/xqedaltx.html