【Shader】【知识点查找】

目录

  • 官方文档
  • Tag
    • SubShaderd 标签
      • Queue
      • RenderType
      • lgnoreProjector
    • Pass标签
      • ColorMask
      • LightMode
  • RenderSetup
    • Cull
    • ZTest
    • ZWrite
    • Blend
    • LOD:Level of Detail
  • 常用类型
  • float half fixed区别
  • 常用数学方法
  • 语义
  • 五种空间
  • 常用属性
  • UnityCG.cginc中常用函数
  • Lighting.cginc中常用
    • 用法
    • 属性
  • 内置宏
  • 光照模型
    • 工具
    • 兰伯特光照
      • 漫反射(逐顶点漫反射)
      • 漫反射(逐片元漫反射)
    • 半兰伯特光照模型
    • 高光反射(Blinn光照模型)
      • 逐像素高光光照模型
    • Blinn-Phong光照模型
  • 更新记录

官方文档

官方解释

Tag

SubShaderd 标签

Queue

控制渲染顺序,指定该物体属于哪 个渲染队列,通过Queue 这种方式可以保证所有的透明物体可以在所有不透明物体后面被渲染 ,我们也可以自定义使用的渲染队列来控制物体的渲染顺序

名称 队列索引号 描述
Background 1000 这个渲染队列会在任何其他队列之前被渲染,我们通常使用该队列来渲染那些需要绘制在背景上的物体
Geometry 2000 默认的渲染队列,大多数物体都在使用这个队列,不透明物体使用这个队列
AlphaTest 2450 需要透明度测试的物体使用这个队列,在Unity 5之后它从Geometry队列中被单独分出来,这是因为在所有不透明物体渲染之后再渲染它们会更加高效
Transparent 3000 这个队列中的物体会在所有Geometry和AlphaTest物体渲染后,再按从后往前的顺序进行渲染。任何使用了透明度混合(例如关闭了深度写入的Shader)的物体都应该使用该队列
Overlay 4000 该队列用于实现一些叠加效果,任何需要再最后渲染的物体都应该使用该队列

RenderType

对着色器进行分类,例如这是一个不透明的着色器,或是一个透明的着色器等。可以被用于着色器替换(Shader Replacement)功能

名称 说明
Opaque 大部分着色器(发现,自发光,反射和地形着色器)
Transparent 大部分半透明着色器(透明,粒子,字体和地形附加通道着色器)
TransparentCutout 遮罩透明着色器(透明镂空,两个通道植被着色器)
Background 天空盒着色器
Overlay 光环,光晕着色器
TreeOpaque 地形引擎树皮
TreeTransparentCutout 地形引擎树叶
TreeBillboard 地形引擎公告牌树
Grass 地形引擎草
GrassBillboard 地形引擎公告牌草

lgnoreProjector

如果该标签值为 “True” 那么使用该 SubShader 的物体将不会受 Projector(投影器) 的影响。通常用于半透明物体

状态名称 功能
True 不受Projector(投影器)影响
False 受到Projector(投影器)影响

Pass标签

ColorMask

用于设置颜色通道的写掩码

状态用法 解释
ColorMask R
ColorMask G
ColorMask B
ColorMask A
ColorMask 0 意味着该Pass不写入任何颜色通道,即不会输出任何颜色

LightMode

定义该Pass再Unity的渲染流水线中的角色

状态名称 功能
Always 不管使用哪种渲染路径,该Pass总是会被渲染,但不会计算任何光照
ForwardBase 用于前向渲染。该Pass会计算环境光,最重要的平行光,逐顶点/SH光源和Lightmaps
Forward Add 用于前向渲染。该Pass会计算额外的逐像素光源,每个Pass对应一个光源
Deferred 用于延迟渲染。该Pass会渲染G缓冲(G-buffer)
ShadowCaster 把物体的深度信息渲染到阴影映射纹理(shadowmap)或一张深度纹理中
PrepassBase 用于遗留的延迟渲染。该Pass会渲染法线和高光反射的指数部分
PrepassFinal 用于遗留的延迟渲染。该Pass通过合并纹理,光照和自发光来渲染得到最后的颜色
Vertex,VertexLMRGBM和VertexLM 用于遗留的顶点照明渲染

RenderSetup

Cull

背面剔除状态

状态名称 功能
Cull Back 剔除背面
Cull Front 剔除正面
Cull Off 关闭剔除

ZTest

深度测试

状态名称 功能
ZTest Less Greatern
ZTest LEqual
ZTest GEqual
ZTest Equal
ZTest NotEqual
ZTest Always

ZWrite

深度写入

状态名称 功能
ZWrite On 开启深度写入
ZWrite Off 关闭深度写入

Blend

