一、效果概述
在游戏UI和特效制作中,高斯模糊是一种常见的效果,用于创建景深、聚焦或朦胧的美术效果。本文将解析一个基于Cocos Creator的高斯模糊着色器实现。
二、核心代码结构
这个效果主要由三部分组成:
- CCEffect - 效果定义和参数配置
- 顶点着色器(sprite-vs) - 标准2D精灵顶点处理
- 片段着色器(sprite-fs) - 高斯模糊核心算法
三、CCEffect配置解析
techniques:
- passes:
- vert: sprite-vs:vert // 指定顶点着色器
frag: sprite-fs:frag // 指定片段着色器
depthStencilState:
depthTest: false // 禁用深度测试
depthWrite: false // 禁用深度写入
blendState:
targets:
- blend: true // 启用混合
blendSrc: src_alpha // 源因子: src_alpha
blendDst: one_minus_src_alpha // 目标因子: 1-src_alpha
rasterizerState:
cullMode: none // 禁用面剔除
properties:
mainTexture: { value: grey } // 输入纹理
textureSize: { value: [1920,1080] }// 纹理尺寸
blurRadius: { value: 10.0, range: [0.0, 10.0] } // 模糊半径(可调)
四、顶点着色器分析
顶点着色器主要完成标准2D精灵的顶点变换:
vec4 vert() {
vec4 pos = vec4(a_position, 1);
// 世界变换(可选)
#if USE_LOCAL
pos = cc_matWorld * pos;
#endif
// 视图投影变换
#if USE_PIXEL_ALIGNMENT
pos = cc_matView * pos;
pos.xyz = floor(pos.xyz); // 像素对齐
pos = cc_matProj * pos;
#else
pos = cc_matViewProj * pos;
#endif
// 传递变量到片段着色器
uv0 = a_texCoord;
color = a_color;
return pos;
}
五、高斯模糊算法实现
片段着色器中实现了完整的二维高斯模糊:
1. 高斯权重计算
float getWeight(float x, float y, float rho) {
return exp(-(x*x + y*y)/(2.0*rho*rho));
}
2. 模糊主函数
vec4 gaussBlur(vec2 uv) {
vec4 finalColor = vec4(0.0);
float rho = blurRadius / 3.0; // 标准差
vec2 texelSize = 1.0 / textureSize; // 单个像素大小
// 第一遍:计算总权重
float totalWeight = 0.0;
for(int x = -MAX_RADIUS; x <= MAX_RADIUS; x++) {
for(int y = -MAX_RADIUS; y <= MAX_RADIUS; y++) {
if (abs(float(x)) <= blurRadius && abs(float(y)) <= blurRadius) {
totalWeight += getWeight(float(x), float(y), rho);
}
}
}
// 第二遍:应用模糊
for(int x = -MAX_RADIUS; x <= MAX_RADIUS; x++) {
for(int y = -MAX_RADIUS; y <= MAX_RADIUS; y++) {
if (abs(float(x)) <= blurRadius && abs(float(y)) <= blurRadius) {
float weight = getWeight(float(x), float(y), rho) / totalWeight;
vec2 offset = vec2(float(x), float(y)) * texelSize;
finalColor += texture(mainTexture, uv + offset) * weight;
}
}
}
return finalColor;
}
3. 片段着色器入口
vec4 frag() {
vec4 col = gaussBlur(uv0);
return col * color;
}
六、性能优化建议
- 分离模糊:将二维模糊拆分为水平和垂直两次一维模糊,可大幅减少采样次数
- 降采样:先缩小纹理尺寸进行模糊,再放大回原尺寸
- 限制半径:如代码中做的,设置最大模糊半径(10像素)
- 使用预计算权重:提前计算好权重表,减少实时计算
七、应用场景
- UI背景模糊效果
- 游戏暂停时的背景处理
- 角色技能特效
- 景深模拟
八、总结
这个实现提供了可配置的高斯模糊效果,通过调整blurRadius
参数可以控制模糊程度。虽然当前实现使用了标准的二维高斯模糊,但在实际项目中可以根据性能需求进行优化。
完整代码已在文章开头给出,读者可以直接在Cocos Creator项目中尝试使用或进一步修改优化。