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.
 
 
 
 
 
 

70 lines
2.2 KiB

// shaders/dialog_wave_core.frag
#version 300 es
precision highp float;
#include <flutter/runtime_effect.glsl>
uniform vec2 u_resolution; // setFloat(0, w) & (1, h)
uniform float u_time; // setFloat(2, t)
uniform float u_amp; // setFloat(3, amp) —— 建议传音量 RMS
out vec4 fragColor;
// ─────────── Noise Helpers ───────────
float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.545);}
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)),u.x),
mix(hash(i+vec2(0,1)), hash(i+vec2(1,1)),u.x),u.y);
}
float fbm(vec2 p){
float a=.5, v=0.;
mat2 m=mat2(1.6,1.2,-1.2,1.6);
for(int i=0;i<3;i++){
v+=a*noise(p); p=m*p*1.6; a*=.55;
}
return v;
}
// ─────────── Palette ───────────
vec3 palette(float t){
vec3 deep = vec3(0.05,0.10,0.30); // 靛蓝
vec3 mid = vec3(0.15,0.00,0.55); // 暗紫
vec3 glow = vec3(0.00,0.60,1.00); // 电蓝
return mix(deep, mix(mid, glow, t*t), t); // t² 让亮部偏蓝
}
void main(){
// ① 归一化到 [-1,1](保持比例)
vec2 uv = (FlutterFragCoord().xy / u_resolution)*2.0 - 1.0;
uv.x *= u_resolution.x / u_resolution.y;
float r = length(uv); // 半径 0~√2
// ② “呼吸”——音量驱动整体缩放(amp ∈ [0,1])
float breath = 1.0 - (.08 + .05*u_amp) * sin(u_time*1.5);
vec2 p = uv / breath; // 越大越收缩
p *= 3.0; // 纹理密度
p += u_time * 0.35; // 缓慢横移
// ③ 旋转扭曲 + fBm 云雾
float angle = atan(p.y,p.x) + 0.25*r; // 小角度漩涡
float radius = length(p);
vec2 q = vec2(cos(angle),sin(angle))*radius;
float n = fbm(q) * .7 + fbm(q*2.0) * .3;
n = smoothstep(.3,.7,n);
vec3 col = palette(n);
// ④ 亮度脉冲(随 amp 加强)
col += (.05 + .08*u_amp) * sin(u_time*2.0 + n*6.0);
// ⑤ 外环光晕(amp 加深)
float halo = smoothstep(.55,.05,r) * (0.15 + 0.5*u_amp);
col += halo;
// ⑥ 羽化:可见区半径 ≈ 0.96
float alpha = step(r, 0.75);
fragColor = vec4(col, alpha);
}