第7.4章:高级宏编程技术

高级宏编程是Cocos Shader开发中的强大工具,它允许我们实现代码生成、元编程和复杂的逻辑控制。本章将深入探讨宏编程的高级技巧,帮助你构建更加灵活和强大的着色器系统。

🎯 学习目标

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

  • 多层级宏定义和复杂宏结构
  • 宏与Include系统的深度集成
  • 跨平台兼容性的宏处理策略
  • 大型项目中的宏管理和架构设计
  • 元编程技巧和代码生成模式

💡 高级宏编程基础

多层级宏定义

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
// 第一层:基础功能�?#define FEATURE_LIGHTING        1
#define FEATURE_SHADOWS 2
#define FEATURE_REFLECTIONS 4
#define FEATURE_TRANSPARENCY 8
#define FEATURE_ANIMATION 16
#define FEATURE_LOD 32

// 第二层:功能组合�?#define PRESET_BASIC (FEATURE_LIGHTING)
#define PRESET_STANDARD (FEATURE_LIGHTING | FEATURE_SHADOWS)
#define PRESET_ADVANCED (FEATURE_LIGHTING | FEATURE_SHADOWS | FEATURE_REFLECTIONS)
#define PRESET_PREMIUM (FEATURE_LIGHTING | FEATURE_SHADOWS | FEATURE_REFLECTIONS | FEATURE_TRANSPARENCY)
#define PRESET_ULTRA (0xFFFFFFFF) // 所有功�?
// 第三层:平台特定�?#ifdef CC_PLATFORM_MOBILE
#define MOBILE_PRESET_BASIC (FEATURE_LIGHTING)
#define MOBILE_PRESET_STANDARD (FEATURE_LIGHTING | FEATURE_SHADOWS)
#define MOBILE_PRESET_HIGH (FEATURE_LIGHTING | FEATURE_SHADOWS | FEATURE_LOD)
#endif

#ifdef CC_PLATFORM_DESKTOP
#define DESKTOP_PRESET_BASIC PRESET_STANDARD
#define DESKTOP_PRESET_STANDARD PRESET_ADVANCED
#define DESKTOP_PRESET_HIGH PRESET_PREMIUM
#define DESKTOP_PRESET_ULTRA PRESET_ULTRA
#endif

// 第四层:智能选择�?#ifdef CC_PLATFORM_MOBILE
#ifndef SHADER_FEATURES
#define SHADER_FEATURES MOBILE_PRESET_STANDARD
#endif
#else
#ifndef SHADER_FEATURES
#define SHADER_FEATURES DESKTOP_PRESET_STANDARD
#endif
#endif

// 功能检测宏
#define HAS_FEATURE(feature) ((SHADER_FEATURES & (feature)) != 0)
#define REQUIRE_FEATURE(feature) static_assert(HAS_FEATURE(feature), "Required feature not enabled")

递归宏和宏函数链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 递归宏示例:数组初始�?#define INIT_ARRAY_1(type, name, v0) type name[1] = {v0}
#define INIT_ARRAY_2(type, name, v0, v1) type name[2] = {v0, v1}
#define INIT_ARRAY_4(type, name, v0, v1, v2, v3) type name[4] = {v0, v1, v2, v3}
#define INIT_ARRAY_8(type, name, v0, v1, v2, v3, v4, v5, v6, v7) \
type name[8] = {v0, v1, v2, v3, v4, v5, v6, v7}

// 宏函数链:光照计�?#define LIGHT_ATTENUATION(distance, range) (1.0 / (1.0 + distance * distance / (range * range)))
#define LIGHT_SPOT_FACTOR(lightDir, spotDir, spotAngle) \
pow(max(dot(-lightDir, spotDir), 0.0), spotAngle)
#define LIGHT_SHADOW_FACTOR(shadowCoord) texture(shadowMap, shadowCoord.xy).r > shadowCoord.z ? 1.0 : 0.0

