├── Ls_Advect.1.glsl
├── Ls_Advect.1.glsl.p
├── Ls_Advect.2.glsl
├── Ls_Advect.xml
├── Ls_Airglow.01.glsl
├── Ls_Airglow.01.glsl.p
├── Ls_Airglow.02.glsl
├── Ls_Airglow.03.glsl
├── Ls_Airglow.04.glsl
├── Ls_Airglow.05.glsl
├── Ls_Airglow.06.glsl
├── Ls_Airglow.07.glsl
├── Ls_Airglow.08.glsl
├── Ls_Airglow.09.glsl
├── Ls_Airglow.10.glsl
├── Ls_Airglow.11.glsl
├── Ls_Airglow.12.glsl
├── Ls_Airglow.13.glsl
├── Ls_Airglow.14.glsl
├── Ls_Airglow.15.glsl
├── Ls_Airglow.16.glsl
├── Ls_Airglow.17.glsl
├── Ls_Airglow.xml
├── Ls_Airglow_builder.py
├── Ls_Ash.1.glsl
├── Ls_Ash.1.glsl.p
├── Ls_Ash.2.glsl
├── Ls_Ash.3.glsl
├── Ls_Ash.xml
├── Ls_Bevel.1.glsl
├── Ls_Bevel.1.glsl.p
├── Ls_Bevel.2.glsl
├── Ls_Bevel.3.glsl
├── Ls_Bevel.4.glsl
├── Ls_Bevel.5.glsl
├── Ls_Bevel.6.glsl
├── Ls_Bevel.xml
├── Ls_Chips.glsl
├── Ls_Chips.glsl.p
├── Ls_Chips.hip
├── Ls_Chips.mx
├── Ls_Chips.textureGrid.exr
├── Ls_Chips.xml
├── Ls_Colourmatrix.glsl
├── Ls_Colourmatrix.glsl.p
├── Ls_Colourmatrix.xml
├── Ls_Colourspace.glsl
├── Ls_Colourspace.glsl.p
├── Ls_Colourspace.xml
├── Ls_Contacts.glsl
├── Ls_Contacts.glsl.p
├── Ls_Contacts.xml
├── Ls_Dilate.1.glsl
├── Ls_Dilate.1.glsl.p
├── Ls_Dilate.2.glsl
├── Ls_Dilate.xml
├── Ls_Dollface.1.glsl
├── Ls_Dollface.1.glsl.p
├── Ls_Dollface.2.glsl
├── Ls_Dollface.xml
├── Ls_FXAA.glsl
├── Ls_FXAA.glsl.p
├── Ls_FXAA.xml
├── Ls_Filmstrip.glsl
├── Ls_Filmstrip.glsl.p
├── Ls_Filmstrip.xml
├── Ls_Fireflies.glsl
├── Ls_Fireflies.glsl.p
├── Ls_Fireflies.xml
├── Ls_Fireflies_sortingnetwork.pl
├── Ls_Flock.1.glsl
├── Ls_Flock.1.glsl.p
├── Ls_Flock.2.glsl
├── Ls_Flock.xml
├── Ls_Fluid.1.glsl
├── Ls_Fluid.1.glsl.p
├── Ls_Fluid.10.glsl
├── Ls_Fluid.2.glsl
├── Ls_Fluid.3.glsl
├── Ls_Fluid.4.glsl
├── Ls_Fluid.5.glsl
├── Ls_Fluid.6.glsl
├── Ls_Fluid.7.glsl
├── Ls_Fluid.8.glsl
├── Ls_Fluid.9.glsl
├── Ls_Fluid.xml
├── Ls_Glint.1.glsl
├── Ls_Glint.1.glsl.p
├── Ls_Glint.2.glsl
├── Ls_Glint.3.glsl
├── Ls_Glint.xml
├── Ls_GlueP.glsl
├── Ls_GlueP.glsl.p
├── Ls_GlueP.xml
├── Ls_Lumps.1.glsl
├── Ls_Lumps.1.glsl.p
├── Ls_Lumps.10.glsl
├── Ls_Lumps.2.glsl
├── Ls_Lumps.3.glsl
├── Ls_Lumps.4.glsl
├── Ls_Lumps.5.glsl
├── Ls_Lumps.6.glsl
├── Ls_Lumps.7.glsl
├── Ls_Lumps.8.glsl
├── Ls_Lumps.9.glsl
├── Ls_Lumps.xml
├── Ls_NaNfix.glsl
├── Ls_NaNfix.glsl.p
├── Ls_NaNfix.xml
├── Ls_Nail.glsl
├── Ls_Nail.glsl.p
├── Ls_Nail.xml
├── Ls_Pentatone.glsl
├── Ls_Pentatone.xml
├── Ls_Poly.01.glsl
├── Ls_Poly.01.glsl.p
├── Ls_Poly.02.glsl
├── Ls_Poly.03.glsl
├── Ls_Poly.04.glsl
├── Ls_Poly.05.glsl
├── Ls_Poly.06.glsl
├── Ls_Poly.07.glsl
├── Ls_Poly.08.glsl
├── Ls_Poly.09.glsl
├── Ls_Poly.10.glsl
├── Ls_Poly.11.glsl
├── Ls_Poly.12.glsl
├── Ls_Poly.13.glsl
├── Ls_Poly.14.glsl
├── Ls_Poly.15.glsl
├── Ls_Poly.16.glsl
├── Ls_Poly.17.glsl
├── Ls_Poly.18.glsl
├── Ls_Poly.19.glsl
├── Ls_Poly.20.glsl
├── Ls_Poly.21.glsl
├── Ls_Poly.22.glsl
├── Ls_Poly.23.glsl
├── Ls_Poly.24.glsl
├── Ls_Poly.25.glsl
├── Ls_Poly.26.glsl
├── Ls_Poly.27.glsl
├── Ls_Poly.28.glsl
├── Ls_Poly.29.glsl
├── Ls_Poly.xml
├── Ls_Poly_builder.py
├── Ls_Posmatte.glsl
├── Ls_Posmatte.glsl.p
├── Ls_Posmatte.xml
├── Ls_Relax.glsl
├── Ls_Relax.glsl.p
├── Ls_Relax.xml
├── Ls_RndmGrade.glsl
├── Ls_RndmGrade.glsl.p
├── Ls_RndmGrade.xml
├── Ls_Shadowplate.1.glsl
├── Ls_Shadowplate.1.glsl.p
├── Ls_Shadowplate.2.glsl
├── Ls_Shadowplate.3.glsl
├── Ls_Shadowplate.4.glsl
├── Ls_Shadowplate.xml
├── Ls_Splineblur.1.glsl
├── Ls_Splineblur.1.glsl.p
├── Ls_Splineblur.2.glsl
├── Ls_Splineblur.xml
├── Ls_Stickon.1.glsl
├── Ls_Stickon.1.glsl.p
├── Ls_Stickon.2.glsl
├── Ls_Stickon.xml
├── Ls_Sweat.1.glsl
├── Ls_Sweat.1.glsl.p
├── Ls_Sweat.2.glsl
├── Ls_Sweat.3.glsl
├── Ls_Sweat.4.glsl
├── Ls_Sweat.xml
├── Ls_Tinyplanet.glsl
├── Ls_Tinyplanet.glsl.p
├── Ls_Tinyplanet.xml
├── Ls_UVewa.glsl
├── Ls_UVewa.glsl.p
├── Ls_UVewa.xml
├── Ls_Vignette.glsl
├── Ls_Vignette.glsl.p
├── Ls_Vignette.xml
├── Ls_Vops.glsl
├── Ls_Vops.glsl.p
├── Ls_Vops.xml
├── Ls_Wireless.glsl
├── Ls_Wireless.glsl.p
└── Ls_Wireless.xml
/Ls_Advect.1.glsl:
--------------------------------------------------------------------------------
1 | // Pass 1: make the vectors
2 | // lewis@lewissaunders.com
3 | // TODO:
4 | // o Pre-blur input in case of kinks?
5 |
6 | uniform sampler2D map;
7 | uniform float adsk_result_w, adsk_result_h, ksize;
8 | uniform bool radial, directvectors;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 |
13 | // Factor to convert pixels to [0,1] texture coords
14 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
15 |
16 | vec2 d = vec2(0.0);
17 |
18 | if(directvectors) {
19 | // Map input is already vectors, yay!
20 | d = texture2D(map, xy * px).xy;
21 | if(radial) {
22 | // Rotate 90 degrees
23 | d = vec2(-d.y, d.x);
24 | }
25 | gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);
26 | return;
27 | }
28 |
29 | // Convolve by x and y Sobel matrices to get gradient vector
30 | d.x = 1.0 * texture2D(map, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
31 | d.x += 2.0 * texture2D(map, (xy + ksize * vec2(-1.0, 0.0)) * px).g;
32 | d.x += 1.0 * texture2D(map, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
33 | d.x += -1.0 * texture2D(map, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
34 | d.x += -2.0 * texture2D(map, (xy + ksize * vec2(+1.0, 0.0)) * px).g;
35 | d.x += -1.0 * texture2D(map, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
36 | d.y += 1.0 * texture2D(map, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
37 | d.y += 2.0 * texture2D(map, (xy + ksize * vec2( 0.0, -1.0)) * px).g;
38 | d.y += 1.0 * texture2D(map, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
39 | d.y += -1.0 * texture2D(map, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
40 | d.y += -2.0 * texture2D(map, (xy + ksize * vec2( 0.0, +1.0)) * px).g;
41 | d.y += -1.0 * texture2D(map, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
42 |
43 | if(!radial) {
44 | // Rotate 90 degrees
45 | d = vec2(-d.y, d.x);
46 | }
47 |
48 | // Bit of a bodge factor right here
49 | d *= 32.0 / ksize;
50 |
51 | // Output vectors for second pass
52 | gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);
53 | }
54 |
--------------------------------------------------------------------------------
/Ls_Advect.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Advect.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Advect.2.glsl:
--------------------------------------------------------------------------------
1 | // Pass 2: do the displace
2 | // TODO:
3 | // o Diffuse samples out along/around path direction?
4 | // lewis@lewissaunders.com
5 |
6 | uniform sampler2D front, map, adsk_results_pass1;
7 | uniform float adsk_result_w, adsk_result_h, blength, spacing, maxlength, sidestep;
8 | uniform vec2 offset;
9 | uniform int samples, oversamples;
10 | uniform vec2 bl, tr;
11 | uniform bool radial, vectors, normalize, adsk_degrade, fadeout, fadein;
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy;
15 |
16 | // Factor to convert pixels to [0,1] texture coords
17 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
18 |
19 | // Get vectors from previous pass
20 | vec2 d = texture2D(adsk_results_pass1, xy * px).xy;
21 |
22 | if(vectors) {
23 | // Return the vectors, not the blur
24 | if(normalize) {
25 | // Bodge factor for a resonable result from PixelSpread
26 | d /= 4.0;
27 | d += 0.5;
28 | gl_FragColor = vec4(d.x, d.y, 1.0, 1.0);
29 | } else {
30 | gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);
31 | }
32 | return;
33 | }
34 |
35 | // Crop
36 | vec2 xyn = xy * px;
37 | if((xyn.x < bl.x) || (xyn.x > tr.x)) {
38 | gl_FragColor = texture2D(front, xyn);
39 | gl_FragColor.a = 0.0;
40 | return;
41 | }
42 | if((xyn.y < bl.y) || (xyn.y > tr.y)) {
43 | gl_FragColor = texture2D(front, xyn);
44 | gl_FragColor.a = 0.0;
45 | return;
46 | }
47 |
48 | float sam = float(samples);
49 | if(adsk_degrade) {
50 | sam /= 4.0;
51 | }
52 |
53 | vec4 acc = vec4(0.0);
54 | for(int j = 0; j < oversamples; j++) {
55 | for(int k = 0; k < oversamples; k++) {
56 | // Starting point for this sample
57 | xy = gl_FragCoord.xy + spacing * vec2(float(j) / (float(oversamples) + 1.0), float(k) / (float(oversamples) + 1.0));
58 | float dist = 0.0;
59 | // Walk along path by sampling vector image, moving, sampling, moving...
60 | for(float i = 0.0; i < sam; i++) {
61 | d = texture2D(adsk_results_pass1, xy * px).xy;
62 | if(length(d) == 0.0) {
63 | // No gradient at this point in the map, early out
64 | break;
65 | }
66 | xy += d * (blength/sam) + blength * sidestep/1000.0 * vec2(-d.y, d.x) + (blength/32.0) * offset;
67 | dist += length(d * (blength/sam));
68 | }
69 | // Sample front image where our walk ended up
70 | acc.rgb += texture2D(front, xy * px).rgb;
71 |
72 | // Diffusion?
73 | /*for(float ix = 0.0; ix < diffusion; ix++) {
74 | for(float iy = 0.0; iy < diffusion; iy++) {
75 | acc.rgb += texture2D(front, (xy + vec2(ix, iy) * dist * px)).rgb * length(vec2(ix, iy)-vec2(diffusion/2.0, diffusion/2.0)) / (diffusion * diffusion * 32.0);
76 | }
77 | }*/
78 |
79 | // Length we've travelled to the matte output
80 | acc.a += dist * (blength/32.0);
81 | }
82 | }
83 | acc /= float(oversamples * oversamples);
84 |
85 | if(fadeout) {
86 | acc.rgb *= 1.0 - smoothstep(0.0, 1.0, abs(acc.a/(maxlength*blength+0.0001)));
87 | }
88 | if(fadein) {
89 | acc.rgb *= smoothstep(0.0, 1.0, abs(acc.a/(maxlength*blength)));
90 | }
91 |
92 | gl_FragColor = acc;
93 | }
94 |
--------------------------------------------------------------------------------
/Ls_Airglow.01.glsl:
--------------------------------------------------------------------------------
1 | // Airglow
2 | // This has a lot of passes. I used a little Python script to generate
3 | // most of them, because they're just a lot of Gaussian blurring
4 | // See Ls_Airglow_builder.py
5 | //
6 | // TODO:
7 | // o Clamp when in video de-tonemapping mode
8 | // o Negate image before/after for "black promist" effect
9 | //
10 | // Pass 1: multiply front RGB and glow source A together
11 | // lewis@lewissaunders.com
12 |
13 | uniform sampler2D front, source;
14 | uniform float adsk_result_w, adsk_result_h;
15 | uniform int colourspace;
16 | vec3 adsk_log2scene(vec3 log);
17 | vec3 adsk_scene2log(vec3 lin);
18 |
19 | // Convert from linear to video a simple, invertible way, but with smooth highlight rolloff
20 | vec3 tonemap(vec3 x) {
21 | x = max(x, 0.0);
22 | x = adsk_scene2log(x);
23 | x -= 95.0 / 1023.0;
24 | x *= 3.14159265;
25 | x = cos(x);
26 | x = 1.0 - x;
27 | x /= 2.0;
28 | x = max(x, 0.0);
29 | return x;
30 | }
31 |
32 | // Convert from video to linear, the inverse of above - unrolls highlights to above 1.0
33 | vec3 untonemap(vec3 x) {
34 | x = max(x, 0.0);
35 | x *= 2.0;
36 | x = 1.0 - x;
37 | x = acos(x);
38 | x /= 3.14159265;
39 | x += 95.0 / 1023.0;
40 | x = max(x, 0.0);
41 | x = adsk_log2scene(x);
42 | x = max(x, 0.0);
43 | return x;
44 | }
45 |
46 | void main() {
47 | vec2 res = vec2(adsk_result_w, adsk_result_h);
48 | vec2 xy = gl_FragCoord.xy / res;
49 | float m = texture2D(source, xy).b;
50 | vec3 f = texture2D(front, xy).rgb;
51 |
52 | // Convert to linear
53 | if(colourspace == 0) {
54 | // Log
55 | f = adsk_log2scene(f);
56 | } else if(colourspace == 1) {
57 | // Video - inverse tonemapping to get some highlights back
58 | f = untonemap(f);
59 | } else if(colourspace == 2) {
60 | // Video (gamma only)
61 | f = max(f, 0.0);
62 | f.r = pow(f.r, 2.4);
63 | f.g = pow(f.g, 2.4);
64 | f.b = pow(f.b, 2.4);
65 | } else if(colourspace == 3) {
66 | // Linear
67 | f = f;
68 | }
69 |
70 | f *= m;
71 |
72 | gl_FragColor = vec4(f, m);
73 | }
74 |
--------------------------------------------------------------------------------
/Ls_Airglow.01.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Airglow.01.glsl.p
--------------------------------------------------------------------------------
/Ls_Airglow.02.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 2: accelerated Gaussian blur, size / 1.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 1.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.03.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 3: accelerated Gaussian blur, size / 1.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass2;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 1.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass2, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.04.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 4: accelerated Gaussian blur, size / 2.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 2.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.05.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 5: accelerated Gaussian blur, size / 2.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass4;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 2.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass4, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.06.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 6: accelerated Gaussian blur, size / 4.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 4.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.07.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 7: accelerated Gaussian blur, size / 4.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass6;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 4.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass6, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.08.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 8: accelerated Gaussian blur, size / 8.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 8.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.09.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 9: accelerated Gaussian blur, size / 8.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass8;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 8.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass8, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.10.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 10: accelerated Gaussian blur, size / 16.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 16.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.11.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 11: accelerated Gaussian blur, size / 16.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass10;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 16.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass10, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.12.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 12: accelerated Gaussian blur, size / 32.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 32.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.13.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 13: accelerated Gaussian blur, size / 32.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass12;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 32.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass12, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.14.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 14: accelerated Gaussian blur, size / 64.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 64.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.15.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 15: accelerated Gaussian blur, size / 64.000000, direction vec2(0.0, 1.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass14;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 64.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass14, downlod, downxy, downres, downs, downs, downs, downs, vec2(0.0, 1.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Airglow.16.glsl:
--------------------------------------------------------------------------------
1 | // Airglow pass 16: accelerated Gaussian blur, size / 128.000000, direction vec2(1.0, 0.0)
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D strength, adsk_results_pass1;
7 | uniform float size, quality;
8 | uniform float adsk_result_w, adsk_result_h;
9 |
10 | // Return a 1D Gaussian blur from texture tex, sampling from mipmap level lod
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(sampler2D tex, float lod, vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs. We don't actually use that here because
22 | // doing both small and large blurs in one pass ruins the mipmap acceleration
23 | // trick - it means we always have to size the mipmap for the smallest blurs
24 | // which makes the large ones really slow
25 | vec4 gx = vec4(0.0);
26 | vec4 gy = vec4(0.0);
27 | vec4 gz = vec4(0.0);
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | vec4 a = vec4(0.0);
32 | vec4 centre = vec4(0.0);
33 | vec4 sample1 = vec4(0.0);
34 | vec4 sample2 = vec4(0.0);
35 |
36 | // First take the centre sample
37 | sample1 = texture2DLod(tex, xy / res, lod);
38 | a += gx * sample1;
39 | vec4 energy = gx;
40 | gx *= gy;
41 | gy *= gz;
42 |
43 | // Now the other samples
44 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
45 | for(float i = 1.0; i <= support; i++) {
46 | sample1 = texture2DLod(tex, (xy - i * dir) / res, lod);
47 | sample2 = texture2DLod(tex, (xy + i * dir) / res, lod);
48 | a += gx * sample1;
49 | a += gx * sample2;
50 | energy += 2.0 * gx;
51 | gx *= gy;
52 | gy *= gz;
53 | }
54 |
55 | return a / energy;
56 | }
57 |
58 | void main() {
59 | vec2 res = vec2(adsk_result_w, adsk_result_h);
60 | float strength = texture2D(strength, gl_FragCoord.xy / res).b;
61 |
62 | // We do the blur in two stages: a box filter downres followed by a proper
63 | // Gaussian blur on that low res image. We get the downres for free
64 | // from the mipmaps of the texture, fetching from that mip level inside a normal
65 | // Gaussian convolution loop.
66 | // We balance the amount of downres against the amount of true convolution with
67 | // the quality parameter, which is the approximate size of the second stage blur
68 | // in pixels; it's not exact because the downres is limited to powers of two
69 | float s = max(size * strength / 128.000000, 0.0001);
70 | float downfactor = min(quality / s, 1.0);
71 | float downlod = floor(log2(1.0/downfactor));
72 | downfactor = 1.0 / pow(2.0, downlod);
73 | float downs = downfactor * s;
74 | vec2 downres = downfactor * res;
75 | vec2 downxy = downfactor * gl_FragCoord.xy;
76 |
77 | gl_FragColor = gaussianblur(adsk_results_pass1, downlod, downxy, downres, downs, downs, downs, downs, vec2(1.0, 0.0));
78 | }
79 |
--------------------------------------------------------------------------------
/Ls_Ash.1.glsl:
--------------------------------------------------------------------------------
1 | // Adaptive sharpening
2 | // Pass 1: edge detection
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D front;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float ksize, threshold;
8 |
9 | void main() {
10 | vec2 xy = gl_FragCoord.xy;
11 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
12 |
13 | vec4 orig = texture2D(front, xy * px);
14 |
15 | float ksize = 1.0;
16 |
17 | // Find gradients of front with X/Y Sobel convolution
18 | vec2 d;
19 | d.x = 1.0 * texture2D(front, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
20 | d.x += 2.0 * texture2D(front, (xy + ksize * vec2(-1.0, 0.0)) * px).g;
21 | d.x += 1.0 * texture2D(front, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
22 | d.x += -1.0 * texture2D(front, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
23 | d.x += -2.0 * texture2D(front, (xy + ksize * vec2(+1.0, 0.0)) * px).g;
24 | d.x += -1.0 * texture2D(front, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
25 | d.y = 1.0 * texture2D(front, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
26 | d.y += 2.0 * texture2D(front, (xy + ksize * vec2( 0.0, -1.0)) * px).g;
27 | d.y += 1.0 * texture2D(front, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
28 | d.y += -1.0 * texture2D(front, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
29 | d.y += -2.0 * texture2D(front, (xy + ksize * vec2( 0.0, +1.0)) * px).g;
30 | d.y += -1.0 * texture2D(front, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
31 |
32 | // Magnitude of gradients finds edges
33 | float mag = length(d);
34 | float edginess = mag;
35 |
36 | // Threshold removes minor edges
37 | edginess *= 1.0 - threshold;
38 | edginess -= threshold;
39 |
40 | gl_FragColor = vec4(orig.r, orig.g, orig.b, edginess);
41 | }
42 |
--------------------------------------------------------------------------------
/Ls_Ash.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Ash.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Ash.2.glsl:
--------------------------------------------------------------------------------
1 | // Adaptive sharpening
2 | // Pass 2: horizontal Gaussian blur
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass1;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float sigma;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | int support = int(sigma * 3.0);
15 |
16 | // Incremental coefficient calculation setup as per GPU Gems 3
17 | vec3 g;
18 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
19 | g.y = exp(-0.5 / (sigma * sigma));
20 | g.z = g.y * g.y;
21 |
22 | if(sigma == 0.0) {
23 | g.x = 1.0;
24 | }
25 |
26 | // Centre sample
27 | vec4 a = g.x * texture2D(adsk_results_pass1, xy * px);
28 | float energy = g.x;
29 | g.xy *= g.yz;
30 |
31 | // The rest
32 | for(int i = 1; i <= support; i++) {
33 | a += g.x * texture2D(adsk_results_pass1, (xy - vec2(float(i), 0.0)) * px);
34 | a += g.x * texture2D(adsk_results_pass1, (xy + vec2(float(i), 0.0)) * px);
35 | energy += 2.0 * g.x;
36 | g.xy *= g.yz;
37 | }
38 | a /= energy;
39 |
40 | gl_FragColor = a;
41 | }
42 |
--------------------------------------------------------------------------------
/Ls_Ash.3.glsl:
--------------------------------------------------------------------------------
1 | // Adaptive sharpening
2 | // Pass 2: vertical Gaussian blur, blend
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass2, front, strengthmap;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float sigma, strength;
8 | uniform bool adaptive, onlyedges, showedges;
9 | const float pi = 3.141592653589793238462643383279502884197969;
10 |
11 | void main() {
12 | vec2 xy = gl_FragCoord.xy;
13 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
14 |
15 | float strength_here = strength * texture2D(strengthmap, xy * px).b;
16 |
17 | int support = int(sigma * 3.0);
18 |
19 | // Incremental coefficient calculation setup as per GPU Gems 3
20 | vec3 g;
21 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
22 | g.y = exp(-0.5 / (sigma * sigma));
23 | g.z = g.y * g.y;
24 |
25 | if(sigma == 0.0) {
26 | g.x = 1.0;
27 | }
28 |
29 | // Centre sample
30 | vec4 a = g.x * texture2D(adsk_results_pass2, xy * px);
31 | float energy = g.x;
32 | g.xy *= g.yz;
33 |
34 | // The rest
35 | for(int i = 1; i <= support; i++) {
36 | a += g.x * texture2D(adsk_results_pass2, (xy - vec2(0.0, float(i))) * px);
37 | a += g.x * texture2D(adsk_results_pass2, (xy + vec2(0.0, float(i))) * px);
38 | energy += 2.0 * g.x;
39 | g.xy *= g.yz;
40 | }
41 | a /= energy;
42 | vec4 unsharp = a;
43 |
44 | // Inflate edge pass a little
45 | float edginess = clamp(unsharp.a * 3.0, 0.0, 1.0);
46 |
47 | if(onlyedges) {
48 | edginess = 1.0 - edginess;
49 | }
50 |
51 | // Sharpen
52 | vec4 orig = texture2D(front, xy * px);
53 | vec4 sharp = orig + vec4(strength_here) * (orig - unsharp);
54 |
55 | if(adaptive){
56 | // Remove sharpening from edges
57 | sharp = edginess * orig + (1.0 - edginess) * sharp;
58 | }
59 |
60 | if(showedges) {
61 | sharp = vec4(edginess);
62 | }
63 |
64 | gl_FragColor = vec4(sharp.r, sharp.g, sharp.b, 1.0);
65 | }
66 |
--------------------------------------------------------------------------------
/Ls_Bevel.1.glsl:
--------------------------------------------------------------------------------
1 | // Bevel
2 | // Pass 1: Dummy pass for front passthrough
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D front;
6 | uniform float adsk_result_w, adsk_result_h;
7 |
8 | void main() {
9 | vec2 xy = gl_FragCoord.xy;
10 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
11 |
12 | gl_FragColor = texture2D(front, xy * px);
13 | }
14 |
--------------------------------------------------------------------------------
/Ls_Bevel.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Bevel.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Bevel.2.glsl:
--------------------------------------------------------------------------------
1 | // Bevel
2 | // Pass 2: horizontal Gaussian blur
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass1;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float sigma;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | int support = int(sigma * 3.0);
15 |
16 | // Incremental coefficient calculation setup as per GPU Gems 3
17 | vec3 g;
18 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
19 | g.y = exp(-0.5 / (sigma * sigma));
20 | g.z = g.y * g.y;
21 |
22 | if(sigma == 0.0) {
23 | g.x = 1.0;
24 | }
25 |
26 | // Centre sample
27 | vec4 a = g.x * texture2D(adsk_results_pass1, xy * px);
28 | float energy = g.x;
29 | g.xy *= g.yz;
30 |
31 | // The rest
32 | for(int i = 1; i <= support; i++) {
33 | a += g.x * texture2D(adsk_results_pass1, (xy - vec2(float(i), 0.0)) * px);
34 | a += g.x * texture2D(adsk_results_pass1, (xy + vec2(float(i), 0.0)) * px);
35 | energy += 2.0 * g.x;
36 | g.xy *= g.yz;
37 | }
38 | a /= energy;
39 |
40 | gl_FragColor = a;
41 | }
42 |
--------------------------------------------------------------------------------
/Ls_Bevel.3.glsl:
--------------------------------------------------------------------------------
1 | // Bevel
2 | // Pass 3: vertical Gaussian blur
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass2;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float sigma;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | int support = int(sigma * 3.0);
15 |
16 | // Incremental coefficient calculation setup as per GPU Gems 3
17 | vec3 g;
18 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
19 | g.y = exp(-0.5 / (sigma * sigma));
20 | g.z = g.y * g.y;
21 |
22 | if(sigma == 0.0) {
23 | g.x = 1.0;
24 | }
25 |
26 | // Centre sample
27 | vec4 a = g.x * texture2D(adsk_results_pass2, xy * px);
28 | float energy = g.x;
29 | g.xy *= g.yz;
30 |
31 | // The rest
32 | for(int i = 1; i <= support; i++) {
33 | a += g.x * texture2D(adsk_results_pass2, (xy - vec2(0.0, float(i))) * px);
34 | a += g.x * texture2D(adsk_results_pass2, (xy + vec2(0.0, float(i))) * px);
35 | energy += 2.0 * g.x;
36 | g.xy *= g.yz;
37 | }
38 | a /= energy;
39 | vec4 unsharp = a;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Bevel.4.glsl:
--------------------------------------------------------------------------------
1 | // Bevel
2 | // Pass 4: gradient detection and actual beveling
3 | // Broadly, we use the gradient vector of the blurred
4 | // image as the X/Y components of a normal vector, which
5 | // we then dot with the light direction.
6 | // To get the sharp edge, we normalize the gradient, then
7 | // use smoothstep() to remove the nasty artifacts where
8 | // it was near zero. This gives us a kinda level-set iso-line
9 | // of the blurred image, which roughly follows the outline of
10 | // the text. It ain't perfect!
11 | //
12 | // This pass outputs the bevel based on the "Height map" input
13 | //
14 | // lewis@lewissaunders.com
15 |
16 | uniform sampler2D adsk_results_pass3, adsk_results_pass1;
17 | uniform float adsk_result_w, adsk_result_h;
18 | uniform float sigma, ambient, smoothy;
19 | uniform vec3 lite;
20 | uniform bool normals;
21 |
22 | void main() {
23 | vec2 xy = gl_FragCoord.xy;
24 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
25 | float fron = texture2D(adsk_results_pass1, xy * px).g;
26 |
27 | // Find gradients with X/Y Sobel convolution
28 | vec2 d;
29 | float ksize = sigma/2.0;
30 | d.x = 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
31 | d.x += 2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, 0.0)) * px).g;
32 | d.x += 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
33 | d.x += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
34 | d.x += -2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, 0.0)) * px).g;
35 | d.x += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
36 | d.y = 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
37 | d.y += 2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2( 0.0, -1.0)) * px).g;
38 | d.y += 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
39 | d.y += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
40 | d.y += -2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2( 0.0, +1.0)) * px).g;
41 | d.y += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
42 | d /= ksize;
43 |
44 | float len = length(d);
45 | float edge = smoothstep(0.0, smoothy/100.0, len);
46 |
47 | d /= len + 0.0001;
48 |
49 | float l = dot(d, normalize(lite.xy - vec2(0.5)));
50 | l = mix(l, fron, ambient);
51 | l = mix(ambient * fron, l, edge);
52 | l *= fron;
53 |
54 | vec4 o = vec4(l, l, l, fron);
55 |
56 | gl_FragColor = o;
57 | }
58 |
--------------------------------------------------------------------------------
/Ls_Bevel.5.glsl:
--------------------------------------------------------------------------------
1 | // Bevel
2 | // Pass 5: gradient detection and actual beveling
3 | // Broadly, we use the gradient vector of the blurred
4 | // image as the X/Y components of a normal vector, which
5 | // we then dot with the light direction.
6 | // To get the sharp edge, we normalize the gradient, then
7 | // use smoothstep() to remove the nasty artifacts where
8 | // it was near zero. This gives us a kinda level-set iso-line
9 | // of the blurred image, which roughly follows the outline of
10 | // the text. It ain't perfect!
11 | //
12 | // This pass outputs the normals of the bevel based on the
13 | // "Height map" input
14 | //
15 | // lewis@lewissaunders.com
16 |
17 | uniform sampler2D adsk_results_pass3, adsk_results_pass1;
18 | uniform float adsk_result_w, adsk_result_h;
19 | uniform float sigma, smoothy;
20 | uniform bool normals;
21 |
22 |
23 | void main() {
24 | vec2 xy = gl_FragCoord.xy;
25 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
26 | float fron = texture2D(adsk_results_pass1, xy * px).g;
27 |
28 | // Find gradients with X/Y Sobel convolution
29 | vec2 d;
30 | float ksize = sigma/2.0;
31 | d.x = 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
32 | d.x += 2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, 0.0)) * px).g;
33 | d.x += 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
34 | d.x += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
35 | d.x += -2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, 0.0)) * px).g;
36 | d.x += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
37 | d.y = 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
38 | d.y += 2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2( 0.0, -1.0)) * px).g;
39 | d.y += 1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
40 | d.y += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
41 | d.y += -2.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2( 0.0, +1.0)) * px).g;
42 | d.y += -1.0 * texture2D(adsk_results_pass3, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
43 | d /= ksize;
44 |
45 | float len = length(d);
46 | float edge = smoothstep(0.0, smoothy/100.0, len);
47 |
48 | d /= len + 0.0001;
49 |
50 | vec3 n = vec3(d.x, d.y, 1.0);
51 | n = mix(vec3(0.0, 0.0, 1.0), n, edge);
52 | gl_FragColor = vec4(n, fron);
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Ls_Bevel.6.glsl:
--------------------------------------------------------------------------------
1 | // Bevel
2 | // Pass 6: Multiply the bevel pass output by the back, and comp
3 | // over the back using the matte
4 | // graphistesmoke@gmail.com (Sébastien DELECOUR / Sebquismoke)
5 |
6 | uniform sampler2D adsk_results_pass4, adsk_results_pass5, back, matte;
7 | uniform float adsk_result_w, adsk_result_h;
8 | uniform bool normals;
9 |
10 |
11 | void main() {
12 | vec2 xy = gl_FragCoord.xy;
13 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
14 | vec3 matte = texture2D(matte, xy * px).rgb;
15 | vec3 back = texture2D(back, xy * px).rgb;
16 | vec3 bevel = texture2D(adsk_results_pass4, xy * px).rgb;
17 | vec3 bevelnormals = texture2D(adsk_results_pass5, xy * px).rgb;
18 |
19 | if(normals) {
20 | gl_FragColor = vec4(bevelnormals.rgb, matte.g);
21 | return;
22 | }
23 |
24 | vec3 o = mix(back, back*bevel, matte.g);
25 |
26 | gl_FragColor = vec4(o, matte.g);
27 | }
28 |
--------------------------------------------------------------------------------
/Ls_Chips.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Chips.glsl.p
--------------------------------------------------------------------------------
/Ls_Chips.hip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Chips.hip
--------------------------------------------------------------------------------
/Ls_Chips.mx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Chips.mx
--------------------------------------------------------------------------------
/Ls_Chips.textureGrid.exr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Chips.textureGrid.exr
--------------------------------------------------------------------------------
/Ls_Colourmatrix.glsl:
--------------------------------------------------------------------------------
1 | // Colour matrix shader for Matchbox
2 | // I apologise for the incredibly stupid variable names but it's 3am yo
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D input1, strength;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float r2r, r2g, r2b, g2r, g2g, g2b, b2r, b2g, b2b;
8 | uniform vec3 or, og, ob, ir, ig, ib;
9 | uniform float effect, gain, mixx;
10 |
11 | void main() {
12 | vec2 coords = gl_FragCoord.xy / vec2(adsk_result_w, adsk_result_h);
13 | float mixx_here = mixx * texture2D(strength, coords).r;
14 | vec3 i = texture2D(input1, coords).rgb;
15 | vec3 ii = vec3(r2r*i.r + g2r*i.g + b2r*i.b, r2g*i.r + g2g*i.g + b2g*i.b, r2b*i.r + g2b*i.g + b2b*i.b);
16 | vec3 iii = ii * mat3(or, og, ob);
17 | vec3 iv = mat3(ir, ig, ib) * iii;
18 | vec3 v = effect*iv + (1.0-effect)*i;
19 | vec3 vi = gain * v;
20 | vec3 vii = mixx_here*vi + (1.0-mixx_here)*i;
21 | gl_FragColor = vec4(vii, 1.0);
22 | }
23 |
--------------------------------------------------------------------------------
/Ls_Colourmatrix.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Colourmatrix.glsl.p
--------------------------------------------------------------------------------
/Ls_Colourspace.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Colourspace.glsl.p
--------------------------------------------------------------------------------
/Ls_Contacts.glsl:
--------------------------------------------------------------------------------
1 | // Tiles the inputs into a grid for impressing clients
2 | // lewis@lewissaunders.com
3 | // TODO:
4 | // o Nonsquare pixels support... eek
5 | // o Variable width borders look gross, how can we get a nice even spacing?
6 |
7 | uniform sampler2D in1, in2, in3, in4, in5, in6;
8 | uniform int rows, cols, randomcount, seed;
9 | uniform bool random, perframe, filltiles;
10 | uniform float scale;
11 | uniform float adsk_result_w, adsk_result_h, adsk_time;
12 |
13 | // Mysterious dirty random number generator
14 | float rand(vec2 co){
15 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
16 | }
17 |
18 | void main() {
19 | vec2 coords = gl_FragCoord.xy / vec2(adsk_result_w, adsk_result_h);
20 | vec2 tilecoords = vec2(0.0, 0.0);
21 | vec4 o = vec4(0.0);
22 | float aspectdiff, tilew, tileh;
23 | int tilex, tiley, tileidx;
24 |
25 | // Figure out how big each tile will be, and which tile we're in
26 | tilew = adsk_result_w / float(cols);
27 | tileh = adsk_result_h / float(rows);
28 | tilex = int(gl_FragCoord.x / tilew);
29 | tiley = int((adsk_result_h - gl_FragCoord.y) / tileh);
30 | tileidx = tiley * cols + tilex;
31 |
32 | // Randomize the tile index
33 | if(random) {
34 | if(perframe) {
35 | tileidx = int(rand(vec2(float(tilex - seed), float(tiley) + 1234.0 * adsk_time)) * float(randomcount));
36 | } else {
37 | tileidx = int(rand(vec2(float(tilex - seed), float(tiley))) * float(randomcount));
38 | }
39 | }
40 |
41 | // Get current coordinates within this tile
42 | tilecoords.x = mod(gl_FragCoord.x, tilew) / tilew;
43 | tilecoords.y = mod(gl_FragCoord.y, tileh) / tileh;
44 |
45 | // Scale coordinates about the centre of each tile to maintain proportions and do fit/fill
46 | tilecoords -= vec2(0.5);
47 | tilecoords *= 100.0 / scale;
48 | aspectdiff = (tilew / tileh) / (adsk_result_w / adsk_result_h);
49 | if(aspectdiff > 1.0) {
50 | tilecoords.x *= aspectdiff;
51 | if(filltiles) {
52 | tilecoords /= aspectdiff;
53 | }
54 | } else {
55 | tilecoords.y /= aspectdiff;
56 | if(filltiles) {
57 | tilecoords *= aspectdiff;
58 | }
59 | }
60 | tilecoords += vec2(0.5);
61 |
62 | // Finally grab input for the tile we're in
63 | if(tileidx == 0) {
64 | o = texture2D(in1, tilecoords);
65 | } else if(tileidx == 1) {
66 | o = texture2D(in2, tilecoords);
67 | } else if(tileidx == 2) {
68 | o = texture2D(in3, tilecoords);
69 | } else if(tileidx == 3) {
70 | o = texture2D(in4, tilecoords);
71 | } else if(tileidx == 4) {
72 | o = texture2D(in5, tilecoords);
73 | } else if(tileidx == 5) {
74 | o = texture2D(in6, tilecoords);
75 | }
76 |
77 | // Draw black if we're in a border area
78 | if((tilecoords.x <= 0.0) || (tilecoords.x > 1.0)) {
79 | o = vec4(0.0);
80 | }
81 | if((tilecoords.y <= 0.0) || (tilecoords.y > 1.0)) {
82 | o = vec4(0.0);
83 | }
84 |
85 | gl_FragColor = o;
86 | }
87 |
--------------------------------------------------------------------------------
/Ls_Contacts.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Contacts.glsl.p
--------------------------------------------------------------------------------
/Ls_Dilate.1.glsl:
--------------------------------------------------------------------------------
1 | #version 120
2 |
3 | // Morphological dilate/erode using non-flat structuring elements
4 | // (see https://www.mathworks.com/help/images/structuring-elements.html)
5 |
6 | uniform sampler2D front, strength, cleanscreen;
7 | uniform float size, stretch;
8 | uniform int kernel;
9 | uniform bool usecolour, usecleanscreen;
10 | uniform vec3 screencolour;
11 | uniform float adsk_result_w, adsk_result_h;
12 | vec2 res = vec2(adsk_result_w, adsk_result_h);
13 |
14 | void main(void) {
15 | vec2 xy = gl_FragCoord.xy;
16 | vec2 sizexy = mix(vec2(2.0, 0.0), vec2(0.0, 2.0), stretch) * texture2D(strength, xy / res).b * size;
17 | vec3 screencol = usecleanscreen ? texture2D(cleanscreen, xy / res).rgb : screencolour;
18 |
19 | // Centre sample
20 | vec3 best = texture2D(front, xy / res).rgb + sign(sizexy.x) * vec3(1.0);
21 | if(usecolour) {
22 | // Ignore weighting if using colour
23 | best -= sign(sizexy.x) * vec3(1.0);
24 | }
25 | float bestdist = distance(best, screencol);
26 |
27 | // The rest
28 | int support = int(abs(sizexy.x) * 3.0);
29 | for(int i = 1; i <= support; i++) {
30 | float weight = 0.0;
31 | float x = float(i) / abs(sizexy.x);
32 | if(kernel == 0) {
33 | // Box
34 | weight = x < 1.0 ? 1.0 : 0.0;
35 | } else if(kernel == 1) {
36 | // Box AA
37 | if(x < 1.0) {
38 | weight = 1.0;
39 | } else if(x < 1.0 + (1.0 / abs(sizexy.x))) {
40 | weight = 1.0 - ((x - 1.0) / (1.0 / abs(sizexy.x)));
41 | } else {
42 | weight = 0.0;
43 | }
44 | } else if(kernel == 2) {
45 | // Triangle
46 | weight = 1.0 - clamp(x, 0.0, 1.0);
47 | } else if(kernel == 3) {
48 | // Ball
49 | weight = sqrt(1 - pow(clamp(x, 0.0, 1.0), 2));
50 | } else if(kernel == 4) {
51 | // Gaussian
52 | weight = exp(-0.5 * pow(x, 2));
53 | }
54 | // Add weights to pixel values before comparison
55 | vec3 a = texture2D(front, (xy - vec2(float(i), 0.0)) / res).rgb + sign(sizexy.x) * vec3(weight);
56 | vec3 b = texture2D(front, (xy + vec2(float(i), 0.0)) / res).rgb + sign(sizexy.x) * vec3(weight);
57 | if(usecolour) {
58 | // Ignore outer parts of support to match non-colour mode box kernel size
59 | if(x > 1.0) break;
60 |
61 | // Ignore weighting if using colour
62 | a -= sign(sizexy.x) * vec3(weight);
63 | b -= sign(sizexy.x) * vec3(weight);
64 | float adist = distance(a, screencol);
65 | float bdist = distance(b, screencol);
66 | if(sizexy.x > 0.0) {
67 | if(adist < bestdist) {
68 | best = a;
69 | bestdist = adist;
70 | }
71 | if(bdist < bestdist) {
72 | best = b;
73 | bestdist = bdist;
74 | }
75 | } else {
76 | if(adist > bestdist) {
77 | best = a;
78 | bestdist = adist;
79 | }
80 | if(bdist > bestdist) {
81 | best = b;
82 | bestdist = bdist;
83 | }
84 | }
85 | } else {
86 | if(sizexy.x > 0.0) {
87 | best = max(best, a);
88 | best = max(best, b);
89 | } else {
90 | best = min(best, a);
91 | best = min(best, b);
92 | }
93 | }
94 | }
95 |
96 | gl_FragColor = vec4(best.r, best.g, best.b, 0.0);
97 | }
98 |
--------------------------------------------------------------------------------
/Ls_Dilate.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Dilate.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Dilate.2.glsl:
--------------------------------------------------------------------------------
1 | #version 120
2 |
3 | uniform sampler2D adsk_results_pass1, strength, cleanscreen;
4 | uniform float size, stretch;
5 | uniform int kernel;
6 | uniform bool usecolour, usecleanscreen;
7 | uniform vec3 screencolour;
8 | uniform float adsk_result_w, adsk_result_h;
9 | vec2 res = vec2(adsk_result_w, adsk_result_h);
10 |
11 | void main(void) {
12 | vec2 xy = gl_FragCoord.xy;
13 | vec2 sizexy = mix(vec2(2.0, 0.0), vec2(0.0, 2.0), stretch) * texture2D(strength, xy / res).b * size;
14 | vec3 screencol = usecleanscreen ? texture2D(cleanscreen, xy / res).rgb : screencolour;
15 |
16 | // Centre sample
17 | vec3 best = texture2D(adsk_results_pass1, xy / res).rgb + sign(sizexy.y) * vec3(1.0);
18 | if(usecolour) {
19 | // Ignore weighting if using colour
20 | best -= sign(sizexy.y) * vec3(1.0);
21 | }
22 | float bestdist = distance(best, screencol);
23 |
24 | // The rest
25 | int support = int(abs(sizexy.y) * 3.0);
26 | for(int i = 1; i <= support; i++) {
27 | float weight = 0.0;
28 | float x = float(i) / abs(sizexy.y);
29 | if(kernel == 0) {
30 | // Box
31 | weight = x < 1.0 ? 1.0 : 0.0;
32 | } else if(kernel == 1) {
33 | // Box AA
34 | if(x < 1.0) {
35 | weight = 1.0;
36 | } else if(x < 1.0 + (1.0 / abs(sizexy.y))) {
37 | weight = 1.0 - ((x - 1.0) / (1.0 / abs(sizexy.y)));
38 | } else {
39 | weight = 0.0;
40 | }
41 | } else if(kernel == 2) {
42 | // Triangle
43 | weight = 1.0 - clamp(x, 0.0, 1.0);
44 | } else if(kernel == 3) {
45 | // Ball
46 | weight = sqrt(1 - pow(clamp(x, 0.0, 1.0), 2));
47 | } else if(kernel == 4) {
48 | // Gaussian
49 | weight = exp(-0.5 * pow(x, 2));
50 | }
51 | // Add weights to pixel values before comparison
52 | vec3 a = texture2D(adsk_results_pass1, (xy - vec2(0.0, float(i))) / res).rgb + sign(sizexy.y) * vec3(weight);
53 | vec3 b = texture2D(adsk_results_pass1, (xy + vec2(0.0, float(i))) / res).rgb + sign(sizexy.y) * vec3(weight);
54 | if(usecolour) {
55 | // Ignore outer parts of support to match non-colour mode box kernel size
56 | if(x > 1.0) break;
57 |
58 | // Ignore weighting if using colour
59 | a -= sign(sizexy.y) * vec3(weight);
60 | b -= sign(sizexy.y) * vec3(weight);
61 | float adist = distance(a, screencol);
62 | float bdist = distance(b, screencol);
63 | if(sizexy.x > 0.0) {
64 | if(adist < bestdist) {
65 | best = a;
66 | bestdist = adist;
67 | }
68 | if(bdist < bestdist) {
69 | best = b;
70 | bestdist = bdist;
71 | }
72 | } else {
73 | if(adist > bestdist) {
74 | best = a;
75 | bestdist = adist;
76 | }
77 | if(bdist > bestdist) {
78 | best = b;
79 | bestdist = bdist;
80 | }
81 | }
82 | } else {
83 | if(sizexy.y > 0.0) {
84 | best = max(best, a);
85 | best = max(best, b);
86 | } else {
87 | best = min(best, a);
88 | best = min(best, b);
89 | }
90 | }
91 | }
92 |
93 | if(!usecolour) {
94 | // Remove weights from final output
95 | if(sizexy.y > 0.0) {
96 | best -= vec3(2.0);
97 | } else {
98 | best += vec3(2.0);
99 | }
100 | }
101 |
102 | gl_FragColor = vec4(best.r, best.g, best.b, 0.0);
103 | }
104 |
--------------------------------------------------------------------------------
/Ls_Dollface.1.glsl:
--------------------------------------------------------------------------------
1 | // Blur only similar pixels
2 | // Pass 2: horizontal blur
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D front, strength;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float sigma, threshold;
8 | uniform bool slow;
9 | uniform int quality;
10 | const float pi = 3.141592653589793238462643383279502884197969;
11 |
12 | void main() {
13 | vec2 xy = gl_FragCoord.xy;
14 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
15 |
16 | float strength_here = texture2D(strength, xy * px).b;
17 | float sigma_here = sigma * strength_here;
18 |
19 | int support = int(sigma_here * 3.0);
20 |
21 | float kernelhyp = length(vec2(support, support));
22 | float rgbhyp = length(vec3(1.0, 1.0, 1.0));
23 |
24 | if(slow) {
25 | // Use straightforward but slow algorithm
26 | vec4 centre = texture2D(front, xy * px);
27 |
28 | vec4 a = vec4(0.0);
29 | float energy = 0.0;
30 |
31 | float inc = pow(2.0, 3.0 - float(quality));
32 |
33 | // Factor to make apparant sharpness of two algorithms similar
34 | float m = 1.666;
35 |
36 | // Yes, this is brute force and dirty
37 | // Making bilateral filtering separable is really hard
38 | // c.f. any number of SIGGRAPH papers
39 | for(float x = -sigma_here * m; x <= sigma_here * m; x += inc) {
40 | for(float y = -sigma_here * m; y <= sigma_here * m; y += inc) {
41 | vec4 b = texture2D(front, (xy + vec2(x, y)) * px);
42 | b.a = 1.0;
43 |
44 | // Mult this sample by colour similarity
45 | float fac = 1.0 - (length(b - centre) / rgbhyp);
46 | fac = pow(fac, threshold);
47 | b *= clamp(fac, 0.001, 1.0);
48 |
49 | // Mult this sample by distance from centre, i.e. triangular kernel
50 | b *= kernelhyp - length(vec2(x, y));
51 |
52 | // Accumulate
53 | a += b;
54 | energy += b.a;
55 | }
56 | }
57 |
58 | if(energy < 0.05) {
59 | // No samples were taken!
60 | gl_FragColor = texture2D(front, xy * px);
61 | return;
62 | }
63 |
64 | a /= energy;
65 | gl_FragColor = a;
66 | return;
67 | }
68 |
69 | // Okay. On to complicated two-pass algorithm
70 | // Incremental coefficient calculation setup as per GPU Gems 3
71 | vec3 g;
72 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma_here);
73 | g.y = exp(-0.5 / (sigma_here * sigma_here));
74 | g.z = g.y * g.y;
75 |
76 | if(sigma_here == 0.0) {
77 | g.x = 1.0;
78 | }
79 |
80 | vec4 a, b, c;
81 | a = vec4(0.0);
82 | float fac, energy = 0.0;
83 |
84 | // Centre sample
85 | vec4 orig = texture2D(front, xy * px);
86 | a += g.x * orig;
87 | energy += g.x;
88 | g.xy *= g.yz;
89 |
90 | int inc = int(pow(2.0, 3.0 - float(quality)));
91 |
92 | // The rest
93 | for(int i = 1; i <= support; i += inc) {
94 | b = texture2D(front, (xy - vec2(float(i), 0.0)) * px);
95 | c = texture2D(front, (xy + vec2(float(i), 0.0)) * px);
96 |
97 | b.a = 1.0;
98 | c.a = 1.0;
99 |
100 | fac = 1.0 - (length(b - orig) / rgbhyp);
101 | fac = pow(fac, threshold);
102 | b *= g.x * clamp(fac, 0.001, 1.0);
103 | a += b;
104 | energy += b.a;
105 |
106 | fac = 1.0 - (length(c - orig) / rgbhyp);
107 | fac = pow(fac, threshold);
108 | c *= g.x * clamp(fac, 0.001, 1.0);
109 | a += c;
110 | energy += c.a;
111 |
112 | g.xy *= g.yz;
113 | }
114 | a /= energy;
115 |
116 | gl_FragColor = a;
117 | }
118 |
--------------------------------------------------------------------------------
/Ls_Dollface.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Dollface.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Dollface.2.glsl:
--------------------------------------------------------------------------------
1 | // Blur only similar pixels
2 | // Pass 2: vertical blur
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass1, strength;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float sigma, threshold;
8 | uniform bool slow;
9 | uniform int quality;
10 | const float pi = 3.141592653589793238462643383279502884197969;
11 |
12 | void main() {
13 | vec2 xy = gl_FragCoord.xy;
14 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
15 |
16 | float strength_here = texture2D(strength, xy * px).b;
17 | float sigma_here = sigma * strength_here;
18 |
19 | int support = int(sigma_here * 3.0);
20 |
21 | float kernelhyp = length(vec2(support, support));
22 | float rgbhyp = length(vec3(1.0, 1.0, 1.0));
23 |
24 | if(slow) {
25 | // Use pass 1 results and quit
26 | gl_FragColor = texture2D(adsk_results_pass1, xy * px);
27 | return;
28 | }
29 |
30 | // Incremental coefficient calculation setup as per GPU Gems 3
31 | vec3 g;
32 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma_here);
33 | g.y = exp(-0.5 / (sigma_here * sigma_here));
34 | g.z = g.y * g.y;
35 |
36 | if(sigma_here == 0.0) {
37 | g.x = 1.0;
38 | }
39 |
40 | vec4 a, b, c;
41 | a = vec4(0.0);
42 | float fac, energy = 0.0;
43 |
44 | // Centre sample
45 | vec4 orig = texture2D(adsk_results_pass1, xy * px);
46 | a += g.x * orig;
47 | energy += g.x;
48 | g.xy *= g.yz;
49 |
50 | int inc = int(pow(2.0, 3.0 - float(quality)));
51 |
52 | // The rest
53 | for(int i = 1; i <= support; i += inc) {
54 | b = texture2D(adsk_results_pass1, (xy - vec2(0.0, float(i))) * px);
55 | c = texture2D(adsk_results_pass1, (xy + vec2(0.0, float(i))) * px);
56 |
57 | b.a = 1.0;
58 | c.a = 1.0;
59 |
60 | fac = 1.0 - (length(b - orig) / rgbhyp);
61 | fac = pow(fac, threshold);
62 | b *= g.x * clamp(fac, 0.001, 1.0);
63 | a += b;
64 | energy += b.a;
65 |
66 | fac = 1.0 - (length(c - orig) / rgbhyp);
67 | fac = pow(fac, threshold);
68 | c *= g.x * clamp(fac, 0.001, 1.0);
69 | a += c;
70 | energy += c.a;
71 |
72 | g.xy *= g.yz;
73 | }
74 | a /= energy;
75 |
76 | gl_FragColor = a;
77 | }
78 |
--------------------------------------------------------------------------------
/Ls_Dollface.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Ls_FXAA.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_FXAA.glsl.p
--------------------------------------------------------------------------------
/Ls_FXAA.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Ls_Filmstrip.glsl:
--------------------------------------------------------------------------------
1 | // Filmstrip
2 | // Arranges input frames into a grid
3 | // TOOD: figure out why increasing border squashes picture...
4 | // lewis@lewissaunders.com
5 |
6 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, adsk_result_pixelratio;
7 | uniform float adsk_front_w, adsk_front_h, adsk_front_frameratio, adsk_front_pixelratio;
8 | uniform sampler2D front;
9 | uniform sampler2D adsk_accum_texture;
10 | uniform bool adsk_accum_no_prev_frame;
11 | uniform float adsk_time;
12 | uniform float cols;
13 | uniform float xborder;
14 | uniform bool allframes, centre;
15 |
16 | void main() {
17 | vec2 res = vec2(adsk_result_w, adsk_result_h);
18 | vec2 xy = gl_FragCoord.xy / res;
19 | xy.y = 1.0 - xy.y;
20 |
21 | // We want border widths the same horizontally and vertically
22 | vec2 border = vec2((xborder/1000.0), (xborder/1000.0) * adsk_result_frameratio);
23 |
24 | // How many rows can we fit of these columns?
25 | float rows = cols * adsk_front_frameratio / adsk_result_frameratio;
26 | float colsused = floor(cols);
27 | float rowsused = floor(rows);
28 | if(centre) {
29 | // If the rows and cols don't fill frame, offset so they're centred
30 | xy -= (vec2(cols-colsused, rows-rowsused) / vec2(cols, rows)) / 2.0;
31 | }
32 |
33 | // Offset to inside edge of frame border, which is not part of the individual cells
34 | vec2 noframe = xy;
35 | noframe *= vec2(1.0) + 2.0 * border;
36 | noframe -= border;
37 |
38 | vec2 cellsize = vec2(1.0) / vec2(cols, rows);
39 |
40 | // Figure out which cell we're in
41 | vec2 loc = floor(noframe / cellsize);
42 | float frame = loc.y * colsused + loc.x;
43 |
44 | // Figure out where we are in this cell
45 | vec2 cell = noframe / cellsize;
46 | cell = mod(cell, 1.0);
47 |
48 | // Offset to be inside border of this cell
49 | vec2 noborder = cell;
50 | noborder *= vec2(1.0) + 2.0 * (border / cellsize);
51 | noborder -= border / cellsize;
52 |
53 | // Read previous output frame
54 | vec4 a = texture2D(adsk_accum_texture, gl_FragCoord.xy / res);
55 | if(allframes || adsk_time == frame + 1.0) {
56 | // We're in the cell we need to add this time
57 | a = texture2D(front, vec2(noborder.x, 1.0 - noborder.y));
58 | }
59 |
60 | // Output black in fill and matte for border areas
61 | bool isborder = false;
62 | if(noborder.x < 0.0 || noborder.x > 1.0 || noborder.y < 0.0 || noborder.y > 1.0) {
63 | isborder = true;
64 | }
65 | if(loc.x >= colsused || loc.x < 0.0 || loc.y >= rowsused || loc.y < 0.0) {
66 | isborder = true;
67 | }
68 | if(isborder) {
69 | a = vec4(0.0);
70 | }
71 |
72 | gl_FragColor = a;
73 | }
74 |
--------------------------------------------------------------------------------
/Ls_Filmstrip.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Filmstrip.glsl.p
--------------------------------------------------------------------------------
/Ls_Filmstrip.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Ls_Fireflies.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Fireflies.glsl.p
--------------------------------------------------------------------------------
/Ls_Fireflies.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Ls_Fireflies_sortingnetwork.pl:
--------------------------------------------------------------------------------
1 | # Prints comparator orders for the sorting network used in Ls_Fireflies.1.glsl
2 | # The module needs to be installed from CPAN first with:
3 | # cpan Algorithm::Networksort
4 |
5 | use Algorithm::Networksort;
6 | use Algorithm::Networksort::Best qw(:all);
7 |
8 | my $inputs = 9;
9 |
10 | # First the standard algorithm-generated one:
11 | my $algorithm = "bosenelson";
12 | my $nw = nwsrt(inputs => $inputs, algorithm => $algorithm);
13 | print $nw->title(), "\n";
14 | print $nw, "\n";
15 | print $nw->graph_text(), "\n";
16 | $nw->formats([ "COMPARESWAP(%d, %d)\n" ]);
17 | print $nw->formatted();
18 |
19 | # Then possible better ones discovered separately:
20 | my @nwkeys = nw_best_names($inputs);
21 | for my $name (@nwkeys)
22 | {
23 | my $nw = nwsrt_best(name => $name);
24 | print $nw->title(), "\n", $nw->formatted(), "\n\n";
25 | print $nw->graph_text(), "\n";
26 | $nw->formats([ "COMPARESWAP(%d, %d)\n" ]);
27 | print $nw->formatted();
28 | }
29 |
--------------------------------------------------------------------------------
/Ls_Flock.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Flock.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Flock.2.glsl:
--------------------------------------------------------------------------------
1 | // Flock pass 2
2 | // This pass simply trims off the top half of the simulation texture,
3 | // which stores velocities that are not useful for Action rendering
4 | //
5 | // lewis@lewissaunders.com
6 | //
7 |
8 | uniform float adsk_result_w, adsk_result_h;
9 | uniform sampler2D adsk_results_pass1;
10 |
11 | void main() {
12 | vec2 xy = gl_FragCoord.xy;
13 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
14 |
15 | gl_FragColor = texture2D(adsk_results_pass1, xy * px * vec2(1.0, 0.5));
16 | }
17 |
--------------------------------------------------------------------------------
/Ls_Fluid.1.glsl:
--------------------------------------------------------------------------------
1 | // Pass 1: advect the vectors by themselves, including the effect
2 | // of the obstacle input and the gravity vector. This takes its
3 | // input from the accumulation texture, or the vector input on frame 1.
4 | // It outputs the advected motion vectors in red/green, and a UV map in
5 | // blue/alpha
6 | // lewis@lewissaunders.com
7 |
8 | uniform sampler2D vecs, adsk_accum_texture, obstacles;
9 | uniform float adsk_result_w, adsk_result_h, velocity, sidestep, obstacleweight;
10 | uniform vec2 offset;
11 | uniform int samples, oversamples;
12 | uniform bool adsk_accum_no_prev_frame;
13 |
14 | vec4 get(vec2 uv) {
15 | if(adsk_accum_no_prev_frame) {
16 | // First frame is input vectors in rg, UV map in ba
17 | return vec4(texture2D(vecs, uv).rg, uv);
18 | } else {
19 | vec4 v = texture2D(adsk_accum_texture, uv);
20 | v.xy += offset/100.0;
21 | float obs = texture2D(obstacles, uv).b;
22 | v.xy *= 1.0 - obstacleweight * obs;
23 | return v;
24 | }
25 | }
26 |
27 | void main() {
28 | vec2 xy = gl_FragCoord.xy;
29 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h); // Factor to convert pixels to [0,1] texture coords
30 |
31 | float sam = float(samples);
32 | vec4 acc = vec4(0.0);
33 | vec2 v;
34 | for(int j = 0; j < oversamples; j++) {
35 | for(int k = 0; k < oversamples; k++) {
36 | // Starting point for this sample
37 | xy = gl_FragCoord.xy + vec2(float(j) / (float(oversamples) + 1.0), float(k) / (float(oversamples) + 1.0));
38 | // Walk along path by sampling vector image, moving, sampling, moving...
39 | for(float i = 0.0; i < sam; i++) {
40 | v = get(xy * px).rg;
41 | if(length(v) == 0.0) {
42 | // No gradient at this point in the map, early out
43 | break;
44 | }
45 | xy -= v * (velocity/sam) + sidestep/100.0 * vec2(-v.y, v.x);
46 | }
47 | // Sample front image where our walk ended up
48 | acc += get(xy * px);
49 |
50 | }
51 | }
52 | acc /= float(oversamples * oversamples);
53 |
54 | gl_FragColor = acc;
55 | }
56 |
--------------------------------------------------------------------------------
/Ls_Fluid.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Fluid.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Fluid.2.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 2 - Gaussian blur 1, horizontal
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass1;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float blur1size;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blur1size;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass1, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass1, (xy - vec2(float(i), 0.0)) * px);
35 | a += g.x * texture2D(adsk_results_pass1, (xy + vec2(float(i), 0.0)) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Fluid.3.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 3 - Gaussian blur 1, vertical
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass2;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float blur1size;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blur1size;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass2, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass2, (xy - vec2(0.0, float(i))) * px);
35 | a += g.x * texture2D(adsk_results_pass2, (xy + vec2(0.0, float(i))) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Fluid.4.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 4 - Gaussian blur 2, horizontal
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass3;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float blur2size;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blur2size;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass3, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass3, (xy - vec2(float(i), 0.0)) * px);
35 | a += g.x * texture2D(adsk_results_pass3, (xy + vec2(float(i), 0.0)) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Fluid.5.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 5 - Gaussian blur 2, vertical
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass4;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float blur2size;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blur2size;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass4, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass4, (xy - vec2(0.0, float(i))) * px);
35 | a += g.x * texture2D(adsk_results_pass4, (xy + vec2(0.0, float(i))) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Fluid.6.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 6 - Gaussian blur 3, horizontal
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass5;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float blur3size;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blur3size;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass5, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass5, (xy - vec2(float(i), 0.0)) * px);
35 | a += g.x * texture2D(adsk_results_pass5, (xy + vec2(float(i), 0.0)) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Fluid.7.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 7 - Gaussian blur 3, vertical
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D adsk_results_pass6;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float blur3size;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blur3size;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass6, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass6, (xy - vec2(0.0, float(i))) * px);
35 | a += g.x * texture2D(adsk_results_pass6, (xy + vec2(0.0, float(i))) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Fluid.8.glsl:
--------------------------------------------------------------------------------
1 | // Undiverge a vector field
2 | // Pass 8 - combine the three blurs, and differentiate to get an approximation of the
3 | // pressure field
4 | // lewis@lewissaunders.com
5 |
6 | uniform sampler2D adsk_results_pass3, adsk_results_pass5, adsk_results_pass7;
7 | uniform float adsk_result_w, adsk_result_h;
8 | uniform float d1, d2, d3, amount1, amount2, amount3;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | vec3 a = vec3(0.0);
15 | a.r -= (amount1/d1) * texture2D(adsk_results_pass3, (xy + vec2(+d1, 0.0)) * px).r;
16 | a.r += (amount1/d1) * texture2D(adsk_results_pass3, (xy + vec2(-d1, 0.0)) * px).r;
17 | a.g -= (amount1/d1) * texture2D(adsk_results_pass3, (xy + vec2(0.0, +d1)) * px).g;
18 | a.g += (amount1/d1) * texture2D(adsk_results_pass3, (xy + vec2(0.0, -d1)) * px).g;
19 | a.r -= (amount2/d2) * texture2D(adsk_results_pass5, (xy + vec2(+d2, 0.0)) * px).r;
20 | a.r += (amount2/d2) * texture2D(adsk_results_pass5, (xy + vec2(-d2, 0.0)) * px).r;
21 | a.g -= (amount2/d2) * texture2D(adsk_results_pass5, (xy + vec2(0.0, +d2)) * px).g;
22 | a.g += (amount2/d2) * texture2D(adsk_results_pass5, (xy + vec2(0.0, -d2)) * px).g;
23 | a.r -= (amount3/d3) * texture2D(adsk_results_pass7, (xy + vec2(+d3, 0.0)) * px).r;
24 | a.r += (amount3/d3) * texture2D(adsk_results_pass7, (xy + vec2(-d3, 0.0)) * px).r;
25 | a.g -= (amount3/d3) * texture2D(adsk_results_pass7, (xy + vec2(0.0, +d3)) * px).g;
26 | a.g += (amount3/d3) * texture2D(adsk_results_pass7, (xy + vec2(0.0, -d3)) * px).g;
27 |
28 | float pressure = a.r + a.g;
29 |
30 | gl_FragColor = vec4(pressure);
31 | }
32 |
--------------------------------------------------------------------------------
/Ls_Glint.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Glint.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Glint.2.glsl:
--------------------------------------------------------------------------------
1 | // Glint pass 2: Gaussian blur horizontal
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass1;
5 | uniform float blursize, blursizer, blursizeg, blursizeb;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform int downsample;
8 |
9 | // Return a 1D Gaussian blur
10 | // sampler is hard-coded to "adsk_results_pass1" to avoid a Baselight bug when passing it as an arg
11 | // xy: centre of blur in pixels
12 | // res: pixel size of mipmap level selected by lod param
13 | // sizes: sigma of blurs, in pixels
14 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
15 | // another pass for vertical
16 | vec4 gaussianblur(vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
17 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
18 |
19 | // Set up state for incremental coefficient calculation, see GPU Gems
20 | // We use vec4s to store four copies of the state, for different size
21 | // red/green/blue/alpha blurs
22 | vec4 gx = vec4(0.0);
23 | vec4 gy = vec4(0.0);
24 | vec4 gz = vec4(0.0);
25 |
26 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
27 | gy = exp(-0.5 / (sigmas * sigmas));
28 | gz = gy * gy;
29 | // vec4 a, centre, sample1, sample2 = vec4(0.0);
30 | vec4 a = vec4(0.0);
31 | vec4 centre = vec4(0.0);
32 | vec4 sample1 = vec4(0.0);
33 | vec4 sample2 = vec4(0.0);
34 |
35 | // First take the centre sample
36 | centre = texture2D(adsk_results_pass1, xy / res);
37 | a += gx * centre;
38 | vec4 energy = gx;
39 | gx *= gy;
40 | gy *= gz;
41 |
42 | // Now the other samples
43 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
44 | for(float i = 1.0; i <= support; i++) {
45 | sample1 = texture2D(adsk_results_pass1, (xy - i * dir) / res);
46 | sample2 = texture2D(adsk_results_pass1, (xy + i * dir) / res);
47 | a += gx * sample1;
48 | a += gx * sample2;
49 | energy += 2.0 * gx;
50 | gx *= gy;
51 | gy *= gz;
52 | }
53 |
54 | a /= energy;
55 |
56 | if(sizered < 0.1) a.r = centre.r;
57 | if(sizegreen < 0.1) a.g = centre.g;
58 | if(sizeblue < 0.1) a.b = centre.b;
59 |
60 | return a;
61 | }
62 |
63 | void main() {
64 | vec2 res = vec2(adsk_result_w, adsk_result_h);
65 | vec2 xy = gl_FragCoord.xy / float(downsample+1);
66 | gl_FragColor = gaussianblur(xy, res, blursize*blursizer, blursize*blursizeg, blursize*blursizeb, 0.0, vec2(1.0, 0.0));
67 | }
68 |
--------------------------------------------------------------------------------
/Ls_Glint.3.glsl:
--------------------------------------------------------------------------------
1 | // Glint pass 3: Gaussian blur vertical and comp
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass2, front, matte;
5 | uniform float blursize, blursizer, blursizeg, blursizeb;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform bool screen, usematte, useblendmatte, outputglints;
8 |
9 | // RGB to Rec709 YPbPr
10 | vec3 yuv(vec3 rgb) {
11 | return mat3(0.2215, -0.1145, 0.5016, 0.7154, -0.3855, -0.4556, 0.0721, 0.5, -0.0459) * rgb;
12 | }
13 |
14 | // Return a 1D Gaussian blur
15 | // sampler is hard-coded to "adsk_results_pass2" to avoid a Baselight bug when passing it as an arg
16 | // xy: centre of blur in pixels
17 | // res: pixel size of mipmap level selected by lod param
18 | // sizes: sigma of blurs, in pixels
19 | // dir: direction of blur, usually vec2(1.0, 0.0) for horizontal followed by
20 | // another pass for vertical
21 | vec4 gaussianblur(vec2 xy, vec2 res, float sizered, float sizegreen, float sizeblue, float sizealpha, vec2 dir) {
22 | vec4 sigmas = vec4(sizered, sizegreen, sizeblue, sizealpha);
23 |
24 | // Set up state for incremental coefficient calculation, see GPU Gems
25 | // We use vec4s to store four copies of the state, for different size
26 | // red/green/blue/alpha blurs
27 | vec4 gx, gy, gz;
28 | gx = 1.0 / (sqrt(2.0 * 3.141592653589793238) * sigmas);
29 | gy = exp(-0.5 / (sigmas * sigmas));
30 | gz = gy * gy;
31 | // vec4 a, centre, sample1, sample2 = vec4(0.0);
32 | vec4 a = vec4(0.0);
33 | vec4 centre = vec4(0.0);
34 | vec4 sample1 = vec4(0.0);
35 | vec4 sample2 = vec4(0.0);
36 |
37 | // First take the centre sample
38 | centre = texture2D(adsk_results_pass2, xy / res);
39 | a += gx * centre;
40 | vec4 energy = gx;
41 | gx *= gy;
42 | gy *= gz;
43 |
44 | // Now the other samples
45 | float support = max(max(max(sigmas.r, sigmas.g), sigmas.b), sigmas.a) * 3.0;
46 | for(float i = 1.0; i <= support; i++) {
47 | sample1 = texture2D(adsk_results_pass2, (xy - i * dir) / res);
48 | sample2 = texture2D(adsk_results_pass2, (xy + i * dir) / res);
49 | a += gx * sample1;
50 | a += gx * sample2;
51 | energy += 2.0 * gx;
52 | gx *= gy;
53 | gy *= gz;
54 | }
55 |
56 | a /= energy;
57 |
58 | if(sizered < 0.1) a.r = centre.r;
59 | if(sizegreen < 0.1) a.g = centre.g;
60 | if(sizeblue < 0.1) a.b = centre.b;
61 |
62 | return a;
63 | }
64 |
65 | void main() {
66 | vec2 res = vec2(adsk_result_w, adsk_result_h);
67 | vec2 xy = gl_FragCoord.xy;
68 |
69 | vec3 frontpix = texture2D(front, xy/res).rgb;
70 | vec3 mattepix = texture2D(matte, xy/res).rgb;
71 |
72 | vec3 blurred = gaussianblur(xy, res, blursize*blursizer, blursize*blursizeg, blursize*blursizeb, 0.0, vec2(0.0, 1.0)).rgb;
73 |
74 | // Blend with front input
75 | vec3 result;
76 | float blurredluma = 0.0;
77 | if(useblendmatte) {
78 | blurred *= mattepix;
79 | blurredluma = yuv(blurred.rgb).r; // Luma is used for matte output below
80 | }
81 | if(screen) {
82 | result = max(max(frontpix, blurred), blurred+frontpix-(blurred*frontpix));
83 | } else {
84 | result = frontpix + blurred;
85 | }
86 | if(outputglints) {
87 | result = blurred;
88 | }
89 |
90 | // Matte output is luma of glint only
91 | gl_FragColor = vec4(result, blurredluma);
92 | }
93 |
--------------------------------------------------------------------------------
/Ls_GlueP.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_GlueP.glsl.p
--------------------------------------------------------------------------------
/Ls_Lumps.1.glsl:
--------------------------------------------------------------------------------
1 | /* The three bands are made like this:
2 | colour = colourblur
3 | lumps = lumpsblur - colourblur
4 | detail = front input - lumpsblur
5 |
6 | There are quite a few passes so here's a diagram of how they connect:
7 |
8 | front input
9 | │
10 | ┌────────┴───────────┬─────────────────────┬──────────┐
11 | │ │ │ │
12 | ▼ ▼ │ │
13 | 01 colourblur h 03 lumpsblur h │ │
14 | │ │ │ │
15 | ▼ ▼ │ │
16 | ┌── 02 colourblur v 04 lumpsblur v ───┬─────┐ │ │
17 | │ │ │ │ │ │ │
18 | │ ├──────────┬─────┐ │ │ │ │ │
19 | │ │ │ │ │ │ │ │ │
20 | │ ▼ │ ▼ ▼ │ ▼ ▼ │
21 | │ 05 colourfilter h │ 07 lumpsfilter h │ 09 detailfilter h │
22 | │ │ │ │ │ │ │
23 | │ ▼ │ ▼ │───────┐ │ │
24 | └► 06 colourfilter v └► 08 lumpsfilter v ◄┘ │ │ │
25 | │ │ │ │ │
26 | │ └───────────────┐ │ │ ┌───────┘
27 | │ ▼ ▼ ▼ ▼
28 | └────────────────────────────────► 10 detailfilter v,
29 | combine and output
30 |
31 | Passes 05, 06, 07, 08, 09 and 10 can also use the colour/lumps/detail inputs
32 | directly when in "recombine" mode, instead of calculating them from the blurs
33 |
34 | Pass 02 can also use the front input's top MIP level to compute a whole image
35 | average, instead of blurring
36 | */
37 |
38 | // Colour blur horizontal pass
39 | // lewis@lewissaunders.com
40 |
41 | uniform sampler2D front;
42 | uniform float adsk_result_w, adsk_result_h;
43 | uniform float coloursize;
44 | uniform bool recombine, mipmapcolour;
45 | const float pi = 3.141592653589793238462643383279502884197969;
46 |
47 | void main() {
48 | if(recombine) discard;
49 | if(mipmapcolour) discard;
50 |
51 | vec2 xy = gl_FragCoord.xy;
52 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
53 |
54 | float sigma = coloursize;
55 | int support = int(sigma * 3.0);
56 |
57 | // Incremental coefficient calculation setup as per GPU Gems 3
58 | vec3 g;
59 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
60 | g.y = exp(-0.5 / (sigma * sigma));
61 | g.z = g.y * g.y;
62 |
63 | if(sigma == 0.0) {
64 | g.x = 1.0;
65 | }
66 |
67 | // Centre sample
68 | vec4 a = g.x * texture2D(front, xy * px);
69 | float energy = g.x;
70 | g.xy *= g.yz;
71 |
72 | // The rest
73 | for(int i = 1; i <= support; i++) {
74 | a += g.x * texture2D(front, (xy - vec2(float(i), 0.0)) * px);
75 | a += g.x * texture2D(front, (xy + vec2(float(i), 0.0)) * px);
76 | energy += 2.0 * g.x;
77 | g.xy *= g.yz;
78 | }
79 | a /= energy;
80 |
81 | gl_FragColor = a;
82 | }
83 |
--------------------------------------------------------------------------------
/Ls_Lumps.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Lumps.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Lumps.10.glsl:
--------------------------------------------------------------------------------
1 | // Detail filter vertical pass and split/scale/combine
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D front, adsk_results_pass4, adsk_results_pass6, adsk_results_pass8, adsk_results_pass9;
5 | uniform sampler2D colourt, lumpst, detailt;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform float detailfiltersize, detailsharpenamnt;
8 | uniform bool outputcolour, outputlumps, outputdetail;
9 | uniform float colourgamma, colourcontrast;
10 | uniform float lumpsgamma, lumpscontrast;
11 | uniform float detailgamma, detailcontrast;
12 | uniform float scolour, slumps, sdetail;
13 | uniform bool recombine, islin;
14 | const float pi = 3.141592653589793238462643383279502884197969;
15 |
16 | vec4 getdetail(vec2 xy) {
17 | if(recombine) {
18 | // Use node's detail input
19 | if(islin) {
20 | return texture2D(detailt, xy) - vec4(0.18);
21 | } else {
22 | return texture2D(detailt, xy) - vec4(0.5);
23 | }
24 | } else {
25 | // Use our calculated detail band
26 | return texture2D(front, xy) - texture2D(adsk_results_pass4, xy);
27 | }
28 | }
29 |
30 | void main() {
31 | vec2 xy = gl_FragCoord.xy;
32 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
33 |
34 | float sigma = abs(detailfiltersize);
35 | int support = int(sigma * 3.0);
36 |
37 | // Incremental coefficient calculation setup as per GPU Gems 3
38 | vec3 g;
39 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
40 | g.y = exp(-0.5 / (sigma * sigma));
41 | g.z = g.y * g.y;
42 |
43 | if(sigma == 0.0) {
44 | g.x = 1.0;
45 | }
46 |
47 | // Centre sample
48 | vec4 a = g.x * texture2D(adsk_results_pass9, xy * px);
49 | float energy = g.x;
50 | g.xy *= g.yz;
51 |
52 | // The rest
53 | for(int i = 1; i <= support; i++) {
54 | a += g.x * texture2D(adsk_results_pass9, (xy - vec2(0.0, float(i))) * px);
55 | a += g.x * texture2D(adsk_results_pass9, (xy + vec2(0.0, float(i))) * px);
56 | energy += 2.0 * g.x;
57 | g.xy *= g.yz;
58 | }
59 | a /= energy;
60 |
61 | vec4 filtered = a;
62 | vec4 detailunfilt = getdetail(xy * px);
63 | if(detailfiltersize < 0.0) {
64 | // Sharpen rather than blur
65 | filtered = detailunfilt + detailsharpenamnt * (detailunfilt - filtered);
66 | }
67 |
68 | vec4 colour = texture2D(adsk_results_pass6, xy * px);
69 | vec4 lumps = texture2D(adsk_results_pass8, xy * px);
70 | vec4 detail = filtered;
71 |
72 | // Grade each band
73 | colour *= colourcontrast;
74 | colour = sign(colour) * pow(abs(colour), vec4(1.0/colourgamma));
75 | lumps *= lumpscontrast;
76 | lumps = sign(lumps) * pow(abs(lumps), vec4(1.0/lumpsgamma));
77 | detail *= detailcontrast;
78 | detail = sign(detail) * pow(abs(detail), vec4(1.0/detailgamma));
79 | colour *= scolour;
80 | lumps *= slumps;
81 | detail *= sdetail;
82 |
83 | vec4 o = vec4(islin ? 0.18 : 0.5);
84 | if(outputcolour) o = colour;
85 | if(outputlumps) o += lumps;
86 | if(outputdetail) o += detail;
87 | gl_FragColor = o;
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/Ls_Lumps.2.glsl:
--------------------------------------------------------------------------------
1 | // Colour blur vertical pass
2 | // lewis@lewissaunders.com
3 |
4 | #extension GL_ARB_shader_texture_lod : enable
5 |
6 | uniform sampler2D front, adsk_results_pass1;
7 | uniform float adsk_result_w, adsk_result_h;
8 | uniform float coloursize;
9 | uniform bool recombine, mipmapcolour;
10 | const float pi = 3.141592653589793238462643383279502884197969;
11 |
12 | void main() {
13 | if(recombine) discard;
14 |
15 | vec2 xy = gl_FragCoord.xy;
16 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
17 |
18 | if(mipmapcolour) {
19 | // Instead of blurring, use the top MIP level as a whole-image average
20 | gl_FragColor = texture2DLod(front, xy * px, 99.0);
21 | return;
22 | }
23 |
24 | float sigma = coloursize;
25 | int support = int(sigma * 3.0);
26 |
27 | // Incremental coefficient calculation setup as per GPU Gems 3
28 | vec3 g;
29 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
30 | g.y = exp(-0.5 / (sigma * sigma));
31 | g.z = g.y * g.y;
32 |
33 | if(sigma == 0.0) {
34 | g.x = 1.0;
35 | }
36 |
37 | // Centre sample
38 | vec4 a = g.x * texture2D(adsk_results_pass1, xy * px);
39 | float energy = g.x;
40 | g.xy *= g.yz;
41 |
42 | // The rest
43 | for(int i = 1; i <= support; i++) {
44 | a += g.x * texture2D(adsk_results_pass1, (xy - vec2(0.0, float(i))) * px);
45 | a += g.x * texture2D(adsk_results_pass1, (xy + vec2(0.0, float(i))) * px);
46 | energy += 2.0 * g.x;
47 | g.xy *= g.yz;
48 | }
49 | a /= energy;
50 |
51 | gl_FragColor = a;
52 | }
53 |
--------------------------------------------------------------------------------
/Ls_Lumps.3.glsl:
--------------------------------------------------------------------------------
1 | // Lumps blur horizontal pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D front;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float lumpsize;
7 | uniform bool recombine;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | if(recombine) discard;
12 |
13 | vec2 xy = gl_FragCoord.xy;
14 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
15 |
16 | float sigma = lumpsize;
17 | int support = int(sigma * 3.0);
18 |
19 | // Incremental coefficient calculation setup as per GPU Gems 3
20 | vec3 g;
21 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
22 | g.y = exp(-0.5 / (sigma * sigma));
23 | g.z = g.y * g.y;
24 |
25 | if(sigma == 0.0) {
26 | g.x = 1.0;
27 | }
28 |
29 | // Centre sample
30 | vec4 a = g.x * texture2D(front, xy * px);
31 | float energy = g.x;
32 | g.xy *= g.yz;
33 |
34 | // The rest
35 | for(int i = 1; i <= support; i++) {
36 | a += g.x * texture2D(front, (xy - vec2(float(i), 0.0)) * px);
37 | a += g.x * texture2D(front, (xy + vec2(float(i), 0.0)) * px);
38 | energy += 2.0 * g.x;
39 | g.xy *= g.yz;
40 | }
41 | a /= energy;
42 |
43 | gl_FragColor = a;
44 | }
45 |
--------------------------------------------------------------------------------
/Ls_Lumps.4.glsl:
--------------------------------------------------------------------------------
1 | // Lumps blur vertical pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass3;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float lumpsize;
7 | uniform bool recombine;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | if(recombine) discard;
12 |
13 | vec2 xy = gl_FragCoord.xy;
14 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
15 |
16 | float sigma = lumpsize;
17 | int support = int(sigma * 3.0);
18 |
19 | // Incremental coefficient calculation setup as per GPU Gems 3
20 | vec3 g;
21 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
22 | g.y = exp(-0.5 / (sigma * sigma));
23 | g.z = g.y * g.y;
24 |
25 | if(sigma == 0.0) {
26 | g.x = 1.0;
27 | }
28 |
29 | // Centre sample
30 | vec4 a = g.x * texture2D(adsk_results_pass3, xy * px);
31 | float energy = g.x;
32 | g.xy *= g.yz;
33 |
34 | // The rest
35 | for(int i = 1; i <= support; i++) {
36 | a += g.x * texture2D(adsk_results_pass3, (xy - vec2(0.0, float(i))) * px);
37 | a += g.x * texture2D(adsk_results_pass3, (xy + vec2(0.0, float(i))) * px);
38 | energy += 2.0 * g.x;
39 | g.xy *= g.yz;
40 | }
41 | a /= energy;
42 |
43 | gl_FragColor = a;
44 | }
45 |
--------------------------------------------------------------------------------
/Ls_Lumps.5.glsl:
--------------------------------------------------------------------------------
1 | // Colour filter horizontal pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass2, colourt;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float colourfiltersize;
7 | uniform bool recombine;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | vec4 getcolour(vec2 xy) {
11 | if(recombine) {
12 | // Use node's colour input
13 | return texture2D(colourt, xy);
14 | } else {
15 | // Use our calculated colour band
16 | return texture2D(adsk_results_pass2, xy);
17 | }
18 | }
19 |
20 | void main() {
21 | vec2 xy = gl_FragCoord.xy;
22 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
23 |
24 | float sigma = abs(colourfiltersize);
25 | int support = int(sigma * 3.0);
26 |
27 | // Incremental coefficient calculation setup as per GPU Gems 3
28 | vec3 g;
29 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
30 | g.y = exp(-0.5 / (sigma * sigma));
31 | g.z = g.y * g.y;
32 |
33 | if(sigma == 0.0) {
34 | g.x = 1.0;
35 | }
36 |
37 | // Centre sample
38 | vec4 a = g.x * getcolour(xy * px);
39 | float energy = g.x;
40 | g.xy *= g.yz;
41 |
42 | // The rest
43 | for(int i = 1; i <= support; i++) {
44 | a += g.x * getcolour((xy - vec2(float(i), 0.0)) * px);
45 | a += g.x * getcolour((xy + vec2(float(i), 0.0)) * px);
46 | energy += 2.0 * g.x;
47 | g.xy *= g.yz;
48 | }
49 | a /= energy;
50 |
51 | gl_FragColor = a;
52 | }
53 |
--------------------------------------------------------------------------------
/Ls_Lumps.6.glsl:
--------------------------------------------------------------------------------
1 | // Colour filter vertical pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass2, adsk_results_pass5, colourt;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float colourfiltersize, coloursharpenamnt;
7 | uniform bool recombine;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | vec4 getcolour(vec2 xy) {
11 | if(recombine) {
12 | // Use node's colour input
13 | return texture2D(colourt, xy);
14 | } else {
15 | // Use our calculated colour band
16 | return texture2D(adsk_results_pass2, xy);
17 | }
18 | }
19 |
20 | void main() {
21 | vec2 xy = gl_FragCoord.xy;
22 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
23 |
24 | float sigma = abs(colourfiltersize);
25 | int support = int(sigma * 3.0);
26 |
27 | // Incremental coefficient calculation setup as per GPU Gems 3
28 | vec3 g;
29 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
30 | g.y = exp(-0.5 / (sigma * sigma));
31 | g.z = g.y * g.y;
32 |
33 | if(sigma == 0.0) {
34 | g.x = 1.0;
35 | }
36 |
37 | // Centre sample
38 | vec4 a = g.x * texture2D(adsk_results_pass5, xy * px);
39 | float energy = g.x;
40 | g.xy *= g.yz;
41 |
42 | // The rest
43 | for(int i = 1; i <= support; i++) {
44 | a += g.x * texture2D(adsk_results_pass5, (xy - vec2(0.0, float(i))) * px);
45 | a += g.x * texture2D(adsk_results_pass5, (xy + vec2(0.0, float(i))) * px);
46 | energy += 2.0 * g.x;
47 | g.xy *= g.yz;
48 | }
49 | a /= energy;
50 |
51 | vec4 filtered = a;
52 | vec4 colour = getcolour(xy * px);
53 | if(colourfiltersize < 0.0) {
54 | // Sharpen rather than blur
55 | filtered = colour + coloursharpenamnt * (colour - filtered);
56 | }
57 |
58 | gl_FragColor = filtered;
59 | }
60 |
--------------------------------------------------------------------------------
/Ls_Lumps.7.glsl:
--------------------------------------------------------------------------------
1 | // Lumps filter horizontal pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass2, adsk_results_pass4, lumpst;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float lumpsfiltersize;
7 | uniform bool recombine, islin;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | vec4 getlumps(vec2 xy) {
11 | if(recombine) {
12 | // Use node's lumps input
13 | if(islin) {
14 | return texture2D(lumpst, xy) - vec4(0.18);
15 | } else {
16 | return texture2D(lumpst, xy) - vec4(0.5);
17 | }
18 | } else {
19 | // Use our calculated lumps band
20 | return texture2D(adsk_results_pass4, xy) - texture2D(adsk_results_pass2, xy);
21 | }
22 | }
23 |
24 | void main() {
25 | vec2 xy = gl_FragCoord.xy;
26 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
27 |
28 | float sigma = abs(lumpsfiltersize);
29 | int support = int(sigma * 3.0);
30 |
31 | // Incremental coefficient calculation setup as per GPU Gems 3
32 | vec3 g;
33 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
34 | g.y = exp(-0.5 / (sigma * sigma));
35 | g.z = g.y * g.y;
36 |
37 | if(sigma == 0.0) {
38 | g.x = 1.0;
39 | }
40 |
41 | // Centre sample
42 | vec4 a = g.x * getlumps(xy * px);
43 | float energy = g.x;
44 | g.xy *= g.yz;
45 |
46 | // The rest
47 | for(int i = 1; i <= support; i++) {
48 | a += g.x * getlumps((xy - vec2(float(i), 0.0)) * px);
49 | a += g.x * getlumps((xy + vec2(float(i), 0.0)) * px);
50 | energy += 2.0 * g.x;
51 | g.xy *= g.yz;
52 | }
53 | a /= energy;
54 |
55 | gl_FragColor = a;
56 | }
57 |
--------------------------------------------------------------------------------
/Ls_Lumps.8.glsl:
--------------------------------------------------------------------------------
1 | // Lumps filter vertical pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass2, adsk_results_pass4, adsk_results_pass7, lumpst;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float lumpsfiltersize, lumpssharpenamnt;
7 | uniform bool recombine, islin;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | vec4 getlumps(vec2 xy) {
11 | if(recombine) {
12 | // Use node's lumps input
13 | if(islin) {
14 | return texture2D(lumpst, xy) - vec4(0.18);
15 | } else {
16 | return texture2D(lumpst, xy) - vec4(0.5);
17 | }
18 | } else {
19 | // Use our calculated lumps band
20 | return texture2D(adsk_results_pass4, xy) - texture2D(adsk_results_pass2, xy);
21 | }
22 | }
23 |
24 | void main() {
25 | vec2 xy = gl_FragCoord.xy;
26 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
27 |
28 | float sigma = abs(lumpsfiltersize);
29 | int support = int(sigma * 3.0);
30 |
31 | // Incremental coefficient calculation setup as per GPU Gems 3
32 | vec3 g;
33 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
34 | g.y = exp(-0.5 / (sigma * sigma));
35 | g.z = g.y * g.y;
36 |
37 | if(sigma == 0.0) {
38 | g.x = 1.0;
39 | }
40 |
41 | // Centre sample
42 | vec4 a = g.x * texture2D(adsk_results_pass7, xy * px);
43 | float energy = g.x;
44 | g.xy *= g.yz;
45 |
46 | // The rest
47 | for(int i = 1; i <= support; i++) {
48 | a += g.x * texture2D(adsk_results_pass7, (xy - vec2(0.0, float(i))) * px);
49 | a += g.x * texture2D(adsk_results_pass7, (xy + vec2(0.0, float(i))) * px);
50 | energy += 2.0 * g.x;
51 | g.xy *= g.yz;
52 | }
53 | a /= energy;
54 |
55 | vec4 filtered = a;
56 | vec4 lumps = getlumps(xy * px);
57 | if(lumpsfiltersize < 0.0) {
58 | // Sharpen rather than blur
59 | filtered = lumps + lumpssharpenamnt * (lumps - filtered);
60 | }
61 |
62 | gl_FragColor = filtered;
63 | }
64 |
--------------------------------------------------------------------------------
/Ls_Lumps.9.glsl:
--------------------------------------------------------------------------------
1 | // Detail filter horizontal pass
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D front, adsk_results_pass4, detailt;
5 | uniform float adsk_result_w, adsk_result_h;
6 | uniform float detailfiltersize;
7 | uniform bool recombine, islin;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | vec4 getdetail(vec2 xy) {
11 | if(recombine) {
12 | // Use node's detail input
13 | if(islin) {
14 | return texture2D(detailt, xy) - vec4(0.18);
15 | } else {
16 | return texture2D(detailt, xy) - vec4(0.5);
17 | }
18 | } else {
19 | // Use our calculated detail band
20 | return texture2D(front, xy) - texture2D(adsk_results_pass4, xy);
21 | }
22 | }
23 |
24 | void main() {
25 | vec2 xy = gl_FragCoord.xy;
26 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
27 |
28 | float sigma = abs(detailfiltersize);
29 | int support = int(sigma * 3.0);
30 |
31 | // Incremental coefficient calculation setup as per GPU Gems 3
32 | vec3 g;
33 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
34 | g.y = exp(-0.5 / (sigma * sigma));
35 | g.z = g.y * g.y;
36 |
37 | if(sigma == 0.0) {
38 | g.x = 1.0;
39 | }
40 |
41 | // Centre sample
42 | vec4 a = g.x * getdetail(xy * px);
43 | float energy = g.x;
44 | g.xy *= g.yz;
45 |
46 | // The rest
47 | for(int i = 1; i <= support; i++) {
48 | a += g.x * getdetail((xy - vec2(float(i), 0.0)) * px);
49 | a += g.x * getdetail((xy + vec2(float(i), 0.0)) * px);
50 | energy += 2.0 * g.x;
51 | g.xy *= g.yz;
52 | }
53 | a /= energy;
54 |
55 | gl_FragColor = a;
56 | }
57 |
--------------------------------------------------------------------------------
/Ls_NaNfix.glsl:
--------------------------------------------------------------------------------
1 | // NaNfix - interpolate NaN pixels from surroundings
2 | // lewis@lewissaunders.com
3 |
4 | uniform float adsk_result_w, adsk_result_h;
5 | uniform sampler2D front;
6 | uniform vec3 tempcolour;
7 | uniform int radius;
8 |
9 | bool isnan(float f) {
10 | // Try a few things. Some drivers optimise some of them away :/
11 | if(f != f) {
12 | return true;
13 | }
14 | if(f < 0.0 || 0.0 < f || f == 0.0) {
15 | return false;
16 | } else {
17 | return true;
18 | }
19 | }
20 |
21 | bool anynans(vec3 v) {
22 | if(isnan(v.r)) return true;
23 | if(isnan(v.g)) return true;
24 | if(isnan(v.b)) return true;
25 | return false;
26 | }
27 |
28 | void main() {
29 | vec2 res = vec2(adsk_result_w, adsk_result_h);
30 | vec2 xy = gl_FragCoord.xy;
31 |
32 | vec3 o = texture2D(front, xy / res).rgb;
33 | float m = 0.0;
34 |
35 | if(anynans(o)) {
36 | o = vec3(0.0);
37 | m = 1.0;
38 | float count = 0.0;
39 | float r = float(radius);
40 | for(float i = -r; i <= r; i += 1.0) {
41 | for(float j = -r; j <= r; j += 1.0) {
42 | vec3 here = texture2D(front, (xy + vec2(i, j))/res).rgb;
43 | if(!anynans(here)) {
44 | o += here;
45 | count += 1.0;
46 | }
47 | }
48 | }
49 | if(count == 0.0) {
50 | // Couldn't find any good pixels in surroundings! Output black.
51 | o = vec3(0.0);
52 | } else {
53 | o /= count;
54 | }
55 | }
56 |
57 | gl_FragColor = vec4(o, m);
58 | }
59 |
--------------------------------------------------------------------------------
/Ls_NaNfix.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_NaNfix.glsl.p
--------------------------------------------------------------------------------
/Ls_NaNfix.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Ls_Nail.glsl:
--------------------------------------------------------------------------------
1 | // Transforms the area inside the nail matte by the difference between two tracks
2 | // Use to stick down floating CG, by nailing from a track on the CG to a track on the BG
3 | // lewis@lewissaunders.com
4 | // TODO:
5 | // o Anti-aliased overlay
6 | // o Rotate, scale, shear?
7 | // o Better filtering probably. Not sure if EWA would work because no dFdx?
8 |
9 | uniform sampler2D front, matte, nailmatte;
10 | uniform float adsk_result_w, adsk_result_h;
11 | uniform vec2 trackfrom, trackto, offset;
12 | uniform float extra, amount, edgeswoop;
13 | uniform bool manualtracks, matteistarget, overlay;
14 | uniform vec3 areatint;
15 |
16 | float distanceToSegment(vec2 p0, vec2 p1, vec2 p) {
17 | vec2 v = p1 - p0;
18 | vec2 w = p - p0;
19 | float c1 = dot(w, v);
20 | float c2 = dot(v, v);
21 |
22 | if(c1 <= 0.0)
23 | return length(p0 - p);
24 | if(c2 <= c1)
25 | return length(p1 - p);
26 |
27 | float b = c1 / c2;
28 | vec2 pb = p0 + b * v;
29 | return length(pb - p);
30 | }
31 |
32 | void main() {
33 | vec2 res = vec2(adsk_result_w, adsk_result_h);
34 | vec2 coords = gl_FragCoord.xy / res;
35 |
36 | vec2 diff = trackto - trackfrom + offset;
37 | diff *= extra;
38 | diff *= amount;
39 |
40 | if(!manualtracks) {
41 | diff /= res;
42 | }
43 |
44 | float coeff = 0.0;
45 | if(matteistarget) {
46 | coeff = texture2D(nailmatte, coords).b;
47 | } else {
48 | coeff = texture2D(nailmatte, coords - diff).b;
49 | }
50 | coeff = mix(coeff, smoothstep(0.0, 1.0, coeff), edgeswoop);
51 | diff *= coeff;
52 |
53 | vec2 q = coords - diff;
54 |
55 | vec3 o = texture2D(front, q).rgb;
56 | float m = texture2D(matte, q).b;
57 |
58 | if(overlay) {
59 | vec2 trackfromp = trackfrom;
60 | vec2 tracktop = trackto;
61 | vec2 offsetp = offset;
62 | vec2 coordsp = coords * res;
63 |
64 | if(manualtracks) {
65 | trackfromp *= res;
66 | tracktop *= res;
67 | offsetp *= res;
68 | }
69 |
70 | if(length(coordsp - trackfromp) < 5.0)
71 | o = vec3(0.8, 0.2, 0.2);
72 |
73 | if(length(coordsp - tracktop) < 5.0)
74 | o = vec3(0.2, 0.8, 0.2);
75 |
76 | if(length(offsetp) > 0.0) {
77 | if(length(coordsp - (tracktop + offsetp)) < 5.0) {
78 | o = vec3(0.2, 0.2, 0.8);
79 | }
80 | }
81 |
82 | if(distanceToSegment(trackfromp, tracktop + offsetp, coordsp) < 1.0) {
83 | if(mod(length(trackfromp - coordsp), 8.0) < 4.0) {
84 | o = vec3(0.4, 0.4, 0.8);
85 | }
86 | }
87 | o += coeff * areatint;
88 | }
89 |
90 | gl_FragColor = vec4(o, m);
91 | }
92 |
--------------------------------------------------------------------------------
/Ls_Nail.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Nail.glsl.p
--------------------------------------------------------------------------------
/Ls_Pentatone.glsl:
--------------------------------------------------------------------------------
1 | // Pentatone
2 | // Move colours towards 2, 3, 4 or 5 target colours
3 | // lewis@lewissaunders.com
4 |
5 | uniform sampler2D front, matte;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform vec3 target1, target2, target3, target4, target5;
8 | uniform float s, t;
9 |
10 | vec2 res = vec2(adsk_result_w, adsk_result_h);
11 | vec2 xy = gl_FragCoord.xy / res;
12 |
13 | void main() {
14 | vec3 rgb = texture2D(front, xy).rgb;
15 | float matte = texture2D(matte, xy).b;
16 |
17 | vec3 force1 = t * (target1 - rgb) * (1.0 - smoothstep(0.0, s, length(target1 - rgb)));
18 | /*vec3 to2 = normalize(target2 - rgb) * s * length(target2 - rgb);
19 | vec3 to3 = normalize(target3 - rgb) * s * length(target3 - rgb);
20 | vec3 to4 = normalize(target4 - rgb) * s * length(target4 - rgb);
21 | vec3 to5 = normalize(target5 - rgb) * s * length(target5 - rgb);*/
22 |
23 | rgb += force1;
24 |
25 | gl_FragColor = vec4(rgb, 1.0);
26 | }
27 |
--------------------------------------------------------------------------------
/Ls_Poly.01.glsl:
--------------------------------------------------------------------------------
1 | /* Poly
2 | lewis@lewissaunders.com
3 |
4 | Create Voronoi diagrams and Deluanay triangulations from seed points in image by
5 | jump flooding, as per "Jump Flooding in GPU" paper
6 | http://www.comp.nus.edu.sg/~tants/jfa.html
7 |
8 | This was inspired by Tom Dobrowolski's shader, reading which was very instructive:
9 | https://www.shadertoy.com/view/ldV3Wc
10 |
11 | TODO:
12 | o There are still occasional glitches and black triangles
13 | o Use 1+JFA instead of standard JFA?
14 | o Seed generation clusters a lot, could be more sophisticated
15 | o Does sdTriangle take into account anamorphicity of 0-1 texel coord space?
16 | o Trimming long thin triangles might help more than trimming small ones
17 | o Fake anchor points at image corners/edges?
18 | o Output dual of seeds, i.e. points at junctions of Voronoi diagram
19 | o Figure out if/why our distance transform output is inferior to OpenCV
20 | o Remove 4096.0 flood steps, since running at 8k uses impossible amount of VRAM?
21 | o Strength inputs which module scale/rotation of sprites/dots/edges/magnify modes
22 |
23 | Pass 1: create seed points from input video
24 | */
25 |
26 | #extension GL_ARB_shader_texture_lod : enable
27 |
28 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
29 | uniform sampler2D front, thresholdi;
30 | uniform float seedthres;
31 | uniform bool inputisseeds;
32 | vec2 res = vec2(adsk_result_w, adsk_result_h);
33 |
34 | void main() {
35 | vec2 xy = gl_FragCoord.xy / res;
36 |
37 | vec3 frontrgb = texture2D(front, xy).rgb;
38 | float frontluma = dot(frontrgb, vec3(0.2126, 0.7152, 0.0722));
39 |
40 | vec3 miprgb = texture2DLod(front, xy, 3.0).rgb;
41 | float mipluma = dot(miprgb, vec3(0.2126, 0.7152, 0.0722));
42 |
43 | float seedness = abs(frontluma - mipluma);
44 |
45 | if(inputisseeds) {
46 | seedness = frontluma;
47 | }
48 |
49 | vec4 o;
50 | float modulated_threshold = pow(seedthres, 3.0);
51 | modulated_threshold *= texture2D(thresholdi, xy).g;
52 | if(seedness > modulated_threshold) {
53 | // This is a seed pixel, output current coords
54 | o = vec4(xy, 0.0, 0.0);
55 | } else {
56 | // This is not a seed, we don't know the closest seed, output -999
57 | o = vec4(-999.0);
58 | }
59 | gl_FragColor = o;
60 | }
61 |
--------------------------------------------------------------------------------
/Ls_Poly.01.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Poly.01.glsl.p
--------------------------------------------------------------------------------
/Ls_Poly.02.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 2: jump flood out coords of closest seeds, round 1, distance 4096
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass1;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass1, xy + vec2(j, k) * (vec2(4096.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.03.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 3: jump flood out coords of closest seeds, round 2, distance 2048
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass2;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass2, xy + vec2(j, k) * (vec2(2048.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.04.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 4: jump flood out coords of closest seeds, round 3, distance 1024
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass3;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass3, xy + vec2(j, k) * (vec2(1024.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.05.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 5: jump flood out coords of closest seeds, round 4, distance 512
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass4;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass4, xy + vec2(j, k) * (vec2(512.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.06.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 6: jump flood out coords of closest seeds, round 5, distance 256
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass5;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass5, xy + vec2(j, k) * (vec2(256.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.07.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 7: jump flood out coords of closest seeds, round 6, distance 128
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass6;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass6, xy + vec2(j, k) * (vec2(128.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.08.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 8: jump flood out coords of closest seeds, round 7, distance 64
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass7;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass7, xy + vec2(j, k) * (vec2(64.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.09.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 9: jump flood out coords of closest seeds, round 8, distance 32
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass8;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass8, xy + vec2(j, k) * (vec2(32.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.10.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 10: jump flood out coords of closest seeds, round 9, distance 16
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass9;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass9, xy + vec2(j, k) * (vec2(16.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.11.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 11: jump flood out coords of closest seeds, round 10, distance 8
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass10;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass10, xy + vec2(j, k) * (vec2(8.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.12.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 12: jump flood out coords of closest seeds, round 11, distance 4
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass11;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass11, xy + vec2(j, k) * (vec2(4.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.13.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 13: jump flood out coords of closest seeds, round 12, distance 2
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass12;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass12, xy + vec2(j, k) * (vec2(2.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.14.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 14: jump flood out coords of closest seeds, round 13, distance 1
3 |
4 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio, normp;
5 | uniform sampler2D adsk_results_pass13;
6 | vec2 res = vec2(adsk_result_w, adsk_result_h);
7 |
8 | float alength(vec2 v) {
9 | v.y /= adsk_result_frameratio;
10 | return pow(pow(abs(v.x), normp) + pow(abs(v.y), normp), 1.0/normp);
11 | }
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy / res;
15 |
16 | vec4 bestseed = vec4(-999.0);
17 | float bestdist = 99999.0;
18 | for(float j = -1.0; j <= 1.0; j += 1.0) {
19 | for(float k = -1.0; k <= 1.0; k += 1.0) {
20 | vec4 s = texture2D(adsk_results_pass13, xy + vec2(j, k) * (vec2(1.0)/res));
21 | if(s.x == -999.0) {
22 | // This sample has not been flooded yet
23 | continue;
24 | }
25 | float dist = alength(s.xy - xy);
26 | if(dist < bestdist) {
27 | // This seed is the closest yet
28 | bestdist = dist;
29 | bestseed = s;
30 | }
31 | }
32 | }
33 |
34 | gl_FragColor = bestseed;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Poly.22.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 22: jump flood out addresses of closest seeds, round 7, distance 64
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass21;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass21, xy + vec2(j, k) * (vec2(64.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly.23.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 23: jump flood out addresses of closest seeds, round 8, distance 32
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass22;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass22, xy + vec2(j, k) * (vec2(32.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly.24.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 24: jump flood out addresses of closest seeds, round 9, distance 16
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass23;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass23, xy + vec2(j, k) * (vec2(16.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly.25.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 25: jump flood out addresses of closest seeds, round 10, distance 8
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass24;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass24, xy + vec2(j, k) * (vec2(8.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly.26.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 26: jump flood out addresses of closest seeds, round 11, distance 4
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass25;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass25, xy + vec2(j, k) * (vec2(4.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly.27.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 27: jump flood out addresses of closest seeds, round 12, distance 2
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass26;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass26, xy + vec2(j, k) * (vec2(2.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly.28.glsl:
--------------------------------------------------------------------------------
1 | // Poly
2 | // Pass 28: jump flood out addresses of closest seeds, round 13, distance 1
3 | // We check if the surrounding pixels tell us about triangles that are closer than our own
4 |
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform sampler2D adsk_results_pass27;
7 | vec2 res = vec2(adsk_result_w, adsk_result_h);
8 |
9 | vec2 address2coords(float a) {
10 | vec2 c;
11 | c.y = floor(a / (adsk_result_w+50.0));
12 | c.x = a - (c.y * (adsk_result_w+50.0));
13 | return (c + vec2(0.5)) / res;
14 | }
15 |
16 | // Signed distance to a triangle
17 | float sdTriangle(vec2 p0, vec2 p1, vec2 p2, vec2 p) {
18 | // The MIT License
19 | // Copyright © 2014 Inigo Quilez
20 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | vec2 e0 = p1 - p0;
22 | vec2 e1 = p2 - p1;
23 | vec2 e2 = p0 - p2;
24 |
25 | vec2 v0 = p - p0;
26 | vec2 v1 = p - p1;
27 | vec2 v2 = p - p2;
28 |
29 | vec2 pq0 = v0 - e0*clamp(dot(v0,e0)/dot(e0,e0), 0.0, 1.0);
30 | vec2 pq1 = v1 - e1*clamp(dot(v1,e1)/dot(e1,e1), 0.0, 1.0);
31 | vec2 pq2 = v2 - e2*clamp(dot(v2,e2)/dot(e2,e2), 0.0, 1.0);
32 |
33 | vec2 d = min(min(vec2(dot(pq0, pq0), v0.x*e0.y-v0.y*e0.x), vec2(dot(pq1, pq1), v1.x*e1.y-v1.y*e1.x)), vec2(dot(pq2, pq2), v2.x*e2.y-v2.y*e2.x));
34 |
35 | return -sqrt(d.x)*sign(d.y);
36 | }
37 |
38 | void main() {
39 | vec2 xy = gl_FragCoord.xy / res;
40 |
41 | vec4 bestseeds = vec4(-999.0);
42 | float bestdist = 99999.0;
43 |
44 | for(float j = -1.0; j <= 1.0; j += 1.0) {
45 | for(float k = -1.0; k <= 1.0; k += 1.0) {
46 | vec4 seeds = texture2D(adsk_results_pass27, xy + vec2(j, k) * (vec2(1.0)/res));
47 | if(seeds.r < 0.0) {
48 | // This point doesn't know about any seeds yet
49 | continue;
50 | }
51 | float dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.g), address2coords(seeds.b), xy);
52 | if(dist < bestdist) {
53 | bestseeds.rgba = seeds.rgba;
54 | bestdist = dist;
55 | }
56 | if(seeds.a >= 0.0) {
57 | // This point knows about 4 seeds, so there's another tri to check
58 | dist = sdTriangle(address2coords(seeds.r), address2coords(seeds.b), address2coords(seeds.a), xy);
59 | if(dist < bestdist) {
60 | bestseeds.rgba = seeds.barg; // This tri is flooded out in RGB, the other in RBA
61 | bestdist = dist;
62 | }
63 | }
64 | }
65 | }
66 |
67 | gl_FragColor = bestseeds;
68 | }
69 |
--------------------------------------------------------------------------------
/Ls_Poly_builder.py:
--------------------------------------------------------------------------------
1 | # Python script which builds the repeated passes for Ls_Poly
2 |
3 | # This writes out the first set of flooding passes from a template
4 | template = open('Ls_Poly.02.glsl').readlines()
5 |
6 | for p in range(3, 15):
7 | r = p - 1
8 | d = pow(2, 13-r)
9 | f = 'Ls_Poly.%02d.glsl' % p
10 | print f
11 | t = list(template)
12 |
13 | t[1] = "// Pass %d: jump flood out coords of closest seeds, round %d, distance %d\n" % (p, r, d)
14 | t[4] = "uniform sampler2D adsk_results_pass%d;\n" % (p - 1)
15 | t[19] = " vec4 s = texture2D(adsk_results_pass%d, xy + vec2(j, k) * (vec2(%d.0)/res));\n" % (p - 1, d)
16 | print t[1] + t[4] + t[19]
17 |
18 | open(f, 'w').write('' .join(t))
19 |
20 |
21 | # The second set of flooding passes
22 | template = open('Ls_Poly.16.glsl').readlines()
23 |
24 | for p in range(17, 29):
25 | r = p - 15
26 | d = pow(2, 13-r)
27 | f = 'Ls_Poly.%d.glsl' % p
28 | print f
29 | t = list(template)
30 |
31 | t[1] = "// Pass %d: jump flood out addresses of closest seeds, round %d, distance %d\n" % (p, r, d)
32 | t[5] = "uniform sampler2D adsk_results_pass%d;\n" % (p - 1)
33 | t[45] = " vec4 seeds = texture2D(adsk_results_pass%d, xy + vec2(j, k) * (vec2(%d.0)/res));\n" % (p - 1, d)
34 | print t[1] + t[5] + t[45]
35 |
36 | open(f, 'w').write('' .join(t))
37 |
--------------------------------------------------------------------------------
/Ls_Posmatte.glsl:
--------------------------------------------------------------------------------
1 | // Pick an ellipsoidal area matte from an XYZ position pass
2 | // lewis@lewissaunders.com
3 | // TODO:
4 | // o Rotation
5 | // o Skew
6 | // o Cube-shaped matte - with rounded corners?
7 |
8 | uniform float adsk_result_w, adsk_result_h;
9 | uniform vec3 pick, overlaycol;
10 | uniform float tolerance, softness, falloffswoop, offsetx, offsety, offsetz, scalex, scaley, scalez;
11 | uniform bool overlay, hatch;
12 | uniform sampler2D front, matte, pos;
13 |
14 | void main() {
15 | vec2 coords = gl_FragCoord.xy / vec2(adsk_result_w, adsk_result_h);
16 | vec3 o, frontpix, pospix, mattepix, centered, diff = vec3(0.0);
17 | float m = 0.0;
18 |
19 | frontpix = texture2D(front, coords).rgb;
20 | mattepix = texture2D(matte, coords).rgb;
21 | pospix = texture2D(pos, coords).rgb;
22 |
23 | // Center coordinate space about the picked colour so we can scale easily
24 | centered = pospix - pick - vec3(offsetx, offsety, offsetz);
25 | diff = centered / vec3(scalex, scaley, scalez);
26 |
27 | m = length(diff);
28 | if(m < tolerance) {
29 | m = 0.0;
30 | } else {
31 | m = (m - tolerance) / softness;
32 | }
33 | m = clamp(1.0 - m, 0.0, 1.0);
34 | m = mix(m, smoothstep(0.0, 1.0, m), falloffswoop);
35 | m *= mattepix.b;
36 |
37 | o = frontpix;
38 | if(overlay) {
39 | o += m * overlaycol;
40 | if(hatch) {
41 | // Cheap-ass diagonal lines
42 | float h = mod(gl_FragCoord.x - gl_FragCoord.y, 20.0);
43 | h = h > 10.0 ? 0.0 : 1.0;
44 | o = mix(o, frontpix, h);
45 | }
46 | }
47 |
48 | gl_FragColor = vec4(o, m);
49 | }
50 |
--------------------------------------------------------------------------------
/Ls_Posmatte.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Posmatte.glsl.p
--------------------------------------------------------------------------------
/Ls_Relax.glsl:
--------------------------------------------------------------------------------
1 | // Relaxxxx
2 | // This actually is mostly just mixing incoming pixels with
3 | // the target colours, which is equivalent to a pivoted contrast
4 | // sort of operator. I really miss ContrastRGB from Shake, basically
5 | // lewis@lewissaunders.com
6 |
7 | uniform float adsk_result_w, adsk_result_h;
8 | uniform vec3 mastercolour, shadowcolour, midtonecolour, highlightcolour;
9 | uniform float mastercontrast, shadowtweak, midtonetweak, highlighttweak;
10 | uniform float shadowrestore, highlightrestore;
11 | uniform float midtonesat, mixx;
12 | uniform bool showranges;
13 | uniform sampler2D front, matte;
14 |
15 | float adsk_getLuminance(vec3 rgb);
16 | float adsk_highlights(float lum, float mid);
17 | float adsk_shadows(float lum, float mid);
18 |
19 | void main() {
20 | vec2 uv = gl_FragCoord.xy / vec2(adsk_result_w, adsk_result_h);
21 | vec3 f = texture2D(front, uv).rgb;
22 | float m = texture2D(matte, uv).b;
23 |
24 | vec3 mastermisted = mix(f, mastercolour, 1.0 - mastercontrast);
25 |
26 | float fluma = adsk_getLuminance(f);
27 | float shadowness = adsk_shadows(fluma, mix(midtonesat, 0.0, 0.5));
28 | float highlightness = adsk_highlights(fluma, mix(midtonesat, 1.0, 0.5));
29 | float midtoneness = 1.0 - (shadowness + highlightness);
30 |
31 | vec3 shadowrestored = mix(mastermisted, f, shadowrestore * shadowness);
32 | vec3 restored = mix(shadowrestored, f, highlightrestore * highlightness);
33 |
34 | vec3 shadowtweaked = mix(restored, shadowcolour, shadowtweak);
35 | vec3 midtonetweaked = mix(restored, midtonecolour, midtonetweak);
36 | vec3 highlighttweaked = mix(restored, highlightcolour, highlighttweak);
37 |
38 | vec3 alltonestweaked = shadowness * shadowtweaked + midtoneness * midtonetweaked + highlightness * highlighttweaked;
39 |
40 | vec3 matted = mix(f, alltonestweaked, m * mixx);
41 |
42 | if(showranges) {
43 | matted = vec3(shadowness, midtoneness, highlightness);
44 | }
45 |
46 | gl_FragColor = vec4(matted, m);
47 | }
48 |
--------------------------------------------------------------------------------
/Ls_Relax.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Relax.glsl.p
--------------------------------------------------------------------------------
/Ls_RndmGrade.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_RndmGrade.glsl.p
--------------------------------------------------------------------------------
/Ls_Shadowplate.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Shadowplate.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Shadowplate.2.glsl:
--------------------------------------------------------------------------------
1 | #version 120
2 |
3 | // Pass 2: blur horizontally
4 |
5 | uniform sampler2D adsk_results_pass1;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform vec2 blursize;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blursize.x;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass1, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass1, (xy - vec2(float(i), 0.0)) * px);
35 | a += g.x * texture2D(adsk_results_pass1, (xy + vec2(float(i), 0.0)) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Shadowplate.3.glsl:
--------------------------------------------------------------------------------
1 | #version 120
2 |
3 | // Pass 3: blur vertically
4 |
5 | uniform sampler2D adsk_results_pass2;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform vec2 blursize;
8 | const float pi = 3.141592653589793238462643383279502884197969;
9 |
10 | void main() {
11 | vec2 xy = gl_FragCoord.xy;
12 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
13 |
14 | float sigma = blursize.y;
15 | int support = int(sigma * 3.0);
16 |
17 | // Incremental coefficient calculation setup as per GPU Gems 3
18 | vec3 g;
19 | g.x = 1.0 / (sqrt(2.0 * pi) * sigma);
20 | g.y = exp(-0.5 / (sigma * sigma));
21 | g.z = g.y * g.y;
22 |
23 | if(sigma == 0.0) {
24 | g.x = 1.0;
25 | }
26 |
27 | // Centre sample
28 | vec4 a = g.x * texture2D(adsk_results_pass2, xy * px);
29 | float energy = g.x;
30 | g.xy *= g.yz;
31 |
32 | // The rest
33 | for(int i = 1; i <= support; i++) {
34 | a += g.x * texture2D(adsk_results_pass2, (xy - vec2(0.0, float(i))) * px);
35 | a += g.x * texture2D(adsk_results_pass2, (xy + vec2(0.0, float(i))) * px);
36 | energy += 2.0 * g.x;
37 | g.xy *= g.yz;
38 | }
39 | a /= energy;
40 |
41 | gl_FragColor = a;
42 | }
43 |
--------------------------------------------------------------------------------
/Ls_Splineblur.1.glsl:
--------------------------------------------------------------------------------
1 | // Directional blur driven by gradient vectors of front input
2 | // Pass 1: make the vectors
3 | // lewis@lewissaunders.com
4 | // TODO:
5 | // o Bigger Sobel kernels?
6 | // o Pre-blur input in case of GMask kinks?
7 | // o Could probably use dfdx,dfdy instead of manual convolution
8 |
9 | uniform sampler2D map;
10 | uniform float adsk_result_w, adsk_result_h, ksize;
11 | uniform bool radial, directvectors;
12 |
13 | void main() {
14 | vec2 xy = gl_FragCoord.xy;
15 |
16 | // Factor to convert [0,1] texture coords to pixels
17 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
18 |
19 | vec2 d = vec2(0.0);
20 |
21 | if(directvectors) {
22 | // Map input is already vectors, yay!
23 | d = texture2D(map, xy * px).xy;
24 | gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);
25 | return;
26 | }
27 |
28 | // Convolve by x and y Sobel matrices to get gradient vector
29 | d.x = 1.0 * texture2D(map, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
30 | d.x += 2.0 * texture2D(map, (xy + ksize * vec2(-1.0, 0.0)) * px).g;
31 | d.x += 1.0 * texture2D(map, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
32 | d.x += -1.0 * texture2D(map, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
33 | d.x += -2.0 * texture2D(map, (xy + ksize * vec2(+1.0, 0.0)) * px).g;
34 | d.x += -1.0 * texture2D(map, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
35 | d.y += 1.0 * texture2D(map, (xy + ksize * vec2(-1.0, -1.0)) * px).g;
36 | d.y += 2.0 * texture2D(map, (xy + ksize * vec2( 0.0, -1.0)) * px).g;
37 | d.y += 1.0 * texture2D(map, (xy + ksize * vec2(+1.0, -1.0)) * px).g;
38 | d.y += -1.0 * texture2D(map, (xy + ksize * vec2(-1.0, +1.0)) * px).g;
39 | d.y += -2.0 * texture2D(map, (xy + ksize * vec2( 0.0, +1.0)) * px).g;
40 | d.y += -1.0 * texture2D(map, (xy + ksize * vec2(+1.0, +1.0)) * px).g;
41 |
42 | if(!radial) {
43 | // Rotate 90 degrees
44 | d = vec2(-d.y, d.x);
45 | }
46 |
47 | // Bit of a bodge factor right here
48 | d *= 32.0 / ksize;
49 |
50 | // Output vectors for second pass
51 | gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);
52 | }
53 |
--------------------------------------------------------------------------------
/Ls_Splineblur.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Splineblur.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Splineblur.2.glsl:
--------------------------------------------------------------------------------
1 | // Directional blur driven by gradient vectors of front input
2 | // Pass 2: do the blur
3 | // lewis@lewissaunders.com
4 | // TOOD:
5 | // o Adaptive sampling based on length?
6 | // o Figure out correct calibration of length slider to pixel lengths?
7 | // o Triangular or gaussian window on samples?
8 | // o Normalize gradient vector and use another input for length control?
9 | // Currently, normalizing would give a super hard edge where the front
10 | // image is a solid colour
11 | // o Variable mix between the two algorithms would be neat
12 |
13 | uniform sampler2D front, map, adsk_results_pass1;
14 | uniform float adsk_result_w, adsk_result_h, blength;
15 | uniform int samples;
16 | uniform bool radial, vectors, normalize, pathy, adsk_degrade;
17 |
18 | void main() {
19 | vec2 xy = gl_FragCoord.xy;
20 |
21 | // Factor to convert [0,1] texture coords to pixels
22 | vec2 px = vec2(1.0) / vec2(adsk_result_w, adsk_result_h);
23 |
24 | // Get vectors from previous pass
25 | vec2 d = texture2D(adsk_results_pass1, xy * px).xy;
26 |
27 | if(vectors) {
28 | // Return the vectors, not the blur
29 | if(normalize) {
30 | // Bodge factor for a resonable result from PixelSpread
31 | d /= 4.0;
32 | d += 0.5;
33 | gl_FragColor = vec4(d.x, d.y, 1.0, 1.0);
34 | } else {
35 | gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);
36 | }
37 | return;
38 | }
39 |
40 | if(length(d) == 0.0) {
41 | // No gradient at this point in the map, early out
42 | gl_FragColor = texture2D(front, xy * px);
43 | return;
44 | }
45 |
46 | vec4 a = vec4(0.0);
47 | float sam = float(samples);
48 | float steps;
49 | bool odd = false;
50 |
51 | if(adsk_degrade) {
52 | sam /= 4.0;
53 | }
54 |
55 | if(!pathy) {
56 | // Do a way simpler blur along a line and get outta here
57 | vec2 step = d * blength / (sam - 1.0);
58 | for(float i = 0.0; i < sam; i++) {
59 | a += texture2D(front, (xy + (i - ((sam-1.0)/2.0)) * step) * px);
60 | }
61 | a /= sam;
62 | gl_FragColor = a;
63 | return;
64 | }
65 |
66 | if(mod(sam, 2.0) == 1.0) {
67 | odd = true;
68 | }
69 | if(odd) {
70 | // Odd number of samples, start with a sample from the current position
71 | a = texture2D(front, xy * px);
72 | steps = (sam - 1.0) / 2.0;
73 | } else {
74 | // Even number of samples, start with nothing
75 | a = vec4(0.0);
76 | steps = (sam / 2.0) - 1.0;
77 | }
78 |
79 | // Now accumulate along the path forwards...
80 | if(!odd) {
81 | // Even number of samples, first step is half length
82 | xy += 0.5 * d * blength / (sam - 1.0);
83 | a += texture2D(front, xy * px);
84 | }
85 | for(float i = 0.0; i < steps; i++) {
86 | d = texture2D(adsk_results_pass1, xy * px).xy;
87 | xy += d * blength / (sam - 1.0);
88 | a += texture2D(front, xy * px);
89 | }
90 |
91 | // ...and backwards
92 | xy = gl_FragCoord.xy;
93 | d = texture2D(adsk_results_pass1, xy * px).xy;
94 | if(!odd) {
95 | // Even number of samples, first step is half length
96 | xy -= 0.5 * d * blength / (sam - 1.0);
97 | a += texture2D(front, xy * px);
98 | }
99 | for(float i = 0.0; i < steps; i++) {
100 | xy -= d * blength / (sam - 1.0);
101 | a += texture2D(front, xy * px);
102 | d = texture2D(adsk_results_pass1, xy * px).xy;
103 | }
104 |
105 | a /= sam;
106 | gl_FragColor = a;
107 | }
108 |
--------------------------------------------------------------------------------
/Ls_Splineblur.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Ls_Stickon.1.glsl:
--------------------------------------------------------------------------------
1 | // Recursively warp an image by motion vectors to stick it to something
2 | // lewis@lewissaunders.com
3 | // Pass 1: recursively distort image or UV map by the motion vectors
4 |
5 | uniform sampler2D front, matte, vectors, adsk_accum_texture;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform bool adsk_accum_no_prev_frame;
8 | uniform bool accumulateUVs;
9 |
10 | void main() {
11 | vec2 res = vec2(adsk_result_w, adsk_result_h);
12 | vec2 uv = gl_FragCoord.xy / res;
13 | vec2 v = texture2D(vectors, uv).rg / res;
14 | vec4 o;
15 |
16 | if(adsk_accum_no_prev_frame) {
17 | // We're at the first frame, about to start accumulating
18 | if(accumulateUVs) {
19 | // Start out with an identity UV map
20 | o.rg = uv;
21 | o.ba = vec2(0.0);
22 | } else {
23 | // Start out with the first frame of the front/matte
24 | o.rgb = texture2D(front, uv).rgb;
25 | o.a = texture2D(matte, uv).b;
26 | }
27 | } else {
28 | // We are mid-accumulation
29 | // Take the previous output frame, offseting each sample
30 | // by the vectors for this frame
31 | o = texture2D(adsk_accum_texture, uv + v);
32 | }
33 |
34 | gl_FragColor = o;
35 | }
36 |
--------------------------------------------------------------------------------
/Ls_Stickon.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Stickon.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Stickon.2.glsl:
--------------------------------------------------------------------------------
1 | // Recursively warp an image by motion vectors to stick it to something
2 | // lewis@lewissaunders.com
3 | // Pass 2: comp and output distorted image
4 |
5 | uniform sampler2D front, matte, back, adsk_results_pass1;
6 | uniform float adsk_result_w, adsk_result_h;
7 | uniform bool accumulateUVs;
8 | uniform bool outputUVs;
9 | uniform bool comp, ispremult;
10 |
11 | void main() {
12 | vec2 res = vec2(adsk_result_w, adsk_result_h);
13 | vec2 uv = gl_FragCoord.xy / res;
14 | vec4 o;
15 |
16 | if(accumulateUVs) {
17 | vec2 accumulatedUV = texture2D(adsk_results_pass1, uv).rg;
18 | if(outputUVs) {
19 | // Output accumulated UVs directly
20 | o.rg = accumulatedUV;
21 | o.ba = vec2(0.0);
22 | } else {
23 | // Output of pass 1 is UVs, distort front and matte using them
24 | o.rgb = texture2D(front, accumulatedUV).rgb;
25 | o.a = texture2D(matte, accumulatedUV).b;
26 | }
27 | } else {
28 | // Output of pass 1 is image, we can use directly
29 | o.rgb = texture2D(adsk_results_pass1, uv).rgb;
30 | o.a = texture2D(adsk_results_pass1, uv).a;
31 | }
32 |
33 | if(!(outputUVs && accumulateUVs) && comp) {
34 | vec3 bg = texture2D(back, uv).rgb;
35 | if(ispremult) {
36 | o.rgb = bg * (1.0 - o.a) + o.rgb;
37 | } else {
38 | o.rgb = mix(bg.rgb, o.rgb, o.a);
39 | }
40 | }
41 |
42 | gl_FragColor = o;
43 | }
44 |
--------------------------------------------------------------------------------
/Ls_Sweat.1.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Sweat.1.glsl.p
--------------------------------------------------------------------------------
/Ls_Sweat.3.glsl:
--------------------------------------------------------------------------------
1 | // Sweat, pass 3: read sim matte and derive UVs
2 | // This is in a seperate pass to cache the UVs so we can multisample
3 | // them more cheaply
4 | // lewis@lewissaunders.com
5 |
6 | uniform sampler2D adsk_results_pass2, front;
7 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
8 | uniform float ksize;
9 |
10 | void main() {
11 | vec2 res = vec2(adsk_result_w, adsk_result_h);
12 | vec2 xy = gl_FragCoord.xy;
13 | float h = texture2D(adsk_results_pass2, xy/res).r;
14 |
15 | // Convolve by x and y Sobel matrices to get gradient vector
16 | vec2 d;
17 | d.x = -1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(-1.0, -1.0)) / res).g;
18 | d.x += -2.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(-1.0, 0.0)) / res).g;
19 | d.x += -1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(-1.0, +1.0)) / res).g;
20 | d.x += 1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(+1.0, -1.0)) / res).g;
21 | d.x += 2.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(+1.0, 0.0)) / res).g;
22 | d.x += 1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(+1.0, +1.0)) / res).g;
23 | d.y = -1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(-1.0, -1.0)) / res).g;
24 | d.y += -2.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2( 0.0, -1.0)) / res).g;
25 | d.y += -1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(+1.0, -1.0)) / res).g;
26 | d.y += 1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(-1.0, +1.0)) / res).g;
27 | d.y += 2.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2( 0.0, +1.0)) / res).g;
28 | d.y += 1.0 * texture2D(adsk_results_pass2, (xy + ksize * vec2(+1.0, +1.0)) / res).g;
29 | d /= ksize;
30 |
31 | gl_FragColor = vec4(d, h, h);
32 | }
33 |
--------------------------------------------------------------------------------
/Ls_Sweat.4.glsl:
--------------------------------------------------------------------------------
1 | // Sweat, pass 4: read UVs and distort the image
2 | // lewis@lewissaunders.com
3 |
4 | uniform sampler2D adsk_results_pass3, front;
5 | uniform float adsk_result_w, adsk_result_h, adsk_result_frameratio;
6 | uniform float distomult;
7 | uniform int isamples;
8 | uniform bool outputuvs;
9 |
10 | void main() {
11 | vec2 res = vec2(adsk_result_w, adsk_result_h);
12 | vec2 xy = gl_FragCoord.xy;
13 | vec2 uv = texture2D(adsk_results_pass3, xy/res).rg;
14 | float h = texture2D(adsk_results_pass3, xy/res).b;
15 | vec3 bg = texture2D(front, xy/res).rgb;
16 |
17 | // Multisampled UV mapping - read from the texture a bunch
18 | // of times and average to reduce noise. This seems more effective
19 | // than EWA filtering a lot of the time and is much faster
20 | vec3 rgb = vec3(0.0);
21 | float samps = float(isamples);
22 | float spacing = 1.0 / (samps + 1.0);
23 | for(float i = 1.0; i <= samps; i++) {
24 | for(float j = 1.0; j <= samps; j++) {
25 | vec2 sample_xy = floor(gl_FragCoord.xy);
26 | sample_xy += vec2(i, j) * vec2(spacing);
27 | vec2 sample_uv = texture2D(adsk_results_pass3, sample_xy/res).rg;
28 | sample_uv *= distomult;
29 | sample_uv += xy/res;
30 | rgb += texture2D(front, sample_uv).rgb;
31 | }
32 | }
33 | rgb /= samps * samps;
34 |
35 | if(outputuvs) {
36 | rgb.rg = uv;
37 | rgb.rg *= distomult;
38 | rgb.rg += xy/res;
39 | rgb.b = 0.0;
40 | bg.rg = xy/res;
41 | bg.b = 0.0;
42 | }
43 |
44 | // Comp the distorted front over the clean one with a cropped in matte
45 | // This removes some horrible edges
46 | float matte = clamp(pow((h * 2.0), 3.0), 0.0, 1.0);
47 | vec3 o = mix(bg, rgb, matte);
48 |
49 | gl_FragColor = vec4(o, matte);
50 | }
51 |
--------------------------------------------------------------------------------
/Ls_Tinyplanet.glsl:
--------------------------------------------------------------------------------
1 | // Stereographic projection of a 360x180 latlong panorama, tiny planets style
2 | // lewis@lewissaunders.com
3 |
4 | uniform float adsk_result_w, adsk_result_h;
5 | uniform sampler2D front;
6 | uniform float yo, xo, long0, lat1, r;
7 | uniform float latm, longm, lato, longo;
8 |
9 | // Defaults set in XML:
10 | // xo = 0.5
11 | // yo = 0.5
12 | // long0, lat1, r = adjusted to taste
13 | // latm = 1.0 / PI
14 | // longm = 1.0 / (2.0 * PI)
15 | // lato = -PI / 2.0
16 | // longo = -PI
17 |
18 | void main() {
19 | vec2 res = vec2(adsk_result_w, adsk_result_h);
20 | vec2 coords = gl_FragCoord.xy / res;
21 | coords.x -= 0.5;
22 | coords.x *= (res.x / res.y);
23 | coords.x += 0.5;
24 |
25 | float p = sqrt((coords.x-xo)*(coords.x-xo)+(coords.y-yo)*(coords.y-yo));
26 | float c = 2.0 * atan(p, 2.0 * r);
27 | float longg = (long0 + atan((coords.x-xo)*sin(c), p*cos(lat1)*cos(c) - (coords.y-yo)*sin(lat1)*sin(c)));
28 | float lat = asin(cos(c)*sin(lat1) + (((coords.y-yo)*sin(c)*cos(lat1)) / p));
29 | vec2 uv;
30 | uv.x = (longg - longo) * longm;
31 | uv.y = (lat - lato) * latm;
32 |
33 | vec3 o = texture2D(front, uv).rgb;
34 |
35 | gl_FragColor = vec4(o, 1.00);
36 | }
37 |
--------------------------------------------------------------------------------
/Ls_Tinyplanet.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Tinyplanet.glsl.p
--------------------------------------------------------------------------------
/Ls_Tinyplanet.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Ls_UVewa.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_UVewa.glsl.p
--------------------------------------------------------------------------------
/Ls_Vignette.glsl:
--------------------------------------------------------------------------------
1 | // Vignette
2 | // lewis@lewissaunders.com
3 |
4 | uniform float adsk_result_w, adsk_result_h;
5 | uniform float adsk_result_frameratio;
6 | uniform vec3 edgetint, midtint;
7 | uniform vec2 centre;
8 | uniform float radius, mixamt, abruptness, aspect;
9 | uniform sampler2D front;
10 | uniform bool clampblack, applyoffset;
11 |
12 | // S-shaped function with variable steepness s
13 | // Maps 0..1 to 0..1
14 | float smoothishstep(float x, float s) {
15 | if(x < 0.5) {
16 | return 0.5*((s*2.0*x - 2.0*x)/(2.0*s*2.0*x - s - 1.0));
17 | } else {
18 | float z = x - 0.5;
19 | float t = -s;
20 | return 0.5*((t*2.0*z - 2.0*z)/(2.0*t*2.0*z - t - 1.0)) + 0.5;
21 | }
22 | }
23 |
24 | void main() {
25 | vec2 uv = gl_FragCoord.xy / vec2(adsk_result_w, adsk_result_h);
26 | vec3 f = texture2D(front, uv).rgb;
27 |
28 | vec2 tocent = uv - centre;
29 | tocent.x *= adsk_result_frameratio;
30 | tocent.x *= aspect;
31 | float rad = length(tocent);
32 | rad /= radius;
33 | float v = pow(cos(clamp(rad, 0.0, 3.1415926535/2.0)), 4.0);
34 | v = smoothishstep(v, abruptness);
35 |
36 | vec3 o;
37 | if(applyoffset) {
38 | o = f - 0.3333 * (1.0 - v);
39 | o = mix(o, o + (edgetint - vec3(0.5)), 1.0 - v);
40 | o = mix(o, o + (midtint - vec3(0.5)), v);
41 | } else {
42 | o = f * v;
43 | o = mix(o, o * (edgetint + vec3(0.5)), 1.0 - v);
44 | o = mix(o, o * (midtint + vec3(0.5)), v);
45 | }
46 |
47 | o = mix(f, o, mixamt);
48 |
49 | if(clampblack) {
50 | o = clamp(o, 0.0, 999999.0);
51 | }
52 |
53 | float m = v;
54 | m = mix(1.0, m, mixamt);
55 |
56 | gl_FragColor = vec4(o, m);
57 | }
58 |
--------------------------------------------------------------------------------
/Ls_Vignette.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Vignette.glsl.p
--------------------------------------------------------------------------------
/Ls_Vops.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Vops.glsl.p
--------------------------------------------------------------------------------
/Ls_Wireless.glsl.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcrs/matchboxes/24c50c71de7681c7a86ed276e9f1c6b3e0f06ea2/Ls_Wireless.glsl.p
--------------------------------------------------------------------------------