混合模式

  • 目标颜色:颜色缓冲中读取到的颜色值

  • 源颜色:指的是片元着色器产生的颜色值

    状态名称| 功能
    -------- | -----
    Blend Off|关闭混合
    Blend Srcfactor Dstfactor|开启混合,并设置混合因子,源颜色(该片元产生的颜色)会乘以SrcFactor,而目标颜色(已经存在于颜色缓存的颜色)会乘以DstFactor,然后把两者相加后再存入颜色缓冲中。
    Blend SrcFactor DstFactor,SrcFactorA DstFactorA|和上面几乎一样,只是使用不同的因子来混合透明通道
    BlendOp BlendOperation|并非是把源颜色和目标颜色简单相加后混合,而是使用BlendOperation对它们进行其他操作

LOD:Level of Detail

Unity选择对应的Subshader会从上往下寻找第一个小于等于LOD值的子着色器。一个着色器中会有一到多个SubShader,但是系统每次只会执行一个子着色器,选择子着色器的标准就是根据子着色器所设置的LOD的值来进行选择。

this.shader.maximumLOD = 600;

常用类型

  • _Color(“Color”,Color) = (1,1,1,1)
  • _Vector(“Vector”,Vector) = (1,2,3,4)
  • _Int(“Int”,Int) = 123
  • _Float(“Float”,Float) = 1.2
  • _Range(“_Range”,Range(1,10)) = 6
  • _2D(“Texture”,2D) = “red”{}
  • _Cube(“Cube”,Cube) = “white”{}
  • _3D(“Cube”,3D) = “black”{}

float half fixed区别

  • float

32位来存储

  • half

16位 -6万 ~ +6万

  • fixed

11位 -2 ~ +2

常用数学方法

  • normalize()

向量单位化

  • max()

用来取得函数中最大的一个值

  • dot()

取得两个向量的点乘

  • pow(a,b)

a的b次方

语义

  • 从应用程序传递到顶点函数的语义(a2v)
    • POSITION 顶点坐标(模型空间)
    • NORMAl 法线(模型空间)
    • TANGENT 切线(模型空间)
    • TEXCOORD0~n 纹理坐标
      COLOR 顶点颜色
  • 从顶点函数传递给片元函数的语义(v2f)
    • SV_POSITION 剪裁空间中的顶点坐标(一般是系统直接使用)
    • CLOLOR0 可以传递一组值 4个
    • COLOR1 可以传递一组值 4个
    • TEXCOORD0~7 传递纹理坐标
  • 从片元函数传递给系统
    • SV_TARGET 颜色值,显示到屏幕上的颜色

五种空间

  • 模型空间
  • 世界空间
  • 观察空间
  • 裁剪空间
    以下为个人理解,大佬请绕道

模型空间:建模时在模型空间进行,模型自带的坐标均为模型空间下的表示
世界空间:理解为从Game窗口看到的空间
观察空间:以摄像机位置为原点,摄像机局部坐标轴为坐标轴的坐标系
裁剪空间:视锥体所在的空间
屏幕空间:理解为从Game窗口看到的空间

常用属性

  1. _WorldSpaceCameraPos

(视野)像机的位置

UnityCG.cginc中常用函数

  1. float3 WorldSpaceViewDir(float4 v)

​ 根据模型空间中的顶点坐标,得到(世界空间)从这个点到摄像机观察的方向

  1. float3 UnityWorldSpaceViewDir(float4 v)

世界空间中的顶点坐标==》 世界空间从这个点到摄像机的观察方向

  1. float3 ObjSpaceViewDir(float4 v)

模型空间中的顶点坐标==》模型空间中从这个颠倒摄像机的观察方向

  1. float3 WorldSpaceLightDir(float4 v)

模型空间中的顶点坐标==》世界空间中从这个点到光源的方向

  1. float3 UnityWorldSpaceLightDir(float 4)

世界空间中的顶点坐标==》世界空间中从这个点到光源的方向

  1. float4 ObjSpaceLightDir(float4 v)

模型空间中的顶点坐标==》模型空间中从这个点到光源的方向

  1. float3 UnityObjectToWorldNormal(float3 norm)

把法线方向 模型空间==》世界空间

  1. float3 UnityObjectToWorldDir(float3 dir)

把方向 模型空间==》世界空间

  1. float3 UnityWorldToObjectDir(float dir)

把方向 世界空间==》 模型空间

  1. float4 UnityObjectToClipPos(float4 v)

模型空间到剪裁空间的转换

Lighting.cginc中常用

用法

Tag{“LightMode”==“ForwardBase”}
#include “Lighting.cginc”

属性

  1. _LightColor0

取得第一个平行光的颜色

2._WorldSpaceLightPos0

第一个直射光的位置

内置宏

  1. UNITY_LIGHTMODEL_AMBIENT.rgb

Unity内置宏,获取环境光

光照模型

计算公式:Diffuse = 直射光颜色*max(0,cos夹角) cos夹角 = 光方向 ·法线方向(因为是单位向量)

工具

公式参考
曲线绘制

兰伯特光照

漫反射(逐顶点漫反射)

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

