Files
komplex/tools/packsrc/Multiscale MIP Fluid/shaders/Buffer D.frag
Digital Artifex c8f3f1e981 Added shader packs
2025-08-19 09:33:45 -04:00

115 lines
3.4 KiB
GLSL

#define VORT_CH xy
#define VORT_SAMPLER iChannel0
#define POIS_SAMPLER iChannel1
#define POIS_CH x
#define DEGREE POISSON_SCALES
#define D(d) textureLod(VORT_SAMPLER, fract(uv+d), mip).VORT_CH
#define P(d) textureLod(POIS_SAMPLER, fract(uv+d), mip).POIS_CH
float laplacian_poisson(vec2 fragCoord) {
const float _K0 = -20.0/6.0, _K1 = 4.0/6.0, _K2 = 1.0/6.0;
vec2 texel = 1.0/iResolution.xy;
vec2 uv = fragCoord * texel;
vec4 t = vec4(texel, -texel.y, 0);
float mip = 0.0;
float p = P( t.ww); float p_n = P( t.wy); float p_e = P( t.xw);
float p_s = P( t.wz); float p_w = P(-t.xw); float p_nw = P(-t.xz);
float p_sw = P(-t.xy); float p_ne = P( t.xy); float p_se = P( t.xz);
return _K0 * p + _K1 * (p_e + p_w + p_n + p_s) + _K2 * (p_ne + p_nw + p_se + p_sw);
}
void tex(vec2 uv, inout mat3 mx, inout mat3 my, inout mat3 mp, int degree) {
vec2 texel = 1.0/iResolution.xy;
float stride = float(1 << degree);
float mip = float(degree);
vec4 t = stride * vec4(texel, -texel.y, 0);
vec2 d = D( t.ww); vec2 d_n = D( t.wy); vec2 d_e = D( t.xw);
vec2 d_s = D( t.wz); vec2 d_w = D(-t.xw); vec2 d_nw = D(-t.xz);
vec2 d_sw = D(-t.xy); vec2 d_ne = D( t.xy); vec2 d_se = D( t.xz);
float p = P( t.ww); float p_n = P( t.wy); float p_e = P( t.xw);
float p_s = P( t.wz); float p_w = P(-t.xw); float p_nw = P(-t.xz);
float p_sw = P(-t.xy); float p_ne = P( t.xy); float p_se = P( t.xz);
mx = mat3(d_nw.x, d_n.x, d_ne.x,
d_w.x, d.x, d_e.x,
d_sw.x, d_s.x, d_se.x);
my = mat3(d_nw.y, d_n.y, d_ne.y,
d_w.y, d.y, d_e.y,
d_sw.y, d_s.y, d_se.y);
mp = mat3(p_nw, p_n, p_ne,
p_w, p, p_e,
p_sw, p_s, p_se);
}
float reduce(mat3 a, mat3 b) {
mat3 p = matrixCompMult(a, b);
return p[0][0] + p[0][1] + p[0][2] +
p[1][0] + p[1][1] + p[1][2] +
p[2][0] + p[2][1] + p[2][2];
}
vec2 pois(vec2 fragCoord)
{
vec2 uv = fragCoord.xy / iResolution.xy;
float k0 = POIS_ISOTROPY;
float k1 = 1.0 - 2.0*(POIS_ISOTROPY);
mat3 pois_x = mat3(
k0, 0.0, -k0,
k1, 0.0, -k1,
k0, 0.0, -k0
);
mat3 pois_y = mat3(
-k0, -k1, -k0,
0.0, 0.0, 0.0,
k0, k1, k0
);
mat3 gauss = mat3(
0.0625, 0.125, 0.0625,
0.125, 0.25, 0.125,
0.0625, 0.125, 0.0625
);
mat3 mx, my, mp;
vec2 v = vec2(0);
float wc = 0.0;
for (int i = 0; i < DEGREE; i++) {
tex(uv, mx, my, mp, i);
float w = POIS_W_FUNCTION;
wc += w;
v += w * vec2(reduce(pois_x, mx) + reduce(pois_y, my), reduce(gauss, mp));
}
return v / wc;
}
#define V(d) textureLod(VORT_SAMPLER, fract(uv+d), mip).zw
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = pois(fragCoord);
#ifdef USE_PRESSURE_ADVECTION
float mip = 0.0;
vec2 tx = 1.0 / iResolution.xy;
vec2 uv = fragCoord * tx;
float prev = P(0.0002 * PRESSURE_ADVECTION * tx * V(vec2(0)));
fragColor = vec4(mix(p.x + p.y, prev + PRESSURE_LAPLACIAN * laplacian_poisson(fragCoord), PRESSURE_UPDATE_SMOOTHING));
#else
fragColor = vec4(p.x + p.y);
#endif
// Adding a very small amount of noise on init fixes subtle numerical precision blowup problems
if (iFrame==0) fragColor=1e-6*rand4(fragCoord, iResolution.xy, iFrame);
}