《Unity Shader入门精要》读书笔记02
第 3 章 Unity Shader 基础
Unity Shader 简化了开发者管理着色器代码以及渲染设置的方式,不需要管理多个文件和函数。 (它不是真的 Shader 文件)
Unity Shader 装在 材质(Material) 上,材质再赋给要渲染的对象。
在 Unity 2022.3.52f1c1 的 3D(Built-In Render Pipeline) 中,Shader 的类型有 Standard Surface Shader;Unlit Shader;Image Effect Shader;Compute Shader;Ray Tracing Shader。
Unity Shader 的导入面板
- Default Maps 中可以指定该 Unity Shader 使用的默认纹理。当任何材质第一次使用该Unity Shader 时,这些纹理就会自动被赋予到相应的属性上。
- 通过单击 Show generated code 按钮来打开一个新的文件,在该文件里将显示Unity在背后为该表面着色器生成的顶点/片元着色器。
- Compile and show code下拉列表可以让开发者检查该Unity Shader针对不同图像编程接口(例如OpenGL、D3D9、D3D11等)最终编译成的 Shader 代码,直接单击该按钮可以查看生成的底层的汇编指令。我们可以利用这些代码来分析和优化着色器。
ShaderLab
ShaderLab 是 Unity 提供的编写 Unity Shader 的一种说明性语言。类似于 CgFX 和 Direct3D Effects ( .FX ) 语言,它们都定义了要显示一个材质所需的所有东西 , 而**不仅仅是着色器代码 **。
Unity Shader 的结构
1 | Shader "ShaderName"{ |
名字
Shader "Custom/MyShader { }
这样写,该 Unity Shader 在材质面板中的位置就是:Shader->Custom->MyShader。
Properties
属性(property)
1 | Properties { |
如果我们需要在 Shader 中访问它们,就需要使用每个属性的名字 (Name)。在 Unity 中,这些属性的名字通常由一个下划线开始。显示的 名称 (display name) 则是出现在材质面板上的名字。我们需要为每个属性指定它的 类型 (PropertyType)
- Unity允许我们重载默认的材质编辑面板,以提供更多自定义的数据类型。
- 即使我们不在Properties语义块中声明这些属性,也可以直接在CG代码片中定义变量。Properties语义块的作用仅仅是为了让这些属性可以出现在材质面板中。
SubShader
每一个UnityShader文件可以包含多个SubShader语义块,但最少要有一个。
一个SubShader中包含多个Pass(渲染通道),是为了将一个复杂的视觉效果“分步骤”地渲染到同一个物体上。
1 | SubShader { |
- 状态设置,常见有Cull,ZTest,ZWrite,Blend
- 标签:键值对,告诉 Unity 的渲染引擎如何以及何时渲染这个对象
- Pass 语义块
1 | Pass{ |
- 我们可以使用 ShaderLab 的 UsePass 命令来直接使用其他 UnityShader 中的 Pass。例如:
UsePass "MyShader/MYPASSNAME"
[!NOTE]
由于Unity内部会把所有Pass的名称转换成大写字母的表示,因此,在使用UsePass命令时必须使用大写形式的名字。
- GrabPass: 该 Pass 负责抓取屏称并将结果存储在一张纹理中,以用于后续的 Pass 处理
Fallback
“如果上面所有的 SubShader 在这块显卡上都不能运行 ,那么就使用这个最低级的 Shader 吧!”
- 语义:
Fallback"name"' 或者 'Fallback Off - 事实上,Fallback还会影响阴影的投射。在渲染阴影纹理时,Unity会在每个 UnityShader 中寻找一个阴影投射的Pass。通常情况下,我们不需要自已专门实现一个Pass,这是因为 Fallback 使用的内置 Shader 中包含了这样一个通用的 Pass。
Unity Shader 的形式
3 种形式
表面着色器(Surface Shader)
- 表面着色器被定义在 SubShader 语义块(而非 Pass 语义块)中的 CGPROGRAM 和 ENDCG 之间。开发者只需要告诉它:“,使用这些纹理去填充颜色,使用这个法线纹理去填充法线,使用Lambert光照模型,其他的不要来烦我!”
- CGPROGRAM和ENDCG之间的代码是使用CG/HLSL编写的,和标准的 CG/HLSL 语法几乎一样。
顶点/片元着色器(Vertex/Fragment Shader)
- 定义在 Pass 语义块中的 CGPROGRAM 和 ENDCG 之间。
- 要写的代码比表面着色器多,但是更灵活。
固定函数着色器(Fixed Function Shader)
- old-time
- 使用 ShaderLab 的渲染设置命令。
[!NOTE] 如果想用GLSL?
建立在你坚持要用GLSL来写UnityShader的意愿下,你可以怎么写呢?和CG/HLSL需要嵌套在CGPROGRAM和ENDCG之间类似,GLSL的代码需要嵌套在GLSLPROGRAM和ENDGLSL之间。
- 标题: 《Unity Shader入门精要》读书笔记02
- 作者: 铁名_IronName
- 创建于 : 2026-01-12 11:22:07
- 更新于 : 2026-01-15 15:26:11
- 链接: https://blog.ironname.top/2026/01/12/《Unity-Shader入门精要》读书笔记02/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。