《Unity Shader入门精要》笔记:初级篇(1)

  3.2 游戏引擎技术
  • 本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载。
  • 本篇博客会补充一些扩展内容(例如其他博客链接)
  • 篇博客还会提供一些边读边做的效果截图。文章内所有数学公式都由Latex在线编辑器生成。
  • 篇博客主要提供一个“glance”,知识点的总结。如有需要请到书店购买正版。
  • 博客提及所有官方文档基于2022.2版本,博客会更新一些书中的旧的知识点到2022.2版本。
  • 如有不对之处欢迎指正。
  • 我创建了一个游戏制作交流群:637959304 进群密码:(CSGO的拆包密码)欢迎各位大佬一起学习交流,不限于任何平台(U3D、UE、COCO2dx、GamesMaker等),以及欢迎编程,美术,音乐等游戏相关的任何人员一起进群学习交流。

  • 初级篇内容主要讲述关于基础的光照模型、纹理和透视等的初级渲染效果。(这部分也可以同时阅读我的HLSL博客内容进行学习)

UnityShader入门

  • 最简单的顶点/片元着色器:
Shader "name"
{
        Properties
        {
                //属性
        }

        SubShader
        {
                Pass
                {
                        //设置渲染状态和标签
                        //开始CG代码片段
                        CGPROGRAM
                        //编译指令
                        #pragma vertex vert
                        #pragma fragment frag

                        //CG代码

                        ENDCG
                        //其他设置
                }
                //其他pass
        }
        //其他的SubShader

        //如果SubShader都失败了
        Fallback “VertexLit”
}
  • 第一个代码
  • 关于’:’语法,可以理解为一种限制,或条件。例如: SV_POSITION是限制函数只能输出裁剪空间的坐标,也可以换一种角度理解,限制->通知,告知Unity要输出的是裁剪空间坐标。
shader "Example/Shader01"
{
        SubShader
        {
                Pass
                {
//CG代码片段
                        CGPROGRAM
//告诉Unity哪个函数包含了顶点着色器代码,哪个函数包含片元着色器代码
                        #pragma vertex vert
                        #pragma fragment frag
//POSITION把顶点坐标填入到V中,SV_POSITION顶点着色器输出的是裁剪空间中的坐标
                        float4 vert(float 4 v : POSITION) : SV_POSITION
                        {
                                return mul (UNITY_MATRIX_MVP,v);
                        
                        }

                        fixed4 frag() : SV_Target
                        {
                                return fixed4(1.0,1.0,1.0,1.0);
                        }
                        ENDCG
                }
        }
 }
image 137 - 《Unity Shader入门精要》笔记:初级篇(1)
材质,Shader
image 138 - 《Unity Shader入门精要》笔记:初级篇(1)
游戏内物体(CUBE)
image 139 - 《Unity Shader入门精要》笔记:初级篇(1)
效果
  • 活学活用: return fixed4(1.0,1.0,0.5,1.0);时的效果。有时候要刷新一下材质才能显示出效果。
image 140 - 《Unity Shader入门精要》笔记:初级篇(1)
image 141 - 《Unity Shader入门精要》笔记:初级篇(1)
  • 注意有一条语句语法进行了更新:Upgrade NOTE: replaced ‘mul(UNITY_MATRIX_MVP,*)’ with ‘UnityObjectToClipPos(*)’
  • 我们利用结构体来存储模型的法线,纹理坐标等信息。
Pass
{
        CGPROGRAM

        #pragma vertex vert
        #pragma fragment frag
//输入结构体
        struct a2v
        {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
        };
//输出结构体
        struct v2f
        {
//裁剪信息
                float4 pos : SV_POSITION;
//颜色信息
                fixed3 color : COLOR0;
        };

        v2f vert(a2v v)
        {
                v2f o;

                o.pos = UnityObjectToClipPos(v.vertex.xyz);
//根据法线向量v.normal来改变颜色
                o.color = v.normal * 0.5 + fixed3(0.5,0.5,0.5);
                 return o;
        }

        fixed4 frag(v2f i) : SV_Target
        {
                return fixed4(i.color,1.0);
                }
        ENDCG
}
image 142 - 《Unity Shader入门精要》笔记:初级篇(1)
image 143 - 《Unity Shader入门精要》笔记:初级篇(1)
你别说还蛮好看的
  • 属性设置:设置一个颜色的properties让用户自定义颜色。
shader "Example/Shader01"
{
//自定义用户面板
    Properties
    {
        _Color ("Color Tint",Color) = (1.0,1.0,1.0,1.0)
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            fixed4 _Color;

            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                fixed3 color : COLOR0;
            };

            v2f vert(a2v v)
            {
                v2f o;

                o.pos = UnityObjectToClipPos(v.vertex.xyz);
                o.color = v.normal * 0.5 + fixed3(0.5,0.5,0.5);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 c = i.color;
//让用户面板中的颜色来决定顶点输出的颜色
                c *= _Color.rgb;
                return fixed4(c,1.0);
            }
            ENDCG
        }
    }
}
image 145 1024x439 - 《Unity Shader入门精要》笔记:初级篇(1)
  • ShaderLab属性类型和CG变量类型的匹配关系
ShaderLab属性类型CG变量类型
Color,Vectorfloat4,half4,fixed4
Range,Floatfloat,half,fixed
2Dsampler2D
CubesamplerCube
3Dsampler3D
  • 数值类型:精度范围在不同平台可能会略有不同
类型精度
float32位
half16位,范围:+-60 000
fixed11位,范围:+-2.0
  • Unity内置文件和变量传送门,UnityShader提供了一些内置文件(具体见官方手册),可以不适用include进行头文件包含,Unity会自动加安策处理。
  • 内置着色器变量:传送门
image 146 - 《Unity Shader入门精要》笔记:初级篇(1)
  • CG/HLSL语义:语义可以让Shader知道从哪里读取数据(例如:COLOR0)。即使语义相同,位置不同表达的意思也会不同。DirectX10以后新的语义类型:系统数值语义(system-value semantics),以SV为开头,代表系统数值。有些时候(例如POSITION和SV_POSITION)语义可以不加SV开头,但如果考虑跨平台的工程,那么最好在能加SV的地方把SV加上去。
  • 从应用阶段传递模型数据给顶点着色器时的常用语义:
语义描述
POSITION模型空间顶点位置,float4
NORAML顶点法线,float3
TANGENT顶点切线,float4
TEXCOORD0-7寄存器类似于,存放坐标等。float2或float4
COLOR顶点颜色,fixed4或float4
image 147 1024x164 - 《Unity Shader入门精要》笔记:初级篇(1)
  • 从顶点着色器传递数据给片元着色器时的常用语义:
语义描述
SV_POSITION裁剪空间中的顶点坐标,必要语义
COLOR0、COLOR1通常用于输出第一、二组顶点颜色
TEXCOORD0-7通常用语输出纹理坐标
  • 片元着色器输出时的常用语义
语义描述
SV_Target输出值存储到渲染目标中,等同于DirectX9中的COLOR
  • 调试:Unity中自带UnityShader的调试,在Windows->Analysis->Frame Debugger中(与书中当时的位置稍有不同)。如果想要看到更多的信息,可以在VS等IDE中寻找相关插件。
image 148 - 《Unity Shader入门精要》笔记:初级篇(1)
image 149 - 《Unity Shader入门精要》笔记:初级篇(1)

  • 额外补充-代码数学规范:
    1、规范化语法
    2、避免不必要的计算
    3、慎用分支和循环语句(因为开销大)
    4、不要除以0

LEAVE A COMMENT