�?.2章:函数重映射技�?

函数重映射是Cocos Shader的强大扩展机制,它允许开发者重新定义内置函数的行为,创建自定义的函数实现,以及构建灵活的函数调用系统。本章将深入探讨函数重映射的原理、实现方法和应用场景�?

🎯 学习目标

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

  • 函数重映射的工作原理和应用场�?- 自定义函数的注册和调用机�?- 内置函数的重写和扩展技�?- 动态函数替换的实现方法
  • 函数重映射在大型项目中的架构设计

💡 函数重映射基础

基本概念

函数重映射允许我们:

  1. **重定义内置函�?*:修改Cocos Creator内置函数的行�?2. 创建函数别名:为复杂函数创建简化的调用接口
  2. 实现函数重载:根据不同条件选择不同的函数实�?4. **模块化设�?*:将复杂功能分解为可重用的函数模�?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 基本的函数重映射示例
    // 原始函数定义
    vec3 calculateLighting_Original(vec3 normal, vec3 lightDir, vec3 viewDir) {
    // 标准光照计算
    return vec3(1.0);
    }

    // 重映射函�?vec3 calculateLighting_Custom(vec3 normal, vec3 lightDir, vec3 viewDir) {
    // 自定义光照计�? return vec3(0.8);
    }

    // 函数重映�?#define calculateLighting calculateLighting_Custom

Cocos Creator的函数重映射机制

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
CCEffect %{
techniques:
- name: function-remapping
passes:
- vert: remapping-vs:vert
frag: remapping-fs:frag
properties: &props
mainTexture: { value: white }
customLightModel: { value: 0, range: [0, 3] }
lightingIntensity: { value: 1.0, range: [0, 2] }
}%

CCProgram remapping-vs %{
#include <surface-vertex>
}%

CCProgram remapping-fs %{
#include <surface-fragment>

uniform Properties {
int customLightModel;
float lightingIntensity;
};
uniform sampler2D mainTexture;

// 声明多种光照函数实现
vec3 standardLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo);
vec3 toonLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo);
vec3 customPBR(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo);
vec3 experimentalLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo);

// 函数重映射表
vec3 calculateLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
if (customLightModel == 0) {
return standardLighting(normal, lightDir, viewDir, lightColor, albedo);
} else if (customLightModel == 1) {
return toonLighting(normal, lightDir, viewDir, lightColor, albedo);
} else if (customLightModel == 2) {
return customPBR(normal, lightDir, viewDir, lightColor, albedo);
} else {
return experimentalLighting(normal, lightDir, viewDir, lightColor, albedo);
}
}

void surf (in SurfaceIn In, inout SurfaceOut Out) {
vec4 albedo = texture(mainTexture, In.uv);
vec3 normal = normalize(In.worldNormal);
vec3 viewDir = normalize(cc_cameraPos.xyz - In.worldPos);
vec3 lightDir = normalize(-cc_mainLitDir.xyz);
vec3 lightColor = cc_mainLitColor.rgb * cc_mainLitColor.a * lightingIntensity;

vec3 lighting = calculateLighting(normal, lightDir, viewDir, lightColor, albedo.rgb);

Out.albedo = vec4(lighting, albedo.a);
Out.normal = normal;
}
}%

🔧 编译时函数重映射

宏驱动的函数选择

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// 光照模型选择�?#define LIGHTING_LAMBERT 0
#define LIGHTING_PHONG 1
#define LIGHTING_BLINN_PHONG 2
#define LIGHTING_PBR 3
#define LIGHTING_TOON 4

#ifndef LIGHTING_MODEL
#define LIGHTING_MODEL LIGHTING_PBR
#endif

// Lambert光照实现
vec3 lambertLighting(vec3 normal, vec3 lightDir, vec3 lightColor, vec3 albedo) {
float NdotL = max(dot(normal, lightDir), 0.0);
return albedo * lightColor * NdotL;
}

// Phong光照实现
vec3 phongLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
float NdotL = max(dot(normal, lightDir), 0.0);
vec3 diffuse = albedo * lightColor * NdotL;