#define CALCULATE_SPOT_LIGHT(lightPos, lightDir, lightColor, lightRange, spotDir, spotAngle, \
worldPos, normal, shadowCoord) \
{ \
vec3 toLight = lightPos - worldPos; \
float distance = length(toLight); \
vec3 lightDirection = toLight / distance; \
float attenuation = LIGHT_ATTENUATION(distance, lightRange); \
float spotFactor = LIGHT_SPOT_FACTOR(lightDirection, spotDir, spotAngle); \
float shadowFactor = LIGHT_SHADOW_FACTOR(shadowCoord); \
float NdotL = max(dot(normal, lightDirection), 0.0); \
return lightColor * attenuation * spotFactor * shadowFactor * NdotL; \
}

条件编译的高级应�?

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 多条件嵌套宏
#define QUALITY_LEVEL_LOW 0
#define QUALITY_LEVEL_MEDIUM 1
#define QUALITY_LEVEL_HIGH 2
#define QUALITY_LEVEL_ULTRA 3

#define PLATFORM_MOBILE 0
#define PLATFORM_DESKTOP 1
#define PLATFORM_CONSOLE 2

// 复杂条件编译矩阵
#if defined(CC_PLATFORM_MOBILE)
#define CURRENT_PLATFORM PLATFORM_MOBILE

#if QUALITY_LEVEL >= QUALITY_LEVEL_MEDIUM
#define ENABLE_NORMAL_MAPPING 1
#define MAX_LIGHTS 4
#else
#define ENABLE_NORMAL_MAPPING 0
#define MAX_LIGHTS 1
#endif

#if QUALITY_LEVEL >= QUALITY_LEVEL_HIGH
#define ENABLE_SHADOWS 1
#define SHADOW_MAP_SIZE 1024
#else
#define ENABLE_SHADOWS 0
#define SHADOW_MAP_SIZE 512
#endif

#elif defined(CC_PLATFORM_DESKTOP)
#define CURRENT_PLATFORM PLATFORM_DESKTOP

#if QUALITY_LEVEL >= QUALITY_LEVEL_LOW
#define ENABLE_NORMAL_MAPPING 1
#define MAX_LIGHTS 8
#endif

#if QUALITY_LEVEL >= QUALITY_LEVEL_MEDIUM
#define ENABLE_SHADOWS 1
#define SHADOW_MAP_SIZE 2048
#endif

#if QUALITY_LEVEL >= QUALITY_LEVEL_HIGH
#define ENABLE_REFLECTIONS 1
#define ENABLE_SSAO 1
#endif

#if QUALITY_LEVEL >= QUALITY_LEVEL_ULTRA
#define ENABLE_GLOBAL_ILLUMINATION 1
#define ENABLE_VOLUMETRIC_LIGHTING 1
#endif

#else
// 默认配置
#define CURRENT_PLATFORM PLATFORM_DESKTOP
#define ENABLE_NORMAL_MAPPING 1
#define MAX_LIGHTS 4
#define ENABLE_SHADOWS 1
#define SHADOW_MAP_SIZE 1024
#endif

// 功能依赖检�?#if ENABLE_REFLECTIONS && !ENABLE_NORMAL_MAPPING
#error "Reflections require normal mapping to be enabled"
#endif

#if ENABLE_GLOBAL_ILLUMINATION && !ENABLE_SHADOWS
#error "Global illumination requires shadows to be enabled"
#endif

🔧 宏与Include系统集成

模块化Include架构

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
55
56
57
58
59
60
61
// 核心Include文件结构
// core/math.glsl
#ifndef SHADER_CORE_MATH_INCLUDED
#define SHADER_CORE_MATH_INCLUDED

#define PI 3.14159265359
#define TWO_PI (2.0 * PI)
#define HALF_PI (PI * 0.5)
#define INV_PI (1.0 / PI)

// 数学工具�?#define SATURATE(x) clamp(x, 0.0, 1.0)
#define LINEARSTEP(a, b, x) SATURATE(((x) - (a)) / ((b) - (a)))
#define SMOOTHERSTEP(x) ((x) * (x) * (3.0 - 2.0 * (x)))

#endif // SHADER_CORE_MATH_INCLUDED

// core/lighting.glsl
#ifndef SHADER_CORE_LIGHTING_INCLUDED
#define SHADER_CORE_LIGHTING_INCLUDED

#include "math.glsl"

