Unity Shader 超详细教程:从入门到精通
目录
-
第一部分:基础入门
(图片来源网络,侵删)- 第 1 章:Shader 是什么?为什么需要它?
- 第 2 章:Unity 中的 Shader 资源
- 第 3 章:Shader 的三种核心类型
- 第 4 章:你的第一个 Shader:创建与基础结构
- 第 5 章:理解 CG/HLSL 代码块
-
第二部分:ShaderLab 与核心概念
- 第 6 章:Properties - 定义 Shader 的可调参数
- 第 7 章:SubShader - 核心渲染逻辑
- 第 8 章:Pass - 渲染通道详解
- 第 9 章:FallBack - 兼容性保障
-
第三部分:编写基础 Shader
- 第 10 章:基础漫反射光照
- 第 11 章:基础高光光照
- 第 12 章:纹理贴图
- 第 13 章:透明度与混合模式
-
第四部分:高级 Shader 开发
- 第 14 章:光照模型
- 第 15 章:法线贴图
- 第 16 章:遮罩与细节贴图
- 第 17 章:顶点修改与动画
-
第五部分:实战与资源
(图片来源网络,侵删)- 第 18 章:实战项目:卡通风格 Shader
- 第 19 章:实战项目:水墨画风格 Shader
- 第 20 章:Shader 资源推荐与学习路径
第一部分:基础入门
第 1 章:Shader 是什么?为什么需要它?
想象一下,一个 3D 模型只是一个空壳,它本身没有颜色、光泽或质感。Shader (着色器) 就是一套指令,告诉 GPU (图形处理器) 如何计算这个模型表面每个像素的颜色、亮度、反光等视觉属性。
为什么需要 Shader?
- 控制视觉效果:Shader 是实现独特艺术风格的核心,无论是金属、玻璃、皮肤、卡通还是水,其外观都由 Shader 决定。
- 高性能:Shader 直接运行在 GPU 上,专门为并行计算设计,可以实现非常复杂的视觉效果,同时保持流畅的帧率。
- 程序化生成:可以通过数学函数和算法动态生成纹理和效果,无需为每种情况都制作一张贴图。
第 2 章:Unity 中的 Shader 资源
在 Unity 中,Shader 文件是一个以 .shader 为后缀的文本文件,它通常包含两个主要部分:
- ShaderLab:Unity 提供的一种高级语言,用于定义 Shader 的结构、属性、渲染状态(如是否开启深度测试、混合模式等),它更像是“配置文件”。
- CG/HLSL 代码块:嵌入在 ShaderLab 中的代码,使用 C 语言的变体 (C for Graphics) 来编写真正的像素和顶点计算逻辑,这是 Shader 的“心脏”。
第 3 章:Shader 的三种核心类型
Unity 主要提供三种类型的 Shader,它们代表了不同的抽象层次:

-
Surface Shader (表面着色器)
- 特点:最高级、最简单的类型,你只需要关注光照模型(如何计算颜色),Unity 会自动为你处理所有复杂的光照计算、阴影、投影等。
- 用途:适用于大多数需要与 Unity 内置光照系统交互的材质,如皮肤、木头、金属等。
- 缺点:灵活性较低,不适合后处理效果或完全自定义的渲染管线。
-
Vertex/Fragment Shader (顶点/片元着色器)
- 特点:中级类型,你需要手动编写顶点着色器(处理顶点位置、法线等)和片元着色器(处理每个像素的颜色),你需要自己处理光照,但可以完全控制渲染过程。
- 用途:当 Surface Shader 无法满足需求时,例如实现卡通描边、自定义的非真实感渲染、复杂的扭曲效果等。
-
Fixed Function Shader (固定功能着色器)
- 特点:最底层、最古老的类型,它不包含任何 CG/HLSL 代码,仅通过 ShaderLab 的指令来模拟旧显卡的固定功能渲染管线。
- 用途:几乎不用于新项目,主要用于兼容非常古老的硬件,了解它有助于理解 Shader 的历史。
学习建议:从 Surface Shader 开始,因为它能让你快速理解光照和材质的基本原理,当你需要更灵活的控制时,再转向 Vertex/Fragment Shader。
第 4 章:你的第一个 Shader:创建与基础结构
- 创建 Shader:在 Project 窗口中右键 -> Create -> Shader -> Standard Surface Shader,这会生成一个基于 PBR 的 Surface Shader。
- 创建材质:右键 -> Create -> Material,并将你创建的 Shader 拖拽到这个材质上。
- Shader 文件结构:打开
.shader文件,你会看到类似下面的结构:
Shader "Custom/MyFirstShader" // Shader 的路径和名称
{
Properties // 定义在材质面板上可调整的属性
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader // 定义一套渲染规则
{
Tags { "RenderType"="Opaque" } // 标签,告诉渲染器如何处理这个Shader
CGPROGRAM // CG代码块的开始
#pragma surface surf Standard fullforwardshadows // 指令:使用surf函数,标准光照模型,支持阴影
sampler2D _MainTex; // 声明一个与Properties中同名的变量
struct Input // 输入结构,surf函数会用到
{
float2 uv_MainTex; // 接收模型的UV坐标
};
void surf (Input IN, inout SurfaceOutputStandard o) // surf函数,核心逻辑
{
// 从纹理中采样颜色
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb; // 设置漫反射颜色
o.Metallic = 0.0; // 设置金属度
o.Smoothness = 0.5; // 设置平滑度
o.Alpha = c.a; // 设置透明度
}
ENDCG // CG代码块的结束
}
FallBack "Diffuse" // 如果SubShader不支持,则回退到这个Shader
}
第 5 章:理解 CG/HLSL 代码块
CGPROGRAM 和 ENDCG 之间的代码是着色器的核心,它使用类似 C 的语法。
#pragma surface surf Standard fullforwardshadows:这是一个编译指令,告诉 Unity 如何处理这段代码。surface surf:指定使用名为surf的函数作为表面着色函数。Standard:指定使用 Unity 的标准 PBR 光照模型。fullforwardshadows:支持所有正向渲染的阴影。
struct Input:定义了传递给surf函数的数据。float2 uv_MainTex是最常用的,它包含了模型表面的 UV 坐标。void surf (...):这是你编写像素颜色计算逻辑的地方。o.Albedo决定了物体在光照下的基础颜色,o.Metallic和o.Smoothness决定了材质的金属感和粗糙度。
第二部分:ShaderLab 与核心概念
第 6 章:Properties - 定义 Shader 的可调参数
Properties 块定义了材质面板上可以显示和调整的变量。
Properties
{
_Color ("Color Tint", Color) = (1,1,1,1) // 颜色属性
_MainTex ("Base (RGB)", 2D) = "white" {} // 2D纹理
_MySlider ("Slider Range", Range(0, 1)) = 0.5 // 滑块,范围0-1
_MyFloat ("Float", Float) = 1.0 // 浮点数
_MyToggle ("Toggle", Int) = 0 // 整数,用于开关
}
这些属性在 CG 代码块中需要被重新声明才能使用,fixed4 _Color;。
第 7 章:SubShader - 核心渲染逻辑
一个 Shader 文件可以包含多个 SubShader,Unity 会从上到下选择第一个能在当前设备上运行的 SubShader,这使得你可以为不同性能的设备编写不同的渲染版本。
`