vec3 reflectDir = reflect(-lightDir, normal);
float RdotV = max(dot(reflectDir, viewDir), 0.0);
vec3 specular = lightColor * pow(RdotV, 32.0);

return diffuse + specular;
}

// Blinn-Phong光照实现
vec3 blinnPhongLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
float NdotL = max(dot(normal, lightDir), 0.0);
vec3 diffuse = albedo * lightColor * NdotL;

vec3 halfDir = normalize(lightDir + viewDir);
float NdotH = max(dot(normal, halfDir), 0.0);
vec3 specular = lightColor * pow(NdotH, 32.0);

return diffuse + specular;
}

// PBR光照实现(简化版�?vec3 pbrLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// 简化的PBR计算
float metallic = 0.0;
float roughness = 0.5;

vec3 F0 = mix(vec3(0.04), albedo, metallic);
vec3 H = normalize(lightDir + viewDir);

float NdotL = max(dot(normal, lightDir), 0.0);
float NdotV = max(dot(normal, viewDir), 0.0);
float NdotH = max(dot(normal, H), 0.0);
float VdotH = max(dot(viewDir, H), 0.0);

// 简化的BRDF计算
float alpha = roughness * roughness;
float D = alpha * alpha / (3.14159 * pow(NdotH * NdotH * (alpha * alpha - 1.0) + 1.0, 2.0));
vec3 F = F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);

vec3 kS = F;
vec3 kD = (1.0 - kS) * (1.0 - metallic);

vec3 diffuse = kD * albedo / 3.14159;
vec3 specular = D * F / (4.0 * NdotV * NdotL + 0.001);

return (diffuse + specular) * lightColor * NdotL;
}

// 卡通光照实�?vec3 toonLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
float NdotL = dot(normal, lightDir);

// 多级卡通化
float toonFactor;
if (NdotL > 0.8) toonFactor = 1.0;
else if (NdotL > 0.4) toonFactor = 0.7;
else if (NdotL > 0.2) toonFactor = 0.4;
else toonFactor = 0.1;

return albedo * lightColor * toonFactor;
}

// 编译时函数重映射
#if LIGHTING_MODEL == LIGHTING_LAMBERT
#define calculateLighting(n, l, v, lc, a) lambertLighting(n, l, lc, a)
#elif LIGHTING_MODEL == LIGHTING_PHONG
#define calculateLighting(n, l, v, lc, a) phongLighting(n, l, v, lc, a)
#elif LIGHTING_MODEL == LIGHTING_BLINN_PHONG
#define calculateLighting(n, l, v, lc, a) blinnPhongLighting(n, l, v, lc, a)
#elif LIGHTING_MODEL == LIGHTING_PBR
#define calculateLighting(n, l, v, lc, a) pbrLighting(n, l, v, lc, a)
#elif LIGHTING_MODEL == LIGHTING_TOON
#define calculateLighting(n, l, v, lc, a) toonLighting(n, l, v, lc, a)
#else
#define calculateLighting(n, l, v, lc, a) lambertLighting(n, l, lc, a)
#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
48
49
50
51
// 基于质量设置的函数重映射
#define QUALITY_LOW 0
#define QUALITY_MEDIUM 1
#define QUALITY_HIGH 2

#ifndef RENDER_QUALITY
#define RENDER_QUALITY QUALITY_MEDIUM
#endif

// 不同质量的法线计�?vec3 calculateNormal_Low(SurfaceIn In) {
return normalize(In.worldNormal);
}

vec3 calculateNormal_Medium(SurfaceIn In) {
#ifdef HAS_NORMAL_MAP
vec3 normalMap = texture(normalTexture, In.uv).xyz * 2.0 - 1.0;
return normalize(In.worldTangent.xyz * normalMap.x +
In.worldBinormal * normalMap.y +
In.worldNormal * normalMap.z);
#else
return normalize(In.worldNormal);
#endif
}