// 光照计算�?#define LAMBERT_DIFFUSE(normal, lightDir) max(dot(normal, lightDir), 0.0)
#define PHONG_SPECULAR(reflectDir, viewDir, shininess) \
pow(max(dot(reflectDir, viewDir), 0.0), shininess)
#define BLINN_PHONG_SPECULAR(normal, halfDir, shininess) \
pow(max(dot(normal, halfDir), 0.0), shininess)

#if ENABLE_PBR
#include "pbr.glsl"
#endif

#endif // SHADER_CORE_LIGHTING_INCLUDED

// features/shadows.glsl
#ifndef SHADER_FEATURES_SHADOWS_INCLUDED
#define SHADER_FEATURES_SHADOWS_INCLUDED

#if ENABLE_SHADOWS

#include "../core/math.glsl"

// 阴影相关�?#define SHADOW_BIAS 0.001
#define PCF_KERNEL_SIZE 3

#define SAMPLE_SHADOW_PCF(shadowMap, shadowCoord, texelSize) \
{ \
float shadow = 0.0; \
for (int x = -1; x <= 1; x++) { \
for (int y = -1; y <= 1; y++) { \
vec2 offset = vec2(x, y) * texelSize; \
float depth = texture(shadowMap, shadowCoord.xy + offset).r; \
shadow += shadowCoord.z > depth + SHADOW_BIAS ? 0.0 : 1.0; \
} \
} \
shadow /= 9.0; \
}

#endif // ENABLE_SHADOWS

#endif // SHADER_FEATURES_SHADOWS_INCLUDED

动态Include选择

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
55
56
57
58
59
60
61
// 主着色器文件中的动态Include
CCProgram dynamic-shader %{

// 基础核心模块
#include <surface-fragment>

// 平台特定Include
#ifdef CC_PLATFORM_MOBILE
#include "mobile/optimizations.glsl"
#elif defined(CC_PLATFORM_WEBGL)
#include "webgl/compatibility.glsl"
#else
#include "desktop/advanced-features.glsl"
#endif

// 功能特定Include
#if HAS_FEATURE(FEATURE_LIGHTING)
#include "features/lighting.glsl"
#endif

#if HAS_FEATURE(FEATURE_SHADOWS)
#include "features/shadows.glsl"
#endif

#if HAS_FEATURE(FEATURE_REFLECTIONS)
#include "features/reflections.glsl"
#endif

#if HAS_FEATURE(FEATURE_ANIMATION)
#include "features/animation.glsl"
#endif

// 质量等级Include
#if QUALITY_LEVEL >= QUALITY_LEVEL_HIGH
#include "quality/high-quality.glsl"
#endif

#if QUALITY_LEVEL >= QUALITY_LEVEL_ULTRA
#include "quality/ultra-quality.glsl"
#endif

// 主Surface函数
void surf(in SurfaceIn In, inout SurfaceOut Out) {
// 使用动态Include中定义的功能
#if HAS_FEATURE(FEATURE_LIGHTING)
Out.albedo = calculateLighting(In, Out);
#else
Out.albedo = texture(mainTexture, In.uv);
#endif

#if HAS_FEATURE(FEATURE_SHADOWS)
float shadow = calculateShadow(In.shadowCoord);
Out.albedo.rgb *= shadow;
#endif

#if HAS_FEATURE(FEATURE_REFLECTIONS)
vec3 reflection = calculateReflection(In, Out);
Out.albedo.rgb += reflection;
#endif
}
}%

宏驱动的代码生成

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
// 代码生成宏系�?#define GENERATE_UNIFORM_PROPERTY(type, name, defaultValue) \
uniform type name; \
type get##name() { return name; } \
void set##name(type value) { name = value; }

#define GENERATE_TEXTURE_PROPERTY(name, index) \
uniform sampler2D name; \
uniform vec4 name##_ST; \
vec2 TRANSFORM_TEX_##name(vec2 uv) { \
return uv * name##_ST.xy + name##_ST.zw; \
} \
vec4 SAMPLE_TEXTURE_##name(vec2 uv) { \
return texture(name, TRANSFORM_TEX_##name(uv)); \
}

#define GENERATE_LIGHTING_FUNCTION(name, equation) \
vec3 calculate##name##Lighting(vec3 normal, vec3 lightDir, vec3 viewDir, \
vec3 lightColor, vec3 albedo) { \
return equation; \
}

