第2.1章:YAML配置详解

CCEffect是Cocos Shader系统的核心配置部分,采用YAML语法定义着色器的渲染技术、通道和属性。本章将深入讲解CCEffect配置的各个方面,帮你掌握着色器配置的精髓。

🎯 学习目标

通过本章学习,你将掌握:

  • CCEffect配置的基本语法和结构
  • 渲染技术(techniques)的配置方法
  • 渲染通道(passes)的详细设置
  • 材质属性(properties)的定义规则
  • 渲染状态和混合模式的配置

💡 CCEffect基本结构

整体架构

CCEffect采用层次化的配置结构,从上到下分为:技术→通道→程序

1
2
3
4
5
6
7
8
9
10
CCEffect:
techniques: # 渲染技术数组
- name: opaque # 技术名称
passes: # 渲染通道数组
- vert: vs-main # 顶点着色器
frag: fs-main # 片元着色器
properties: # 材质属性
# 属性定义
migrations: # 版本迁移配置
# 迁移规则

基础配置示例

1
2
3
4
5
6
7
8
9
10
11
CCEffect:
techniques:
- name: opaque
passes:
- vert: standard-vs
frag: standard-fs
properties: &props
mainTexture: { value: white }
mainColor: { value: [1, 1, 1, 1] }
metallic: { value: 0.0 }
roughness: { value: 0.5 }

🛠️ 渲染技术(Techniques)配置

技术定义

渲染技术定义了不同的渲染方式,常见的技术包括:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
techniques:
# 不透明物体渲染
- name: opaque
passes:
- vert: standard-vs
frag: opaque-fs

# 透明物体渲染
- name: transparent
passes:
- vert: standard-vs
frag: transparent-fs
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha

# 阴影渲染
- name: shadow-caster
passes:
- vert: shadow-vs
frag: shadow-fs
rasterizerState:
cullMode: front

技术选择机制

Cocos Creator会根据材质设置和渲染条件自动选择合适的技术:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 系统会根据以下条件选择技术:
# 1. 材质的透明度设置
# 2. 当前渲染管线
# 3. 光照条件
# 4. 平台特性
techniques:
- name: opaque
# 用于不透明物体的标准渲染

- name: transparent
# 用于需要混合的透明物体

- name: cutout
# 用于Alpha测试的透明物体

🎨 渲染通道(Passes)配置

基本通道配置

每个渲染通道定义了一次完整的渲染过程:

1
2
3
4
5
6
7
8
9
passes:
- vert: vertex-shader-name # 顶点着色器名称
frag: fragment-shader-name # 片元着色器名称
properties: &props # 材质属性引用
# 属性定义
phase: forward # 渲染阶段
embeddedMacros: # 内嵌宏定义
USE_TEXTURE: true
propertyIndex: 0 # 属性索引

渲染状态配置

深度状态(DepthStencilState)

1
2
3
4
5
6
7
8
9
passes:
- vert: vs-main
frag: fs-main
depthStencilState:
depthTest: true # 启用深度测试
depthWrite: true # 启用深度写入
depthFunc: less # 深度比较函数
stencilTestFront: false # 前面模板测试
stencilTestBack: false # 背面模板测试

光栅化状态(RasterizerState)

1
2
3
4
5
6
7
8
passes:
- vert: vs-main
frag: fs-main
rasterizerState:
cullMode: back # 背面剔除
polygonMode: fill # 多边形填充模式
shadeModel: gourand # 着色模式
lineWidth: 1.0 # 线宽

混合状态(BlendState)

1
2
3
4
5
6
7
8
9
10
11
12
13
passes:
- vert: vs-main
frag: fs-main
blendState:
targets:
- blend: true # 启用混合
blendSrc: src_alpha # 源混合因子
blendDst: one_minus_src_alpha # 目标混合因子
blendSrcAlpha: one # 源Alpha混合因子
blendDstAlpha: one_minus_src_alpha # 目标Alpha混合因子
blendEq: add # 混合方程
blendAlphaEq: add # Alpha混合方程
colorMask: all # 颜色通道掩码

常用混合模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 标准Alpha混合(透明)
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha

# 加法混合(发光效果)
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one