vec3 calculateNormal_High(SurfaceIn In) {
#ifdef HAS_NORMAL_MAP
vec3 normalMap = texture(normalTexture, In.uv).xyz * 2.0 - 1.0;
normalMap.xy *= normalScale;

// 高质量法线混�? vec3 worldNormal = normalize(In.worldNormal);
vec3 detailNormal = normalMap;

// 使用更精确的切线空间变换
vec3 T = normalize(In.worldTangent.xyz);
vec3 B = normalize(In.worldBinormal);
vec3 N = worldNormal;
mat3 TBN = mat3(T, B, N);

return normalize(TBN * detailNormal);
#else
return normalize(In.worldNormal);
#endif
}

// 质量级别函数重映�?#if RENDER_QUALITY == QUALITY_LOW
#define calculateNormal calculateNormal_Low
#elif RENDER_QUALITY == QUALITY_MEDIUM
#define calculateNormal calculateNormal_Medium
#else
#define calculateNormal calculateNormal_High
#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
48
49
50
51
52
53
54
55
56
57
// 函数指针类型定义(使用整数索引模拟)
#define FUNC_STANDARD_LIGHTING 0
#define FUNC_TOON_LIGHTING 1
#define FUNC_PBR_LIGHTING 2
#define FUNC_EXPERIMENTAL_LIGHTING 3

uniform int lightingFunctionIndex;

// 函数实现
vec3 standardLightingImpl(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
float NdotL = max(dot(normal, lightDir), 0.0);
return albedo * lightColor * NdotL;
}

vec3 toonLightingImpl(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
float NdotL = dot(normal, lightDir);
float toonStep = step(0.5, NdotL);
return albedo * lightColor * mix(0.3, 1.0, toonStep);
}

vec3 pbrLightingImpl(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// PBR实现
return albedo * lightColor * max(dot(normal, lightDir), 0.0);
}

vec3 experimentalLightingImpl(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// 实验性光�? float fresnel = pow(1.0 - max(dot(normal, viewDir), 0.0), 3.0);
return albedo * lightColor * fresnel;
}

// 动态函数调度器
vec3 dispatchLightingFunction(int funcIndex, vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
if (funcIndex == FUNC_STANDARD_LIGHTING) {
return standardLightingImpl(normal, lightDir, viewDir, lightColor, albedo);
} else if (funcIndex == FUNC_TOON_LIGHTING) {
return toonLightingImpl(normal, lightDir, viewDir, lightColor, albedo);
} else if (funcIndex == FUNC_PBR_LIGHTING) {
return pbrLightingImpl(normal, lightDir, viewDir, lightColor, albedo);
} else if (funcIndex == FUNC_EXPERIMENTAL_LIGHTING) {
return experimentalLightingImpl(normal, lightDir, viewDir, lightColor, albedo);
} else {
return standardLightingImpl(normal, lightDir, viewDir, lightColor, albedo);
}
}

// 主函数中的使�?void surf(in SurfaceIn In, inout SurfaceOut Out) {
vec3 lighting = dispatchLightingFunction(
lightingFunctionIndex,
normalize(In.worldNormal),
normalize(-cc_mainLitDir.xyz),
normalize(cc_cameraPos.xyz - In.worldPos),
cc_mainLitColor.rgb * cc_mainLitColor.a,
texture(mainTexture, In.uv).rgb
);

Out.albedo = vec4(lighting, 1.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
// 参数化的光照函数系统
struct LightingParams {
float diffuseStrength;
float specularStrength;
float roughness;
float metallic;
vec3 tintColor;
};

uniform LightingParams lightingParams;

// 基础光照函数模板
vec3 baseLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo, LightingParams params) {
float NdotL = max(dot(normal, lightDir), 0.0);
vec3 diffuse = albedo * lightColor * NdotL * params.diffuseStrength;

vec3 halfDir = normalize(lightDir + viewDir);
float NdotH = max(dot(normal, halfDir), 0.0);
float specular = pow(NdotH, 1.0 / (params.roughness + 0.001));
vec3 specularColor = lightColor * specular * params.specularStrength;

return (diffuse + specularColor) * params.tintColor;
}