// 使用代码生成�?GENERATE_UNIFORM_PROPERTY(float, roughness, 0.5)
GENERATE_UNIFORM_PROPERTY(float, metallic, 0.0)
GENERATE_UNIFORM_PROPERTY(vec3, tintColor, vec3(1.0))

GENERATE_TEXTURE_PROPERTY(mainTexture, 0)
GENERATE_TEXTURE_PROPERTY(normalTexture, 1)
GENERATE_TEXTURE_PROPERTY(roughnessTexture, 2)

GENERATE_LIGHTING_FUNCTION(Lambert,
albedo * lightColor * max(dot(normal, lightDir), 0.0))

GENERATE_LIGHTING_FUNCTION(BlinnPhong,
albedo * lightColor * max(dot(normal, lightDir), 0.0) +
lightColor * pow(max(dot(normalize(lightDir + viewDir), normal), 0.0), 32.0))

🎨 跨平台兼容性宏

平台检测和适配

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// 平台检测宏系统
#ifdef CC_PLATFORM_MOBILE
#define IS_MOBILE_PLATFORM 1
#define IS_DESKTOP_PLATFORM 0
#define IS_CONSOLE_PLATFORM 0
#elif defined(CC_PLATFORM_DESKTOP)
#define IS_MOBILE_PLATFORM 0
#define IS_DESKTOP_PLATFORM 1
#define IS_CONSOLE_PLATFORM 0
#elif defined(CC_PLATFORM_CONSOLE)
#define IS_MOBILE_PLATFORM 0
#define IS_DESKTOP_PLATFORM 0
#define IS_CONSOLE_PLATFORM 1
#else
#define IS_MOBILE_PLATFORM 0
#define IS_DESKTOP_PLATFORM 1
#define IS_CONSOLE_PLATFORM 0
#endif

// 图形API检�?#ifdef CC_USE_OPENGL
#define GRAPHICS_API_OPENGL 1
#define GRAPHICS_API_VULKAN 0
#define GRAPHICS_API_METAL 0
#define GRAPHICS_API_D3D11 0
#elif defined(CC_USE_VULKAN)
#define GRAPHICS_API_OPENGL 0
#define GRAPHICS_API_VULKAN 1
#define GRAPHICS_API_METAL 0
#define GRAPHICS_API_D3D11 0
#elif defined(CC_USE_METAL)
#define GRAPHICS_API_OPENGL 0
#define GRAPHICS_API_VULKAN 0
#define GRAPHICS_API_METAL 1
#define GRAPHICS_API_D3D11 0
#elif defined(CC_USE_D3D11)
#define GRAPHICS_API_OPENGL 0
#define GRAPHICS_API_VULKAN 0
#define GRAPHICS_API_METAL 0
#define GRAPHICS_API_D3D11 1
#endif

// 精度适配�?#if IS_MOBILE_PLATFORM
#define PRECISION_HIGH highp
#define PRECISION_MEDIUM mediump
#define PRECISION_LOW lowp
#define DEFAULT_PRECISION mediump
#else
#define PRECISION_HIGH
#define PRECISION_MEDIUM
#define PRECISION_LOW
#define DEFAULT_PRECISION
#endif

// 功能支持检�?#if GRAPHICS_API_OPENGL
#define SUPPORTS_TEXTURE_ARRAYS 1
#define SUPPORTS_COMPUTE_SHADERS 0
#define SUPPORTS_TESSELLATION 0
#elif GRAPHICS_API_VULKAN
#define SUPPORTS_TEXTURE_ARRAYS 1
#define SUPPORTS_COMPUTE_SHADERS 1
#define SUPPORTS_TESSELLATION 1
#elif GRAPHICS_API_METAL
#define SUPPORTS_TEXTURE_ARRAYS 1
#define SUPPORTS_COMPUTE_SHADERS 1
#define SUPPORTS_TESSELLATION 1
#elif GRAPHICS_API_D3D11
#define SUPPORTS_TEXTURE_ARRAYS 1
#define SUPPORTS_COMPUTE_SHADERS 1
#define SUPPORTS_TESSELLATION 1
#endif

