第1.3章:Cocos Shader语法详解
Cocos Shader采用了独特的YAML + GLSL混合语法,本章将深入介绍Cocos Shader的语法结构、编写规则和最佳实践,为后续的着色器开发打下坚实基础。
🎯 学习目标
通过本章学习,你将掌握:
- Cocos Shader的整体语法结构
- CCEffect配置的详细语法
- CCProgram着色器程序的编写规则
- 属性定义和传递机制
- 内置函数和宏的使用方法
🏗️ Cocos Shader整体结构
基本文件结构
Cocos Shader文件(.effect)由三个主要部分组成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| CCEffect: techniques: - name: opaque passes: - vert: vs-main frag: fs-main properties:
CCProgram vs-main %{ // GLSL顶点着色器代码 }%
CCProgram fs-main %{ // GLSL片元着色器代码 }%
|
语法特点
- YAML配置语法:用于定义渲染状态和属性
- CCProgram语法:用于编写GLSL着色器代码
- 预处理器支持:支持条件编译和宏定义
- 内置函数库:提供丰富的工具函数
📋 CCEffect配置详解
Techniques技术配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| CCEffect: techniques: - name: opaque passes: - vert: vs-main frag: fs-main phase: forward priority: 128 stage: default - name: transparent passes: - vert: vs-main frag: fs-main phase: forward priority: 256 blendState: targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha
|
Pass渲染通道配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| passes: - vert: vertex-shader-name frag: fragment-shader-name rasterizerState: cullMode: back depthStencilState: depthTest: true depthWrite: true blendState: targets: - blend: true blendSrc: src_alpha blendDst: one_minus_src_alpha dynamics: - name: CC_USE_HDR type: number value: 0
|
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
| properties: mainTexture: value: white editor: tooltip: "主纹理" tintColor: value: [1, 1, 1, 1] editor: type: color tooltip: "着色颜色" intensity: value: 1.0 range: [0, 5.0] editor: slide: true tooltip: "强度" offset: value: [0, 0] editor: tooltip: "偏移量"
|
🔧 CCProgram着色器程序
顶点着色器基本结构
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
| CCProgram vs-main %{ precision highp float; #include <builtin/uniforms/cc-global> #include <builtin/uniforms/cc-local> in vec3 a_position; in vec3 a_normal; in vec2 a_texCoord; in vec4 a_color; out vec3 v_worldPos; out vec3 v_worldNormal; out vec2 v_uv; out vec4 v_color; vec4 vert() { vec4 worldPos = cc_matWorld * vec4(a_position, 1.0); v_worldPos = worldPos.xyz; v_worldNormal = normalize((cc_matWorldIT * vec4(a_normal, 0.0)).xyz); v_uv = a_texCoord; v_color = a_color; return cc_matViewProj * worldPos; } }%
|
片元着色器基本结构
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
| CCProgram fs-main %{ precision highp float; #include <builtin/uniforms/cc-global> #include <builtin/functions/common> in vec3 v_worldPos; in vec3 v_worldNormal; in vec2 v_uv; in vec4 v_color; uniform sampler2D mainTexture; uniform Properties { vec4 tintColor; float intensity; vec2 offset; }; vec4 frag() { vec2 uv = v_uv + offset; vec4 texColor = texture(mainTexture, uv); vec4 finalColor = texColor * v_color * tintColor; finalColor.rgb *= intensity; return finalColor; } }%
|
🎨 属性系统详解
属性类型支持
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
| properties: floatValue: value: 1.0 range: [0, 10] intValue: value: 5 range: [0, 100] vec2Value: value: [0.5, 0.5] vec3Value: value: [1, 1, 1] vec4Value: value: [1, 1, 1, 1] colorValue: value: [1, 0, 0, 1] editor: type: color textureValue: value: white editor: tooltip: "纹理属性" boolValue: value: true editor: inspector: boolean
|
编辑器集成
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
| properties: sliderValue: value: 0.5 range: [0, 1] editor: slide: true tooltip: "滑动条控制" enumValue: value: 0 editor: inspector: enum options: - "选项1" - "选项2" - "选项3" groupedValue: value: 1.0 editor: group: "材质参数" tooltip: "分组属性"
|
🔍 内置函数和宏
常用内置函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| CCProgram common-functions %{ float smoothstep(float edge0, float edge1, float x); float clamp(float x, float minVal, float maxVal); float mix(float x, float y, float a); float dot(vec3 x, vec3 y); vec3 cross(vec3 x, vec3 y); float length(vec3 x); vec3 normalize(vec3 x); vec4 texture(sampler2D sampler, vec2 coord); vec4 textureLod(sampler2D sampler, vec2 coord, float lod); vec4 matrixTransform(mat4 matrix, vec4 position); }%
|
内置宏定义
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
| #ifdef GL_ES precision mediump float; #else precision highp float; #endif
#ifdef CC_USE_HDR #endif
#ifdef CC_USE_IBL #endif
#define PI 3.14159265359 #define TWO_PI 6.28318530718 #define HALF_PI 1.57079632679
#define TRANSFORM_TEX(tex, name) (tex.xy * name##_ST.xy + name##_ST.zw)
|
💡 高级语法特性
条件编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| CCProgram conditional-compile %{ precision highp float; #define QUALITY_LOW 0 #define QUALITY_MEDIUM 1 #define QUALITY_HIGH 2 #ifndef QUALITY_LEVEL #define QUALITY_LEVEL QUALITY_MEDIUM #endif vec4 frag() { #if QUALITY_LEVEL == QUALITY_LOW return vec4(1.0, 0.0, 0.0, 1.0); #elif QUALITY_LEVEL == QUALITY_MEDIUM return vec4(0.0, 1.0, 0.0, 1.0); #else return vec4(0.0, 0.0, 1.0, 1.0); #endif } }%
|
Include机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| float remap(float value, float oldMin, float oldMax, float newMin, float newMax) { return newMin + (value - oldMin) * (newMax - newMin) / (oldMax - oldMin); }
vec3 rgb2hsv(vec3 c) { }
CCProgram main-shader %{ #include <common/math-utils> vec4 frag() { float remappedValue = remap(input, 0.0, 1.0, -1.0, 1.0); return vec4(remappedValue); } }%
|
🎮 实际应用示例
完整的Unlit着色器
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 45 46 47 48 49 50 51 52 53 54
| CCEffect %{ techniques: - name: opaque passes: - vert: unlit-vs frag: unlit-fs properties: &props mainTexture: { value: white } tintColor: { value: [1, 1, 1, 1], editor: { type: color } } alphaThreshold: { value: 0.5, range: [0, 1] } }%
CCProgram unlit-vs %{ precision highp float; in vec3 a_position; in vec2 a_texCoord; out vec2 v_uv; vec4 vert() { vec4 position = vec4(a_position, 1); position = cc_matWorld * position; v_uv = a_texCoord; return cc_matViewProj * position; } }%
CCProgram unlit-fs %{ precision highp float; in vec2 v_uv; uniform sampler2D mainTexture; uniform Properties { vec4 tintColor; float alphaThreshold; }; vec4 frag() { vec4 col = texture(mainTexture, v_uv); col *= tintColor; // Alpha测试 if (col.a < alphaThreshold) { discard; } return col; } }%
|
📝 语法规范和最佳实践
命名规范
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| in vec3 a_position; in vec2 a_texCoord;
out vec2 v_uv; out vec3 v_worldPos;
uniform float u_time; uniform sampler2D mainTexture;
#define MAX_LIGHT_COUNT 8 #define PI 3.14159265359
|
性能优化建议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| precision mediump float;
vec4 frag() { vec4 col = texture(mainTexture, v_uv); if (col.a < 0.1) discard; }
float result = mix(a, b, t);
|
🔧 调试技巧
可视化调试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #define DEBUG_MODE 0
#if DEBUG_MODE == 1 return vec4(v_uv, 0.0, 1.0); #elif DEBUG_MODE == 2 return vec4(v_normal * 0.5 + 0.5, 1.0); #elif DEBUG_MODE == 3 return v_color; #else return finalColor; #endif
|
分步验证
1 2 3 4 5 6 7 8 9 10 11 12
| vec4 frag() { vec4 texColor = texture(mainTexture, v_uv); float NdotL = max(0.0, dot(v_normal, lightDir)); return texColor * NdotL; }
|
📚 小结
本章详细介绍了Cocos Shader的语法结构:
- CCEffect配置定义渲染技术和属性
- CCProgram包含GLSL着色器代码
- 丰富的属性系统支持各种数据类型
- 内置函数和宏简化开发工作
- 条件编译和Include机制提高代码复用性
掌握了基础语法后,接下来我们将学习如何创建和使用自定义着色器。
下一章: 第2.1章:YAML配置详解
💡 学习建议
- 循序渐进:先理解整体结构,再深入细节
- 动手实践:每个语法点都要通过代码验证
- 参考示例:多看内置着色器的实现
- 调试练习:学会使用调试技巧排查问题
🔗 参考资源
继续你的Cocos Shader学习之旅!