82 lines
2.1 KiB
GLSL
82 lines
2.1 KiB
GLSL
#define CURL_CH w
|
|
#define CURL_SAMPLER iChannel0
|
|
#define DEGREE VORTICITY_SCALES
|
|
|
|
#define CURL(d) textureLod(CURL_SAMPLER, fract(uv+(d+0.0)), mip).CURL_CH
|
|
#define D(d) abs(textureLod(CURL_SAMPLER, fract(uv+d), mip).CURL_CH)
|
|
|
|
void tex(vec2 uv, inout mat3 mc, inout float curl, 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);
|
|
|
|
float d = D( t.ww); float d_n = D( t.wy); float d_e = D( t.xw);
|
|
float d_s = D( t.wz); float d_w = D(-t.xw); float d_nw = D(-t.xz);
|
|
float d_sw = D(-t.xy); float d_ne = D( t.xy); float d_se = D( t.xz);
|
|
|
|
mc = mat3(d_nw, d_n, d_ne,
|
|
d_w, d, d_e,
|
|
d_sw, d_s, d_se);
|
|
|
|
curl = CURL();
|
|
|
|
}
|
|
|
|
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 confinement(vec2 fragCoord)
|
|
{
|
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
|
|
|
float k0 = CONF_ISOTROPY;
|
|
float k1 = 1.0 - 2.0*(CONF_ISOTROPY);
|
|
|
|
mat3 conf_x = mat3(
|
|
-k0, -k1, -k0,
|
|
0.0, 0.0, 0.0,
|
|
k0, k1, k0
|
|
);
|
|
|
|
mat3 conf_y = mat3(
|
|
-k0, 0.0, k0,
|
|
-k1, 0.0, k1,
|
|
-k0, 0.0, k0
|
|
);
|
|
|
|
mat3 mc;
|
|
vec2 v = vec2(0);
|
|
float curl;
|
|
|
|
float cacc = 0.0;
|
|
vec2 nacc = vec2(0);
|
|
float wc = 0.0;
|
|
for (int i = 0; i < DEGREE; i++) {
|
|
tex(uv, mc, curl, i);
|
|
float w = CONF_W_FUNCTION;
|
|
vec2 n = w * normz(vec2(reduce(conf_x, mc), reduce(conf_y, mc)));
|
|
v += curl * n;
|
|
cacc += curl;
|
|
nacc += n;
|
|
wc += w;
|
|
}
|
|
|
|
#ifdef PREMULTIPLY_CURL
|
|
return v / wc;
|
|
#else
|
|
return nacc * cacc / wc;
|
|
#endif
|
|
|
|
}
|
|
|
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
|
{
|
|
fragColor = vec4(confinement(fragCoord),0,0);
|
|
// 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);
|
|
} |