兼容性包装宏

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
// API兼容性包�?#if GRAPHICS_API_OPENGL
#define TEXTURE_SAMPLE(tex, uv) texture(tex, uv)
#define TEXTURE_SAMPLE_LOD(tex, uv, lod) textureLod(tex, uv, lod)
#define TEXTURE_SIZE(tex, lod) textureSize(tex, lod)
#elif GRAPHICS_API_D3D11
#define TEXTURE_SAMPLE(tex, uv) tex.Sample(sampler, uv)
#define TEXTURE_SAMPLE_LOD(tex, uv, lod) tex.SampleLevel(sampler, uv, lod)
#define TEXTURE_SIZE(tex, lod) tex.GetDimensions()
#elif GRAPHICS_API_METAL
#define TEXTURE_SAMPLE(tex, uv) tex.sample(sampler, uv)
#define TEXTURE_SAMPLE_LOD(tex, uv, lod) tex.sample(sampler, uv, level(lod))
#define TEXTURE_SIZE(tex, lod) tex.get_width(lod), tex.get_height(lod)
#endif

// 数学函数兼容�?#if GRAPHICS_API_D3D11
#define FRACT(x) frac(x)
#define MIX(a, b, t) lerp(a, b, t)
#define STEP(edge, x) step(edge, x)
#else
#define FRACT(x) fract(x)
#define MIX(a, b, t) mix(a, b, t)
#define STEP(edge, x) step(edge, x)
#endif

// 属性兼容性宏
#if GRAPHICS_API_D3D11
#define VERTEX_INPUT_POSITION POSITION
#define VERTEX_INPUT_NORMAL NORMAL
#define VERTEX_INPUT_TEXCOORD TEXCOORD
#define VERTEX_OUTPUT_POSITION SV_Position
#else
#define VERTEX_INPUT_POSITION in_position
#define VERTEX_INPUT_NORMAL in_normal
#define VERTEX_INPUT_TEXCOORD in_texcoord
#define VERTEX_OUTPUT_POSITION gl_Position
#endif

性能优化�?

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
// 性能优化策略�?#if IS_MOBILE_PLATFORM
// 移动端优�? #define OPTIMIZE_FOR_MOBILE 1
#define USE_SIMPLIFIED_LIGHTING 1
#define MAX_LOOP_ITERATIONS 8
#define USE_FIXED_POINT_MATH 1

#define MOBILE_OPTIMIZE(mobile_code, desktop_code) mobile_code
#define PRECISION_OPTIMIZE(type) PRECISION_MEDIUM type

#else
// 桌面端优�? #define OPTIMIZE_FOR_MOBILE 0
#define USE_SIMPLIFIED_LIGHTING 0
#define MAX_LOOP_ITERATIONS 32
#define USE_FIXED_POINT_MATH 0

#define MOBILE_OPTIMIZE(mobile_code, desktop_code) desktop_code
#define PRECISION_OPTIMIZE(type) type

#endif

// 条件循环展开
#if MAX_LOOP_ITERATIONS <= 8
#define UNROLL_LOOP(code, var, count) \
if (count > 0) { int var = 0; code } \
if (count > 1) { int var = 1; code } \
if (count > 2) { int var = 2; code } \
if (count > 3) { int var = 3; code } \
if (count > 4) { int var = 4; code } \
if (count > 5) { int var = 5; code } \
if (count > 6) { int var = 6; code } \
if (count > 7) { int var = 7; code }
#else
#define UNROLL_LOOP(code, var, count) \
for (int var = 0; var < count; var++) { code }
#endif

// 精度优化�?#if USE_FIXED_POINT_MATH
#define FIXED_POINT_MULTIPLY(a, b) ((a * b) >> 16)
#define FIXED_POINT_DIVIDE(a, b) ((a << 16) / b)
#define FLOAT_TO_FIXED(f) int(f * 65536.0)
#define FIXED_TO_FLOAT(i) (float(i) / 65536.0)
#else
#define FIXED_POINT_MULTIPLY(a, b) (a * b)
#define FIXED_POINT_DIVIDE(a, b) (a / b)
#define FLOAT_TO_FIXED(f) f
#define FIXED_TO_FLOAT(i) i
#endif

🏗�?企业级宏架构设计

项目配置管理

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
// 项目配置文件:project_config.glsl
#ifndef PROJECT_CONFIG_INCLUDED
#define PROJECT_CONFIG_INCLUDED

