ShaderLab中vertex fragment类Shader基础格式笔记

//U3D用的shader语言叫ShaderLab,基础语法官方文档地址
//https://docs.unity3d.com/Manual/SL-Shader.html
//开头指明名字,可以在别的shader中通过名字调用该shader的Pass什么的
//UsePass "ShaderName/PassName"
Shader "ShaderName"
{
    //属性定义
    Properties
    {
        [DisplayType]_Name("Display Name", type) = defaultValue {options}
        [DisplayType]_Name("Display Name", type) = defaultValue {options}
        //改Shader暴露的参数,在需要使用的Pass的CG代码段里需要重新声明一次

        //type包括
        // Color 一种颜色,由RGBA四个量来定义
        // 2D 一张2的阶数大小(256,512之类)的贴图。
        // Rect 一个非2阶数大小的贴图
        // Cube 即Cube map texture(立方体纹理)
        // Float 任意一个浮点数
        // Vector 一个四维数
        // Range(min, max) 一个介于最小值和最大值之间的浮点数

        //defaultValue
        //color 的是 (0,0,0,0)
        //Rrct 的是 "white" {}

        //{option}: 它只对2D,Rect或者Cube贴图有关,最少一对什么都不含的空白的{},
        // 选项(多个选项,可以使用空白分隔): ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal中的一个

        //DisplayType可选,告诉编辑器如何显示这个属性,常见的类型
        // [Toggle] Display as a toggle
        // [Enum(One,1,SrcAlpha,5)] 展示位枚举
        // 共有两种自定义界面的方式,详细见自定义编辑界面笔记

        //在自定义函数部分中可以用[name]的方式使用 比如 Blend [_SrcBlend] [_DstBlend]
        //Properties块定义的参数是给材质球用的,用代码的方式可以有更多类型的参数,但不能被保存下来
    }

    //子着色器,可以包含多个,根据不同的条件选择一个执行(硬件条件之类的)
    //从上到下; SubShader的标签、Pass的标签;SubShader是否和当前的GPU兼容
    SubShader
    {
        //硬件将通过判定这些标签来决定什么时候调用该着色器
        //可选可以啥都不写全部走默认值
        Tags { 
            "Queue"="Transparent+10"
            //Queue 渲染顺序,从小到大调用,可以用加减法微调,预定义的Queue有
            //Background 1000 - 最早被调用的渲染,用来渲染天空盒或者背景
            //Geometry 2000 - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
            //AlphaTest 2450 - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
            //Transparent 3000 - 以从后往前的顺序渲染透明物体
            //Overlay 4000 - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)

            "RenderType"="Transparent"
            //Unity可以运行时替换符合特定RenderType的所有Shader,与Camera.RenderWithShader或Camera.SetReplacementShader配合使用
            //Unity内置的RenderType包括:
            //Opaque: 不透明的物
            //Transparent: 透明着色器
            //Background: 天空盒都
            //Overlay: GUI、镜头光晕等
            //可以自定义替换标签 "Distort"="On"

            //其他常用
            "IgnoreProjector"="True" //不接受Projector组件的投影
            "ForceNoShadowCasting"="True" //不产生阴影
        }

        //剔除规则 默认剔除背面
        Cull Back | Front | Off

        //是否写入深度缓存 默认写入
        ZWrite On | Off

        //深度检查 默认小于等于
        ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always

        //深度偏移 用来解决z-fighting现象 比如 Offset 3, 0
        Offset Factor, Units

        //混合模式指令 也可以放在Pass中 详见Blending笔记
        Blend SrcAlpha OneMinusSrcAlpha
        //Blend Off 关闭混合,默认值
        //Blend SrcFactor DstFactor 最终值=原值*SrcFactor + 屏幕值*DstFactor

        //Level of Detail, Quality Settings中设定 MaximumLOD level,从上到下选择第一个起效的SubShader
        //代码用 Shader.globalMaximumLOD 控制
        //一个SubShader一个LOD值 不支持Pass级的控制
        LOD 200 //默认值为200

        //支持多pass 多次绘制
        Pass
        {
            //可选 模板缓冲 每个像素有一个8位(0-255)的模板值
            //目标测试位于深度检测之前,额外的一个条件决定 片元shader是否调用
            stencil
            {  
                Ref referenceValue //参考值,这个值将用来与模板缓冲中的值进行比较
                ReadMask readMask //读遮罩,读取是按位与(&)操作,默认值255
                WriteMask writeMask //写遮罩,默认值255
                Comp comparisonFunction //比较方式 默认 always 
                //参考值&readMask Comp 当前缓冲值&readMask
                //[Greater, GEqual, Less, LEqual, Equal, NotEqual, Always, Never]

                Pass stencilOperation //通过模板测试和深度测试时的处理方式 默认值:keep
                Fail stencilOperation //模板测试失败时 默认值:keep
                ZFail stencilOperation //模板测试通过 深度测试失败 默认值:keep
                //处理方式
                //Keep 保留当前缓冲中的内容,即stencilBufferValue不变。
                //Zero 将0写入缓冲,即stencilBufferValue值变为0。
                //Replace 将参考值写入缓冲,即将referenceValue赋值给stencilBufferValue。
                //IncrSat stencilBufferValue加1,如果stencilBufferValue超过255了,那么保留为255,即不大于255。
                //DecrSat stencilBufferValue减1,如果stencilBufferValue超过为0,那么保留为0,即不小于0。
                //Invert 将当前模板缓冲值(stencilBufferValue)按位取反
                //IncrWrap 当前缓冲的值加1,如果缓冲值超过255了,那么变成0,(然后继续自增)
                //DecrWrap 当前缓冲的值减1,如果缓冲值已经为0,那么变成255,(然后继续自减)
            }

            //可选,用于Pass的重用
            Name "PassName"

            //可选 Pass的Tags有和SubShader公用的也有专用的
            Tags { 
                "LightMode"="ForwardBase"
                //最重要的一个tag 指定用哪一种渲染路径,保证U3D的光照变量能被正确赋值
                //ForwardBase 前向渲染,会计算环境光,最重要的平行光,逐顶点光源和Lightmaps
                //ForwardAdd 前向渲染,会计算额外的逐像素光源,一个Pass对应一个光源
                //Always 永远都渲染,但不处理光照
                //Deferred 延迟渲染,会计算G-buffer
                //ShadowCaster 把物体渲染到阴影映射纹理或一张深度纹理中
            }

            //可以改变改pass的一些参数 不使用subshader的参数
            //比如 Cull Zwrite Ztest 等

            //标记CG代码开始
            CGPROGRAM

            //#pragma 编译指令段 详见 https://docs.unity3d.com/Manual/SL-ShaderPrograms.html

            //指明顶点Shader和片元shader的函数名字
            #pragma vertex vert
            #pragma fragment frag

            //编译目标model版本
            #pragma target name
            //2.5(默认) 数字越高,要求越高

            //多版本Shader 会生成多个版本的Shader 详见multiple shader笔记
            #pragma multi_compile ...
            //or 
            #pragma shader_feature ...

            //指定渲染平台
            #pragma only_renderers gles gles3
            #pragma exclude_renderers d3d9 d3d11 opengl
            //常见手游平台
            //gles - OpenGL ES 2.0
            //gles3 - OpenGL ES 3.x
            //metal - iOS/Mac Metal

            //cginc包,支持自定义,但是要写明路径,默认路径为Shader所在目录
            #include "UnityCG.cginc"
            #include "../Lib/MyTools.cginc"

            //数据类型声明
            //基础精确
            //float:32位高精度浮点数。
            //half: 16位中精度浮点数。范围是[-6万, +6万],能精确到十进制的小数点后 3.3 位。
            //fixed:11位低精度浮点数。范围是[-2, 2],精度是 1/256 ≈ 0.004
            //都何以组合为向量或是矩阵比如 half3 fixed4 float4x4 等
            //颜色和单位向量,使用fixed 其他情况,尽量使用half;否则才使用float。

            //材质类型需要一条额外参数配置
            sampler2D _XXXX;
            float4 _XXXX_ST;

            //uniform 在UnityShader中可以省略
            uniform fixed3 XX;
            fixed XXX;

            //程序传给定点着色器的数据
            struct a2v
            {
                //类型 名字 : 绑定的语义(从哪里读取数据,把数据输出到哪里)
                //常见语义如下 
                float4 vertex : POSITION; //顶点的位置
                float4 normal : NORMAL; //顶点的法线方向
                float4 tangent : TANGENT; //顶点的切线方向
                fixed4 color : COLOR; //顶点的颜色
                float2 uvn : TEXCOORDn; //n从0开始,第n+1套纹理坐标
            };

            //定点着色器给片元着色器的数据
            //经由顶点着色器的输出进行插值运算得出
            struct v2f
            {
                float4 vertex : SV_POSITION; //必须有,有固定含义,表名裁剪空间的定点坐标
                float4 custom : TEXCOORDn; //n:0~7 无固定含义 用来做一些自定义数据的传递
            };

            v2f vert (a2v v)
            {
                v2f o;
                ... ...
                return o;
            }

            //SV_Target 即 SystemValue_RenderTarget
            fixed4 frag (v2f i) : SV_Target
            {
                ... ...
                //最终的结果是一个颜色 带一个alpha值
                return fixed4(baseCol, alpha);
            }
            ENDCG
        }
    }

    //可选 备用shader
    FallBack "Diffuse"
    //当本Shader的所有SubShader都不支持当前显卡,就会使用FallBack语句指定的另一个Shader。
    //FallBack最好指定Unity自己预制的Shader实现,因其一般能够在当前所有显卡运行。
    // FallBack Off //将关闭FallBack

    //可选 自定义编辑器
    CustomEditor "CustomShaderGUI类名"
}
posted @ 2017-04-17 16:45  Hichy  阅读(654)  评论(0编辑  收藏  举报