# 乘法混合(阴影效果)
blendState:
targets:
- blend: true
blendSrc: dst_color
blendDst: zero

# 屏幕混合(高亮效果)
blendState:
targets:
- blend: true
blendSrc: one_minus_dst_color
blendDst: one

🔧 材质属性(Properties)定义

基本属性类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
properties:
# 纹理属性
mainTexture:
value: white # 默认值(内置纹理)
editor:
displayName: "主纹理" # 编辑器显示名称
type: texture # 编辑器类型
tooltip: "物体的主要纹理贴图" # 工具提示

# 颜色属性
mainColor:
value: [1, 1, 1, 1] # 默认RGBA值
editor:
type: color # 颜色选择器
tooltip: "物体的主要颜色"

# 浮点数属性
metallic:
value: 0.0 # 默认值
range: [0, 1] # 取值范围
editor:
slide: true # 滑动条控件
tooltip: "金属度"

# 向量属性
tilingOffset:
value: [1, 1, 0, 0] # [tilingX, tilingY, offsetX, offsetY]
editor:
tooltip: "纹理的平铺和偏移"

高级属性配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
properties:
# 分组属性
groupProperty:
value: 1.0
editor:
group: "材质参数" # 属性分组
tooltip: "分组中的属性"

# 条件属性
normalTexture:
value: normal
editor:
parent: USE_NORMAL_MAP # 父级条件
tooltip: "法线贴图"

# 枚举属性
blendMode:
value: 0
editor:
inspector: enum
options:
- "Normal"
- "Additive"
- "Multiply"
- "Screen"
tooltip: "混合模式选择"

# 布尔属性
enableFeature:
value: false
editor:
inspector: boolean
tooltip: "启用特殊功能"

属性引用和继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CCEffect:
techniques:
# 定义共享属性
- name: opaque
passes:
- vert: vs-main
frag: fs-opaque
properties: &sharedProps
mainTexture: { value: white }
mainColor: { value: [1, 1, 1, 1] }
metallic: { value: 0.0 }
roughness: { value: 0.5 }

# 透明技术引用共享属性
- name: transparent
passes:
- vert: vs-main
frag: fs-transparent
properties: *sharedProps # 引用共享属性
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha

📚 高级配置特性

版本迁移(Migrations)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CCEffect:
techniques:
# ... 技术定义

migrations:
# 从版本1.0迁移到2.0
- version: "2.0"
upgrade: |
// 属性重命名
this.properties.mainColor = this.properties.oldColor || [1, 1, 1, 1];
delete this.properties.oldColor;

// 新增属性
this.properties.roughness = this.properties.roughness || 0.5;

# 从版本2.0迁移到3.0
- version: "3.0"
upgrade: |
// 纹理格式升级
if (this.properties.mainTexture === 'old-format') {
this.properties.mainTexture = 'new-format';
}

动态宏定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
passes:
- vert: vs-main
frag: fs-main
# 嵌入宏定义
embeddedMacros:
USE_TEXTURE: true
MAX_LIGHTS: 8
QUALITY_LEVEL: 2

# 动态宏(运行时可修改)
dynamics:
- name: USE_NORMAL_MAP
type: boolean
value: false
- name: SHADOW_QUALITY
type: number
value: 1
range: [0, 3]

条件编译配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
passes:
- vert: vs-main
frag: fs-main
properties:
# 基础属性
mainTexture: { value: white }
mainColor: { value: [1, 1, 1, 1] }

# 条件属性(仅在启用法线贴图时显示)
normalTexture:
value: normal
editor:
parent: USE_NORMAL_MAP

normalScale:
value: 1.0
range: [0, 2]
editor:
parent: USE_NORMAL_MAP
slide: true

💡 实际应用示例

PBR材质配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
CCEffect:
techniques:
- name: opaque
passes:
- vert: pbr-vs
frag: pbr-fs
properties: &pbrProps
# 基础属性
albedoMap: { value: white }
albedoColor: { value: [1, 1, 1, 1], editor: { type: color } }

# PBR属性
metallicMap: { value: white }
metallic: { value: 0.0, range: [0, 1], editor: { slide: true } }

roughnessMap: { value: white }
roughness: { value: 0.5, range: [0, 1], editor: { slide: true } }