// 项目信息
#define PROJECT_NAME "MyGameProject"
#define PROJECT_VERSION_MAJOR 1
#define PROJECT_VERSION_MINOR 2
#define PROJECT_VERSION_PATCH 0

// 目标平台配置
#define TARGET_PLATFORMS (PLATFORM_MOBILE | PLATFORM_DESKTOP)
#define MINIMUM_OPENGL_VERSION 330
#define MINIMUM_OPENGL_ES_VERSION 300

// 性能配置
#define DEFAULT_QUALITY_LEVEL QUALITY_LEVEL_MEDIUM
#define ENABLE_PERFORMANCE_PROFILING 1
#define ENABLE_DEBUG_VISUALIZATION 0

// 功能配置
#define ENABLE_ADVANCED_LIGHTING 1
#define ENABLE_DYNAMIC_SHADOWS 1
#define ENABLE_SCREEN_SPACE_REFLECTIONS 0
#define ENABLE_VOLUMETRIC_FOG 0
#define ENABLE_TEMPORAL_ANTI_ALIASING 1

// 资源配置
#define MAX_TEXTURE_SIZE 2048
#define MAX_SHADOW_MAP_SIZE 1024
#define MAX_REFLECTION_PROBES 8
#define MAX_LIGHTS_PER_OBJECT 4

#endif // PROJECT_CONFIG_INCLUDED

模块化宏系统

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
// 模块管理器:module_manager.glsl
#ifndef MODULE_MANAGER_INCLUDED
#define MODULE_MANAGER_INCLUDED

#include "project_config.glsl"

// 模块声明�?#define DECLARE_MODULE(name, version, dependencies) \
static const char* MODULE_##name##_NAME = #name; \
static const int MODULE_##name##_VERSION = version; \
static const char* MODULE_##name##_DEPENDENCIES = dependencies;

