基于GLSL实现类似模糊彩色Blob背景的技术问询
实现模糊彩色Blob页面背景的Shader优化需求
目标是实现类似以下风格的页面背景:

这类背景是分布在整个页面的模糊彩色Blob,以下是当前的Shader代码:
当前Vertex Shader代码
varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
当前Fragment Shader代码
precision highp float; uniform float uTime; uniform float uAmplitude; uniform float uFrequency; varying vec2 vUv; uniform vec2 uResolution; vec4 Sphere(vec2 position, float radius) { // float dist = radius / distance(vUv, position); // float strength = 0.01 / distance(vUv, position); float strength = 0.1 / distance(vec2(vUv.x, (vUv.y - 0.5) * 8. + 0.5), vec2(0.)); return vec4(strength * strength); } void main() { vec2 uv = vUv; vec4 pixel = vec4(0.0, 0.0, 0.0, 0.0); vec2 positions[4]; positions[0] = vec2(.5, .5); // positions[1] = vec2(sin(uTime * 3.0) * 0.5, (cos(uTime * 1.3) * 0.6) + vUv.y); // positions[2] = vec2(sin(uTime * 2.1) * 0.1, (cos(uTime * 1.9) * 0.8) + vUv.y); // positions[3] = vec2(sin(uTime * 1.1) * 1.1, (cos(uTime * 2.6) * 0.7) + vUv.y); for (int i = 0; i < 2; i++) pixel += Sphere(positions[i], 0.22); pixel = pixel * pixel; gl_FragColor = pixel; }
优化后的Shader实现方案
核心优化点
- 改用平滑衰减函数生成自然模糊边缘的Blob形状
- 为每个Blob分配柔和色调,实现彩色叠加效果
- 恢复并优化动态位置逻辑,让Blob缓慢移动增加灵动性
- 适配屏幕分辨率,避免Blob拉伸变形
修改后的Fragment Shader代码
precision highp float; uniform float uTime; uniform vec2 uResolution; varying vec2 vUv; // 生成带平滑模糊边缘的Blob vec4 createBlob(vec2 uv, vec2 center, float radius, vec3 color) { // 适配屏幕宽高比,防止Blob拉伸 vec2 scaledUv = uv * uResolution / min(uResolution.x, uResolution.y); vec2 scaledCenter = center * uResolution / min(uResolution.x, uResolution.y); float dist = distance(scaledUv, scaledCenter); // 平滑衰减函数,实现自然模糊边缘 float strength = smoothstep(radius, radius * 0.5, dist); strength = pow(strength, 2.0); // 强化边缘衰减效果 return vec4(color * strength, strength); } void main() { vec2 uv = vUv; vec4 finalColor = vec4(0.0); // 定义4个Blob的位置、尺寸和颜色 vec2 positions[4]; positions[0] = vec2(0.5 + sin(uTime * 0.2) * 0.3, 0.5 + cos(uTime * 0.3) * 0.2); positions[1] = vec2(0.2 + sin(uTime * 0.15) * 0.4, 0.7 + cos(uTime * 0.25) * 0.3); positions[2] = vec2(0.8 + sin(uTime * 0.25) * 0.3, 0.3 + cos(uTime * 0.18) * 0.25); positions[3] = vec2(0.4 + sin(uTime * 0.12) * 0.25, 0.2 + cos(uTime * 0.32) * 0.3); vec3 colors[4]; colors[0] = vec3(0.6, 0.2, 0.8); // 淡紫 colors[1] = vec3(0.2, 0.6, 0.8); // 淡蓝 colors[2] = vec3(0.8, 0.6, 0.2); // 淡橙 colors[3] = vec3(0.2, 0.8, 0.6); // 淡青 float radii[4]; radii[0] = 0.8; radii[1] = 0.7; radii[2] = 0.9; radii[3] = 0.65; // 叠加所有Blob for (int i = 0; i < 4; i++) { finalColor += createBlob(uv, positions[i], radii[i], colors[i]); } // 限制颜色饱和度,添加深色背景底 finalColor = clamp(finalColor, 0.0, 1.0); finalColor += vec4(0.1, 0.1, 0.15, 0.0); gl_FragColor = finalColor; }
关键说明
- 形状优化:用
smoothstep替代简单的距离倒数,生成边缘平滑过渡的Blob,再通过pow强化衰减,让模糊感更自然 - 屏幕适配:将UV坐标按屏幕最小边缩放,确保Blob在不同宽高比的屏幕上保持圆形
- 动态效果:每个Blob使用不同频率的
sin/cos函数控制位移,速度缓慢避免视觉干扰 - 色彩控制:选用低饱和度的柔和色调,叠加后形成丰富的彩色背景,深色底让Blob更突出
- 性能保障:Blob数量控制在4个,计算逻辑简洁,不会影响页面流畅度
内容的提问来源于stack exchange,提问作者Bart Krakowski
相关产品推荐
相关产品推荐