# 法线贴图
normalMap: { value: normal, editor: { parent: USE_NORMAL_MAP } }
normalScale: { value: 1.0, range: [0, 2], editor: { parent: USE_NORMAL_MAP, slide: true } }

# 环境遮蔽
aoMap: { value: white, editor: { parent: USE_AO_MAP } }
aoIntensity: { value: 1.0, range: [0, 1], editor: { parent: USE_AO_MAP, slide: true } }

dynamics:
- name: USE_NORMAL_MAP
type: boolean
value: false
- name: USE_AO_MAP
type: boolean
value: false

- name: transparent
passes:
- vert: pbr-vs
frag: pbr-fs
properties: *pbrProps
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha

卡通着色器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
CCEffect:
techniques:
- name: opaque
passes:
- vert: toon-vs
frag: toon-fs
properties:
# 基础纹理
mainTexture: { value: white }
mainColor: { value: [1, 1, 1, 1], editor: { type: color } }

# 卡通化参数
shadowColor: { value: [0.5, 0.5, 0.5, 1], editor: { type: color } }
shadowThreshold: { value: 0.5, range: [0, 1], editor: { slide: true } }
shadowSmooth: { value: 0.1, range: [0, 1], editor: { slide: true } }

# 描边参数
outlineWidth: { value: 0.01, range: [0, 0.1], editor: { slide: true, parent: USE_OUTLINE } }
outlineColor: { value: [0, 0, 0, 1], editor: { type: color, parent: USE_OUTLINE } }

dynamics:
- name: USE_OUTLINE
type: boolean
value: false

# 描边通道
- name: outline
passes:
- vert: outline-vs
frag: outline-fs
rasterizerState:
cullMode: front
properties:
outlineWidth: { value: 0.01 }
outlineColor: { value: [0, 0, 0, 1] }

📝 配置最佳实践

1. 属性组织

1
2
3
4
5
6
7
8
9
10
11
12
13
properties:
# 按功能分组组织属性
# --- 基础材质 ---
mainTexture: { value: white, editor: { group: "基础材质" } }
mainColor: { value: [1, 1, 1, 1], editor: { group: "基础材质", type: color } }

# --- PBR参数 ---
metallic: { value: 0.0, editor: { group: "PBR参数", slide: true } }
roughness: { value: 0.5, editor: { group: "PBR参数", slide: true } }

# --- 高级选项 ---
normalMap: { value: normal, editor: { group: "高级选项", parent: USE_NORMAL_MAP } }
emissionMap: { value: black, editor: { group: "高级选项", parent: USE_EMISSION } }

2. 性能优化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
techniques:
# 低质量版本(移动端)
- name: opaque-low
passes:
- vert: simple-vs
frag: simple-fs
embeddedMacros:
QUALITY_LEVEL: 0
MAX_LIGHTS: 4

# 高质量版本(桌面端)
- name: opaque-high
passes:
- vert: advanced-vs
frag: advanced-fs
embeddedMacros:
QUALITY_LEVEL: 2
MAX_LIGHTS: 16
ENABLE_SHADOWS: true

3. 平台适配

1
2
3
4
5
6
7
8
9
10
11
passes:
- vert: vs-main
frag: fs-main
# 根据平台调整精度
embeddedMacros:
PRECISION_LEVEL: |
#ifdef GL_ES
mediump
#else
highp
#endif

📚 小结

本章深入介绍了CCEffect的YAML配置:

  • CCEffect采用层次化结构:技术→通道→程序
  • 渲染技术定义不同的渲染方式和条件
  • 渲染通道配置具体的渲染状态和参数
  • 材质属性系统支持丰富的类型和编辑器集成
  • 高级特性包括版本迁移、动态宏、条件编译等

掌握YAML配置是开发高质量着色器的重要基础,接下来我们将学习GLSL语法的详细内容。

下一章: 第2.2章:GLSL基础语法

💡 学习建议

  1. 从简单开始:先掌握基本的technique和pass配置
  2. 实验属性:尝试不同的属性类型和编辑器选项
  3. 理解渲染状态:深入了解混合模式和深度测试
  4. 参考内置:查看引擎内置着色器的配置方式

🔗 参考资源

继续学习,你将成为Cocos Shader配置专家!