#define REQUIRE_MODULE(name, min_version) \
static_assert(MODULE_##name##_VERSION >= min_version, \
"Module " #name " version requirement not met");

// 模块声明
DECLARE_MODULE(Core, 100, "")
DECLARE_MODULE(Lighting, 200, "Core:100")
DECLARE_MODULE(Shadows, 150, "Core:100,Lighting:200")
DECLARE_MODULE(PostProcessing, 300, "Core:100")
DECLARE_MODULE(Animation, 120, "Core:100")

// 功能模块加载�?#define LOAD_MODULE(name) \
#if ENABLE_##name \
#include "modules/" #name ".glsl" \
REQUIRE_MODULE(name, MINIMUM_##name##_VERSION) \
#endif

// 条件模块加载
#if ENABLE_ADVANCED_LIGHTING
LOAD_MODULE(LIGHTING)
#if ENABLE_DYNAMIC_SHADOWS
LOAD_MODULE(SHADOWS)
#endif
#endif

#if ENABLE_SCREEN_SPACE_REFLECTIONS
LOAD_MODULE(POST_PROCESSING)
#endif

#endif // MODULE_MANAGER_INCLUDED

自动化测试宏

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
55
56
57
58
59
60
61
62
63
64
65
66
67
// 测试框架:test_framework.glsl
#ifndef TEST_FRAMEWORK_INCLUDED
#define TEST_FRAMEWORK_INCLUDED

#ifdef ENABLE_UNIT_TESTS

// 测试宏定�?#define TEST_EPSILON 0.001
#define TEST_ASSERT(condition, message) \
if (!(condition)) { \
logTestFailure(__FILE__, __LINE__, message); \
return false; \
}

#define TEST_ASSERT_NEAR(actual, expected, epsilon, message) \
if (abs(actual - expected) > epsilon) { \
logTestFailure(__FILE__, __LINE__, message); \
return false; \
}

#define TEST_CASE(name) \
bool test_##name() { \
logTestStart(#name);

#define TEST_END() \
logTestSuccess(); \
return true; \
}

// 测试用例示例
TEST_CASE(LightingCalculation)
vec3 normal = vec3(0, 1, 0);
vec3 lightDir = vec3(0, 1, 0);
vec3 expected = vec3(1, 1, 1);

vec3 result = calculateLighting(normal, lightDir, vec3(1), vec3(1));
TEST_ASSERT_NEAR(result.r, expected.r, TEST_EPSILON, "Red component mismatch");
TEST_ASSERT_NEAR(result.g, expected.g, TEST_EPSILON, "Green component mismatch");
TEST_ASSERT_NEAR(result.b, expected.b, TEST_EPSILON, "Blue component mismatch");
TEST_END()

TEST_CASE(ShadowCalculation)
vec4 shadowCoord = vec4(0.5, 0.5, 0.3, 1.0);
float expectedShadow = 1.0;

float actualShadow = calculateShadow(shadowCoord);
TEST_ASSERT_NEAR(actualShadow, expectedShadow, TEST_EPSILON, "Shadow calculation failed");
TEST_END()

// 测试套件运行器
#define RUN_ALL_TESTS() \
{ \
int passedTests = 0; \
int totalTests = 0; \
\
totalTests++; if (test_LightingCalculation()) passedTests++; \
totalTests++; if (test_ShadowCalculation()) passedTests++; \
\
logTestSummary(passedTests, totalTests); \
}

#else
#define TEST_CASE(name) void dummy_test_##name() {
#define TEST_END() }
#define RUN_ALL_TESTS()
#endif // ENABLE_UNIT_TESTS

#endif // TEST_FRAMEWORK_INCLUDED

版本管理和向后兼容

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
55
56
57
58
// 版本管理系统:version_manager.glsl
#ifndef VERSION_MANAGER_INCLUDED
#define VERSION_MANAGER_INCLUDED

// 引擎版本定义
#define CC_ENGINE_VERSION_3_8_0 380
#define CC_ENGINE_VERSION_3_8_1 381
#define CC_ENGINE_VERSION_3_8_2 382
#define CC_ENGINE_VERSION_3_9_0 390

#ifndef CC_ENGINE_VERSION
#define CC_ENGINE_VERSION CC_ENGINE_VERSION_3_8_0
#endif

// API兼容性宏
#if CC_ENGINE_VERSION >= CC_ENGINE_VERSION_3_9_0
#define CC_HAS_NEW_LIGHTING_SYSTEM 1
#define CC_HAS_IMPROVED_SHADOWS 1
#define CC_HAS_ADVANCED_POST_PROCESSING 1
#elif CC_ENGINE_VERSION >= CC_ENGINE_VERSION_3_8_1
#define CC_HAS_NEW_LIGHTING_SYSTEM 0
#define CC_HAS_IMPROVED_SHADOWS 1
#define CC_HAS_ADVANCED_POST_PROCESSING 0
#else
#define CC_HAS_NEW_LIGHTING_SYSTEM 0
#define CC_HAS_IMPROVED_SHADOWS 0
#define CC_HAS_ADVANCED_POST_PROCESSING 0
#endif

// 向后兼容包装器
#if !CC_HAS_NEW_LIGHTING_SYSTEM
// 为旧版本提供新API的兼容实现
#define newLightingFunction oldLightingFunction
#define enhancedSurfaceShader basicSurfaceShader
#endif

#if !CC_HAS_IMPROVED_SHADOWS
// 影子系统向后兼容
#define calculateShadowCascade(coord) calculateBasicShadow(coord)
#define sampleShadowMap(map, coord) texture(map, coord.xy).r
#endif

// 弃用警告宏
#define DEPRECATED_FUNCTION(oldName, newName, version) \
#pragma message("Warning: " #oldName " is deprecated since version " #version ". Use " #newName " instead.")

#define DEPRECATED_MACRO(oldMacro, newMacro, version) \
#pragma message("Warning: " #oldMacro " is deprecated since version " #version ". Use " #newMacro " instead.")

// 使用示例
#ifdef USE_DEPRECATED_API
DEPRECATED_FUNCTION(oldCalculateLighting, calculateEnhancedLighting, 3.8.0)
#define calculateLighting oldCalculateLighting
#else
#define calculateLighting calculateEnhancedLighting
#endif

#endif // VERSION_MANAGER_INCLUDED

错误处理和调试宏

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 错误处理系统:error_handling.glsl
#ifndef ERROR_HANDLING_INCLUDED
#define ERROR_HANDLING_INCLUDED

// 错误级别定义
#define ERROR_LEVEL_INFO 0
#define ERROR_LEVEL_WARNING 1
#define ERROR_LEVEL_ERROR 2
#define ERROR_LEVEL_FATAL 3

#ifndef MINIMUM_ERROR_LEVEL
#ifdef DEBUG_MODE
#define MINIMUM_ERROR_LEVEL ERROR_LEVEL_INFO
#else
#define MINIMUM_ERROR_LEVEL ERROR_LEVEL_WARNING
#endif
#endif

// 条件编译的错误处�?#if MINIMUM_ERROR_LEVEL <= ERROR_LEVEL_INFO
#define LOG_INFO(message) logMessage(ERROR_LEVEL_INFO, __FILE__, __LINE__, message)
#else
#define LOG_INFO(message)
#endif

#if MINIMUM_ERROR_LEVEL <= ERROR_LEVEL_WARNING
#define LOG_WARNING(message) logMessage(ERROR_LEVEL_WARNING, __FILE__, __LINE__, message)
#define WARN_IF(condition, message) if (condition) LOG_WARNING(message)
#else
#define LOG_WARNING(message)
#define WARN_IF(condition, message)
#endif

#if MINIMUM_ERROR_LEVEL <= ERROR_LEVEL_ERROR
#define LOG_ERROR(message) logMessage(ERROR_LEVEL_ERROR, __FILE__, __LINE__, message)
#define ERROR_IF(condition, message) if (condition) { LOG_ERROR(message); return; }
#else
#define LOG_ERROR(message)
#define ERROR_IF(condition, message)
#endif

// 运行时检查宏
#ifdef ENABLE_RUNTIME_CHECKS
#define CHECK_NORMAL_VALID(normal) \
WARN_IF(length(normal) < 0.9 || length(normal) > 1.1, "Normal vector is not normalized")

#define CHECK_UV_RANGE(uv) \
WARN_IF(any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0))), "UV coordinates out of range")