Shader "ShaderStudy/DiffuseReflection"
{
    Properties
    {
        _Diffuess("Color",Color) = (1,1,1,1)
    }
        SubShader
    {


        Pass
        {
            Tags{ "LightMode" = "ForwardBase" }
            CGPROGRAM

            fixed3 _Diffuess;

            #pragma vertex vert
            #pragma fragment frag
    // make fog work
    #pragma multi_compile_fog

    #include "UnityCG.cginc"
    #include "Lighting.cginc"
    struct appdata
    {
        float4 vertex : POSITION;
        float2 normal : NORMAL;
    };

    struct v2f
    {
        float4 position:SV_POSITION;
        fixed3 color : COLOR;
    };

    v2f vert(appdata v)
    {
        v2f f;
        f.position = UnityObjectToClipPos(v.vertex); //模型空间到剪裁空间的转换

        fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; //Unity内置宏,获取环境光

        fixed3 normalDir = normalize(mul(v.normal,(float3x3)unity_WorldToObject));
        fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
        fixed3 diffuse = _LightColor0.rgb * _Diffuess.rgb * max(dot(normalDir,lightDir),0);
        f.color = diffuse + ambient;

        return f;
    }

    fixed4 frag(v2f f) : SV_Target
    {

        return fixed4(f.color,1);
    }
    ENDCG
}
    }
}

漫反射(逐片元漫反射)

Shader "Unlit/2"
{
    Properties
    {
        _Diffuse("Diffuse",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal:NORMAL;
            };

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

            fixed4 _Diffuse;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex); //模型空间顶点到剪裁空间顶点的转换

                fixed3 normalDir = normalize(UnityObjectToWorldNormal(v.normal));
                o.color = normalDir;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; //Unity内置宏,获取环境光

                fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);

                fixed3 diffuse = _LightColor0.rgb *_Diffuse.rgb* max(0,dot(i.color,lightDir));

                return fixed4(diffuse+ambient,1);
            }
            ENDCG
        }
    }
}

半兰伯特光照模型

计算公式:Diffuse = 直射光颜色max(0,cos夹角0.5+0.5) cos夹角 = 光方向 ·法线方向(因为是单位向量)
代码如下0.5+0.5即可

高光反射(Blinn光照模型)

逐像素高光光照模型

计算公式:Diffuse = 直射光颜色*pow(max(0,cos夹角),高光参数(一般10)) 夹角 = 反射光方向 ·视野方向(因为是单位向量)

Shader "StudyShader/SpecularReflection"
{
   Properties
    {
        _Diffuse("Diffuse",Color) = (1,1,1,1)
        _SpecularColor("SpecularColor",Color) = (1,1,1,1)
        _Gloss("Gloss",Range(8,200)) = 10
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal:NORMAL;
            };

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

            fixed4 _Diffuse;
            fixed4 _SpecularColor;
            half _Gloss;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex); //模型空间顶点到剪裁空间顶点的转换

                fixed3 normalDir = normalize(UnityObjectToWorldNormal(v.normal));
                o.color = normalDir;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; //Unity内置宏,获取环境光

                fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);

                fixed3 diffuse = _LightColor0.rgb *_Diffuse.rgb* max(0,dot(i.color,lightDir)*0.5+0.5);

                fixed3 reflectDir = normalize(reflect(-lightDir,i.color)); //求得反射光的方向

                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-WorldSpaceViewDir(i.vertex));

                fixed3 specular = _LightColor0.rgb*_SpecularColor.rgb*pow(max(dot(viewDir,reflectDir),0),_Gloss);

                return fixed4(diffuse+ambient+specular,1);
            }
            ENDCG
        }
    }
}


Blinn-Phong光照模型

计算公式:Blinn-Phong = 直射光颜色*pow(max(0,cos夹角),高光参数(一般10)) ;夹角 = 是法线和x的夹角 ;x是平行光和视野方向的平行线

Shader "StudyShader/SpecularReflection" //Blinn-Phong
{
   Properties
    {
        _Diffuse("Diffuse",Color) = (1,1,1,1)
        _SpecularColor("SpecularColor",Color) = (1,1,1,1)
        _Gloss("Gloss",Range(8,200)) = 10
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal:NORMAL;
            };

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

            fixed4 _Diffuse;
            fixed4 _SpecularColor;
            half _Gloss;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex); //模型空间顶点到剪裁空间顶点的转换

                fixed3 normalDir = normalize(UnityObjectToWorldNormal(v.normal));
                o.color = normalDir;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb; //Unity内置宏,获取环境光

                fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); //平行光方向

                fixed3 diffuse = _LightColor0.rgb *_Diffuse.rgb* max(0,dot(i.color,lightDir)*0.5+0.5); // 漫反射

                fixed3 reflectDir = normalize(reflect(-lightDir,i.color)); //求得反射光的方向

                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-WorldSpaceViewDir(i.vertex)); //视野方向

                fixed3 bisector = normalize(viewDir+lightDir); //平分线方向 相加即可

                fixed3 specular = _LightColor0.rgb*_SpecularColor.rgb*pow(max(dot(i.color,bisector),0),_Gloss);

                return fixed4(diffuse+ambient+specular,1);
            }
            ENDCG
        }
    }
}

更新记录

  • 2023/3/7 更新一些内容
  • 2023/3/10 整合之前的文章

你可能感兴趣的:(Shader,unity,游戏开发)