// 特殊化的光照函数
vec3 metallicLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo, LightingParams params) {
// 金属材质特殊处理
LightingParams metallicParams = params;
metallicParams.specularStrength *= 2.0;
metallicParams.diffuseStrength *= (1.0 - params.metallic);

return baseLighting(normal, lightDir, viewDir, lightColor, albedo, metallicParams);
}

vec3 subsurfaceLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo, LightingParams params) {
// 次表面散射处�? vec3 result = baseLighting(normal, lightDir, viewDir, lightColor, albedo, params);

// 添加背面光照
float backLight = max(dot(-normal, lightDir), 0.0);
vec3 subsurface = albedo * lightColor * backLight * 0.3;

return result + subsurface;
}

// 函数重映射接�?#define MATERIAL_TYPE_STANDARD 0
#define MATERIAL_TYPE_METALLIC 1
#define MATERIAL_TYPE_SUBSURFACE 2

uniform int materialType;

vec3 calculateMaterialLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
switch(materialType) {
case MATERIAL_TYPE_METALLIC:
return metallicLighting(normal, lightDir, viewDir, lightColor, albedo, lightingParams);
case MATERIAL_TYPE_SUBSURFACE:
return subsurfaceLighting(normal, lightDir, viewDir, lightColor, albedo, lightingParams);
default:
return baseLighting(normal, lightDir, viewDir, lightColor, albedo, lightingParams);
}
}

🔧 内置函数重写

Surface函数重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 重写内置的表面函�?// 原始surf函数的扩展版�?void surf_Extended(in SurfaceIn In, inout SurfaceOut Out) {
// 调用原始surf函数
surf_Original(In, Out);

// 添加自定义后处理
Out.albedo.rgb = applyCustomColorGrading(Out.albedo.rgb);
Out.normal = applyCustomNormalAdjustment(Out.normal);
Out.emissive += calculateCustomEmission(In);
}

// 重写顶点函数
void vert_Extended() {
// 调用原始顶点函数
vert_Original();

// 添加自定义顶点变�? gl_Position = applyCustomProjection(gl_Position);
}

// 函数重映�?#define surf surf_Extended
#define vert vert_Extended

光照函数重写

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
// 重写内置光照计算
vec3 cc_lighting_original(SurfaceIn In, vec3 albedo, vec3 normal, vec3 emissive) {
// 这里是假设的内置光照函数
return albedo * 0.8 + emissive;
}

vec3 cc_lighting_enhanced(SurfaceIn In, vec3 albedo, vec3 normal, vec3 emissive) {
// 增强版光照计�? vec3 viewDir = normalize(cc_cameraPos.xyz - In.worldPos);
vec3 lightDir = normalize(-cc_mainLitDir.xyz);
vec3 lightColor = cc_mainLitColor.rgb * cc_mainLitColor.a;

// 添加边缘光效�? float rimPower = 2.0;
float rim = 1.0 - max(dot(normal, viewDir), 0.0);
vec3 rimLighting = pow(rim, rimPower) * lightColor * 0.3;

// 基础光照
float NdotL = max(dot(normal, lightDir), 0.0);
vec3 diffuse = albedo * lightColor * NdotL;

// 环境�? vec3 ambient = cc_ambientSky.rgb * albedo * 0.1;

return ambient + diffuse + rimLighting + emissive;
}

// 函数重映�?#define cc_lighting cc_lighting_enhanced

工具函数重写

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
// 重写纹理采样函数
vec4 texture_enhanced(sampler2D tex, vec2 uv) {
// 添加纹理过滤和增�? vec4 color = texture(tex, uv);

// 对比度增�? color.rgb = (color.rgb - 0.5) * 1.2 + 0.5;

// 饱和度调�? float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114));
color.rgb = mix(vec3(luminance), color.rgb, 1.1);

return color;
}

// 重写法向量计�?vec3 normalize_safe(vec3 v) {
float len = length(v);
return len > 0.0001 ? v / len : vec3(0.0, 1.0, 0.0);
}

// 重写数学函数
float pow_safe(float base, float exponent) {
return pow(max(base, 0.0001), exponent);
}

