Unity ShaderLab 个人学习笔记

最近在回顾Unity的着色器知识。

这里主要记录个人在ShaderLab中遇到的一些重点内容。

这篇会做持续记录,直到完成此遍回顾。

ShaderLab的基本结构

ShaderLab是基于Cg(HLSL)的,但不等同于Cg。它在此基础上又添加了一套东西,是高于Shader的东西。

某种程度可以把ShaderLab代码等同于Unity的材质。它包含了整套东西,概念上像是HLSL基础之上的D3D Effects。

Shader "ShaderName" {
    Properties {
        // 属性
    }
    SubShader {
        Pass {
            // 具体的Shader程序
        }
        Pass {
            // 有时会用到多个Pass
        }
    }
    SubShader {
        // 因为硬件的差异,有的旧硬件不支持某些Shader
        // 可能需要提供多个子Shader供Unity选择
        // Unity会选择第一个能运行的子Shader
    }
    // 当所有子Shader都不能运行时
    // 提供一个应急方案,双引号里是Shader名称
    // 或者关掉这个功能
    // 代码是:Fallback off
    Fallback "Diffuse"
}

注意这里Fallback有个隐藏影响,在Unity预计算阴影时,会在SubShader里找相关Pass,找不到就会用Fallback提供的。

Properties 属性设置

如果把Shader看成一套功能,或者广义的函数,那Properties就是Shader被提交给GPU执行时携带的参数。

...

Properies {
    // 形式:
    // Name("DisplayName", PropertyType) = DefaultValue
    // 例如:
    _pos("Position", Vector) = (1, 1, 1, 1)
}

...

这里_pos可以在后面的Shader代码里作为“变量名”使用。

PropertyType支持IntFloatRange(min,max)ColorVector2DCube3D这些类型,其中后3种是纹理类型。

贴图类型可以像这样:_tex("Texture", 2D) = "white"{},指定默认纹理。"white"是默认纹理名称。

代码种的属性会对应到Unity材质属性设置面板中。

SubShader的一般结构

...

SubShader {

    // 不一定要有
    Tags {
        // 标签块
        // 键值对形式        
    }

    // 不一定要有
    RenderSetup {
        // 状态设置块
    }

    Pass {

        // Pass的名字,不一定要给
        Name "Pass1"

        // Pass的Tags
        // 注意和和SubRender的不一样

        // 也可以有Pass自己的RenderSetup

        // CGPROGAM/ENDCG 表示该块是Cg代码
        // GLSLPROGAM/ENDGLSL 表示该块是glsl代码
        // 但是不推荐使用glsl,因为Unity能够将Cg交叉编译给glsl,反之不能
        CGPROGRAM

        // 指定具体的功能函数入口
        #pragma vertex      vert
        #pragma fragment    frag

        float4 vert(float4 v : POSITION) : SV_POSITION {
            return mul(UNITY_MATRIX_MVP, v);
        }

        fixed4 frag() : SV_Target {
            return fixed4(1.0, 0.0, 0.0, 1.0);
        }

        ENDCG
    }
}

...

Tags和RenderSetup放到后面记录。

其实ShaderLab还支持固定渲染管线,但是毕竟现在几乎已经没有了非可编程管线的硬件,就不做记录了。

RenderSetup 渲染状态设置

常用的状态表:

状态名 设置项目 解释
Cull Back, Front, Off 剔除模式:背面、正面、关闭
ZTest Less, Greater, LEqual, GEqual, Equal, NotEqual, Always 深度测试: <、>、<=、>=、==、!=、总是
ZWrit On, Off 深度写入开关
Blend 原模式,目的模式 打开并设置混合模式