#define CHECK_COLOR_RANGE(color) \
WARN_IF(any(lessThan(color, vec3(0.0))) || any(greaterThan(color, vec3(1.0))), "Color values out of range")
#else
#define CHECK_NORMAL_VALID(normal)
#define CHECK_UV_RANGE(uv)
#define CHECK_COLOR_RANGE(color)
#endif

// 性能监控�?#ifdef ENABLE_PERFORMANCE_MONITORING
#define PERF_BLOCK_BEGIN(name) \
float perf_start_##name = cc_time.x;

#define PERF_BLOCK_END(name) \
float perf_elapsed_##name = cc_time.x - perf_start_##name; \
if (perf_elapsed_##name > PERFORMANCE_WARNING_THRESHOLD) { \
LOG_WARNING("Performance warning: " #name " took " + perf_elapsed_##name + "ms"); \
}
#else
#define PERF_BLOCK_BEGIN(name)
#define PERF_BLOCK_END(name)
#endif

#endif // ERROR_HANDLING_INCLUDED

📖 本章总结

通过本章学习,我们深入掌握了:

  • 高级宏编程:多层级宏定义、递归宏和复杂条件编译
  • 模块化架构:宏与Include系统的深度集成和动态选择
  • 跨平台兼容:平台检测、API包装和性能优化策略
  • 企业级架构:项目配置管理、模块化系统和版本控制
  • 质量保证:自动化测试、错误处理和性能监控
  • 最佳实践:代码生成、元编程和大型项目管理

🚀 下一步学习

恭喜完成第7章的所有内容!现在你已经掌握了Cocos Shader宏定义与函数重映射的完整知识体系。建议继续学习:

👉 第8章:自定义Surface Shader

💡 实践练习

  1. 基础练习:设计一个多平台兼容的宏系统
  2. 进阶练习:实现完整的模块化Include架构
  3. 高级练习:构建企业级的宏管理和测试框架

参考资料

系列导航

🎉 第7章完成

第7章:宏定义与函数重映射已全部完成!你现在已经掌握了:

  • 7.1 宏定义系统的核心概念和应用
  • 7.2 函数重映射的高级技术和设计模式
  • 7.3 内置函数的安全重写和系统扩展
  • 7.4 企业级宏编程和架构设计

这些知识将为你后续的高级着色器开发奠定坚实的基础。继续加油!