// 函数重映�?#define texture texture_enhanced
#define normalize normalize_safe
#define pow pow_safe

🎯 高级函数重映射模�?

1. 装饰器模�?

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
// 装饰器函数:在原函数基础上添加功�?vec3 withDebugVisualization(vec3 originalResult, vec3 debugColor, float debugStrength) {
return mix(originalResult, debugColor, debugStrength);
}

vec3 withPerformanceMonitoring(vec3 originalResult, float startTime) {
float elapsed = cc_time.x - startTime;
// 在调试模式下显示性能信息
#ifdef DEBUG_PERFORMANCE
if (elapsed > 0.016) { // 超过16ms警告
return mix(originalResult, vec3(1.0, 0.0, 0.0), 0.3);
}
#endif
return originalResult;
}

// 装饰器包装函�?vec3 decoratedLighting(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
float startTime = cc_time.x;

// 调用原函�? vec3 result = originalLighting(normal, lightDir, viewDir, lightColor, albedo);

// 应用装饰�? result = withDebugVisualization(result, vec3(0.0, 1.0, 0.0), debugVisualizationStrength);
result = withPerformanceMonitoring(result, startTime);

return result;
}

2. 策略模式

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
// 策略接口
struct LightingStrategy {
int strategyType;
vec4 parameters;
};

uniform LightingStrategy lightingStrategy;

// 策略实现
vec3 executeStrategy_Realistic(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo, vec4 params) {
// 真实感光照策�? return pbrLighting(normal, lightDir, viewDir, lightColor, albedo);
}

vec3 executeStrategy_Stylized(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo, vec4 params) {
// 风格化光照策�? float toonLevels = params.x;
return toonLighting(normal, lightDir, viewDir, lightColor, albedo, toonLevels);
}

vec3 executeStrategy_Performance(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo, vec4 params) {
// 性能优化策略
return lambertLighting(normal, lightDir, lightColor, albedo);
}

// 策略执行�?vec3 executeLightingStrategy(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
if (lightingStrategy.strategyType == 0) {
return executeStrategy_Realistic(normal, lightDir, viewDir, lightColor, albedo, lightingStrategy.parameters);
} else if (lightingStrategy.strategyType == 1) {
return executeStrategy_Stylized(normal, lightDir, viewDir, lightColor, albedo, lightingStrategy.parameters);
} else {
return executeStrategy_Performance(normal, lightDir, viewDir, lightColor, albedo, lightingStrategy.parameters);
}
}

3. 责任链模�?

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
// 光照处理�?vec3 processLighting_AmbientOcclusion(vec3 lighting, SurfaceIn In, vec3 albedo) {
#ifdef ENABLE_AO
float ao = texture(aoTexture, In.uv).r;
return lighting * ao;
#else
return lighting;
#endif
}

vec3 processLighting_Shadows(vec3 lighting, SurfaceIn In, vec3 albedo) {
#ifdef ENABLE_SHADOWS
float shadow = calculateShadow(In.shadowCoord);
return lighting * shadow;
#else
return lighting;
#endif
}

vec3 processLighting_Fog(vec3 lighting, SurfaceIn In, vec3 albedo) {
#ifdef ENABLE_FOG
float fogFactor = calculateFog(In.viewPos);
return mix(cc_fogColor.rgb, lighting, fogFactor);
#else
return lighting;
#endif
}

vec3 processLighting_ColorGrading(vec3 lighting, SurfaceIn In, vec3 albedo) {
#ifdef ENABLE_COLOR_GRADING
return applyColorGrading(lighting);
#else
return lighting;
#endif
}

// 责任链执�?vec3 processLightingChain(vec3 baseLighting, SurfaceIn In, vec3 albedo) {
vec3 result = baseLighting;

result = processLighting_AmbientOcclusion(result, In, albedo);
result = processLighting_Shadows(result, In, albedo);
result = processLighting_Fog(result, In, albedo);
result = processLighting_ColorGrading(result, In, albedo);

return result;
}

📋 函数重映射管�?

