You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.0 KiB

// shaders/mic_flow.frag
#version 300 es
precision highp float;
#include <flutter/runtime_effect.glsl>
uniform vec2 u_resolution; // 由 FlutterShaders 自动注入
uniform float u_time; // AnimationController -> setFloat(2, ...)
uniform float u_amp; // 可选:实时音量 (0~1),建议 setFloat(3, rms)
out vec4 fragColor;
// ——— 经典 hash & noise ———
float hash(vec2 p) {
return fract(sin(dot(p, vec2(127.1,311.7))) * 43758.5453123);
}
float noise(vec2 p) {
vec2 i = floor(p), f = fract(p);
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0,0.0)), u.x),
mix(hash(i + vec2(0.0,1.0)), hash(i + vec2(1.0,1.0)), u.x),
u.y);
}
// fBm:3-oct & 微 Domain Warp
float fbm(vec2 p) {
float sum = 0.0, amp = 0.5;
mat2 m = mat2(1.6, 1.2,
-1.2, 1.6); // 轻微旋转,防止轴纹
for (int i = 0; i < 3; ++i) {
sum += amp * noise(p);
p = m * p * 1.6;
amp *= 0.55;
}
return sum;
}
// 调色盘:深蓝 → 云白
vec3 palette(float t) {
vec3 deep = vec3(0.08, 0.42, 1.00);
vec3 light= vec3(0.94, 0.98, 1.00);
return mix(deep, light, t);
}
void main() {
// 0‒1 -> -0.5‒0.5,保持圆心在 Shader 0,0
vec2 uv = (FlutterFragCoord().xy / u_resolution) - .5;
// 呼吸缩放(≈ 0.92‒1.08)
float breath = 1.0 + (0.05 + 0.03 * u_amp) * sin(u_time * 1.4);
vec2 p = uv * 3.2 / breath; // 越大云越细腻
p += u_time * 0.35; // 横向漂移
// 多层 fBm + 微距 domain-warp
float n = fbm(p) * 0.65 + fbm(p * 2.0 + vec2(5.2)) * 0.35;
float t = smoothstep(0.32, 0.68, n); // 阈值决定明暗分布
vec3 col= palette(t);
// ─── 边缘羽化 ───
float r = length(uv); // 半径 0-0.5
float alpha = smoothstep(0.48, 0.46, r); // 92% 处开始衰减
// 轻量亮度脉冲:让中心更有“呼吸”感
float pulse = 0.04 * sin(u_time * 2.0 + n * 4.0);
col += pulse;
fragColor = vec4(col, alpha);
}