unity shader入门精要_Unity Shader 入门(二):shader 基础

unity shader入门精要_Unity Shader 入门(二):shader 基础_第1张图片

一、参考与说明(需要写在开始东西):

1.1 Unity Shader 入门精要学习

https://github.com/candycat1992/Unity_Shaders_Book/tree/unity_5_4​github.com

1.2 写在开头,最近一直在关注渲染方面的文章,越看越发现,还是自下而上的学习路线比较好,了解背景原理,学习上层知识才更容易。但也确实发现,一头扎进去很容易迷茫,要学的要看的东西太多,现实也有各种原因,需要你快速直接的实现一些效果。这也是unity shader的好处,Unity在底层做了很多事情,我们只需要编写简单的代码,就可以看到效果,而且也有很多官方的shader案例,可以供我们参考。我想这大概也是作者想做的事情,让大家可以先有能力读懂shader代码,就像文字和词组的组合可以创造出很多不同的文章,但是学习还是要从文字开始,后面就要看大家的想象力了。同时又时间和能力的话,还是要保持对底层原理的学习,内功修炼要持久。

二、shader背景

我相信学习unity shader 大家一定听到过很多专业名词,比如:hlsl,glsl,cg,surfaceshader,vertex shader, fragment shader等等,我想还是有必要做个解释的。unity shader 支持如下三种语法:

  1. glsl -- OpenGL ShadingLanguage (基于OpenGL)
  2. hlsl -- High Level Shading Language (基于DirectX)
  3. cg -- C for Graphic (基于NVIDIA)

其中hlsl和cg比较常用,surfaceshader这个看了渲染管线可以知道,shader并没有surfaceshader,unity 也一样,支持 vertex fragment shader, surfaceshader是对顶点片段shader的上层封装,致力于让大家写shader更简单,不过本篇文章还是以顶点片段为主。unity 创建shader时包括一下几个模板选项

  1. Standard Surface Shader -- 顶点片段的封装 表面着色器
  2. Unlit Shader -- 用于修改顶点片段着色器
  3. Image Effect Shader -- 用于屏幕后处理着色器
  4. Compute Shader -- 用于处理并行运算(GPGPU)
  5. Ray Tracing Shader -- 光线追踪

三、Unlit Shader(顶点片段着色器) 语法

下面就是unity 创建的Unlit Shader .

  1. 开头 Shader 后面引号内的就是 shader 的名称及路径
  2. Properties 为属性,在材质球inspector面板中是可见的,下面为Properties 中支持类型
name ("display name", Range (min, max)) = number
name ("display name", Color) = (number,number,number,number)
name ("display name", 2D) = "name" { options }
name ("display name", Rect) = "name" { options }
name ("display name", Cube) = "name" { options }
name ("display name", Float) = number
name ("display name", Vector) = (number,number,number,number)

3. SubShader 为具体执行逻辑的部分 ,可以有多个SubShader,顺序执行,从上到下寻找并使用终端所能支持的第一个SubShader,
4.Tags 标签,标记一些属性, 且可不写,tags还分在SubShader中和Pass中两类

4.1 语法 Tags{ "TagName1" = "Value1" "TagName2" = "Value2"} 4.2 SubShader Tags 官方地址
1.Queue 控制渲染顺序,指定该物体属于哪一个渲染队列
2.RenderType 对着色器分类。例如:这是一个不透明着色器
3.DisableBatching 可以用该标签直接表明是否使用批处理
4.ForecNoShadowCasting 控制该SubShader的物体是否会投射阴影
5.IgnoreProjector 设置该SubShader的物体是否受Projector影响,
6.CanUseSpriteAtlas 当该SubShader用于“sprite”时,将该标签设为False
7.PriviewType 材质面板的预览类型,一般默认材质预览效果是球形
4.3 Pass Tags 官方地址
1.LightModel 定义该Pass在渲染管线中的角色
2.RequireOption 用于指定满足某些条件是才渲染该
3.PassFlags 一个pass可以用一个标志表明改变渲染流水线是怎么样传递数据给pass的

5. Pass,具体shader的实现部分,SubShader可以有多个Pass,但是多pass也会增加DrawCall,所以一般建议一到两个pass

5.1 语义 参考博客
Unity支持的语义:
1,从应用阶段传递模型数据给顶点着色器时支持的语义如下表

语义 描述
POSITION 模型空间中的顶点位置 通常float4
NORMAL 顶点法线 通常float3
TANGENT 顶点切线 通常float4
TEXCOORD(n) 该顶点的纹理坐标 n组
COLOR 顶点颜色 通常fixed4 float4

2,丛顶点着色器传递到片元着色器时支持的语义如下表:

语义 描述
SV_POSITION 裁剪空间中的顶点坐标 结构体必须包含一个该词修饰的变量
COLOR0 通常用于输出第一组顶点颜色
COLOR1 通常用于输出第二组顶点颜色
TEXCOORDN(0~7) 通常用于输出纹理坐标

3,片元着色器输出时支持的语义

语义 描述
SV_Target 输出值将会存储到渲染目标中

数据类型的对比:

类型 精度
float 最高精度 通常32位
half 中等精度 通常16位
fixed 最低精度 通常11位

5.2 HLSL和CG语法在unity shader中要包裹在CGPROGRAM 和 ENDCG之间,中间我们可以添加 顶点和片段函数,其中他们的参数就包括上面的语义,让系统知道参数代表了什么,以及是如何传递的。
5.3 #include "UnityCG.cginc" 引用文件 ,unity自带的很多方法都在这个文件中,如各种矩阵投影转换等,这个文件大家可以在官网中下载对应版本的 Built-in Shader,观察其中代码,官方地址

Shader "Unlit/VertexFragmentShader"  //名称
{ 
    Properties //属性集合
    {
        _MainTex ("Texture", 2D) = "white" {} //语法_MainTex 为字段名称,Texture为面板显示名称,
                                              //2D是类型,white是初始值,特别注意,定义属性后需
                                              //要在Pass中声明此属性
    }
    SubShader //子shader
    {
        Tags { "RenderType"="Opaque" }

        Pass //Pass通道
        {
            CGPROGRAM  // HLSL和CG语法在unity shader中要包裹在CGPROGRAM 和 ENDCG之间
            #pragma vertex vert  //指定顶点函数
            #pragma fragment frag  //指定片段函数

            #include "UnityCG.cginc" //引用文件  

            struct appdata  //顶点函数输入
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f //片段函数输入  和 顶点函数输出
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v) //顶点函数
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target //片段函数
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

四、总结

shader的学习是有难度的,里面的实现又包含各种数学算法等,猛的进去,会有一头雾水的感觉,所以,本篇文章希望以顶点片段着色器的整体语法框架入手,让大家可以看懂shader,就比如一个房子,我们不知道里面有什么东西,多么的华丽,但是我们知道房子要有门、窗户、墙、厕所啊、厨房啊等等,厨房是做饭的,看到vertex 也可以知道是处理顶点的,那么,我们想知道具体做的什么饭,怎么处理的顶点就可以找到对应的地方深入的学习了,毕竟unity shader实现的效果,网上是可以找到很多的,甚至可以用shader graph去连线,然后自己再去用代码实现。

你可能感兴趣的:(unity,shader入门精要)