1. 版本控制系统

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
// 函数版本管理
#define LIGHTING_VERSION_1_0 100
#define LIGHTING_VERSION_1_1 101
#define LIGHTING_VERSION_2_0 200

#ifndef LIGHTING_VERSION
#define LIGHTING_VERSION LIGHTING_VERSION_2_0
#endif

// 版本兼容性映�?#if LIGHTING_VERSION >= LIGHTING_VERSION_2_0
vec3 calculateLighting_v2(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// 版本2.0的实�? return pbrLighting(normal, lightDir, viewDir, lightColor, albedo);
}
#define calculateLighting calculateLighting_v2
#elif LIGHTING_VERSION >= LIGHTING_VERSION_1_1
vec3 calculateLighting_v1_1(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// 版本1.1的实�? return blinnPhongLighting(normal, lightDir, viewDir, lightColor, albedo);
}
#define calculateLighting calculateLighting_v1_1
#else
vec3 calculateLighting_v1_0(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// 版本1.0的实�? return lambertLighting(normal, lightDir, lightColor, albedo);
}
#define calculateLighting calculateLighting_v1_0
#endif

2. 模块化函数库

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
// 基础模块
#include "lighting_core.glsl"
#include "material_utils.glsl"
#include "math_utils.glsl"

// 扩展模块
#ifdef ENABLE_ADVANCED_LIGHTING
#include "pbr_lighting.glsl"
#include "subsurface_scattering.glsl"
#endif

#ifdef ENABLE_ARTISTIC_EFFECTS
#include "toon_lighting.glsl"
#include "stylized_effects.glsl"
#endif

#ifdef ENABLE_PERFORMANCE_OPTIMIZATIONS
#include "mobile_optimizations.glsl"
#include "lod_systems.glsl"
#endif

// 模块函数映射
#ifdef ENABLE_ADVANCED_LIGHTING
#define calculateLighting calculatePBRLighting
#elif defined(ENABLE_ARTISTIC_EFFECTS)
#define calculateLighting calculateToonLighting
#else
#define calculateLighting calculateBasicLighting
#endif

3. 配置驱动的重映射

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
// 配置结构
struct ShaderConfig {
int lightingModel; // 光照模型选择
int materialType; // 材质类型
int qualityLevel; // 质量等级
vec4 customParameters; // 自定义参�?};

uniform ShaderConfig shaderConfig;

// 配置解释�?vec3 interpretLightingConfig(vec3 normal, vec3 lightDir, vec3 viewDir, vec3 lightColor, vec3 albedo) {
// 根据配置选择函数
if (shaderConfig.lightingModel == 0) {
return lambertLighting(normal, lightDir, lightColor, albedo);
} else if (shaderConfig.lightingModel == 1) {
if (shaderConfig.qualityLevel >= 2) {
return pbrLighting(normal, lightDir, viewDir, lightColor, albedo);
} else {
return blinnPhongLighting(normal, lightDir, viewDir, lightColor, albedo);
}
} else if (shaderConfig.lightingModel == 2) {
float toonLevels = shaderConfig.customParameters.x;
return toonLighting(normal, lightDir, viewDir, lightColor, albedo, toonLevels);
}

return albedo * lightColor;
}

// 主函数重映射
#define calculateLighting interpretLightingConfig

📖 本章总结

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

  • �?函数重映射基础:基本概念和Cocos Creator的重映射机制
  • �?编译时重映射:宏驱动的函数选择和条件重映射
  • �?运行时重映射:动态函数指针和参数化重映射系统
  • �?内置函数重写:Surface函数、光照函数和工具函数的重�?- �?高级设计模式:装饰器、策略和责任链模式的应用
  • �?管理策略:版本控制、模块化和配置驱动的重映�?

🚀 下一步学�?

掌握了函数重映射技术后,建议继续学习:

👉 �?.3章:可替换内置函数

💡 实践练习

  1. 基础练习:实现一个支持多种光照模型的函数重映射系�?2. 进阶练习:创建基于配置的动态函数选择机制
  2. 高级练习:设计完整的模块化着色器函数�?

*参考资�?

系列导航