Last active
December 8, 2025 06:27
-
-
Save AKST/f0edd31f4775ef7a7c8a190b281a05a1 to your computer and use it in GitHub Desktop.
some shader toy stuff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const float DITHER_SCALE = 8.0; | |
| const vec3 LUM_VECTOR = vec3(0.299, 0.587, 0.114); | |
| const mat4 BAYER_MATRIX = mat4( | |
| 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, | |
| 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, | |
| 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, | |
| 15.0/16.0, 7.0/16.0, 13.0/16.0, 5.0/16.0 | |
| ); | |
| vec2 square_coord(vec2 frag_coord) { | |
| return floor(frag_coord / DITHER_SCALE) * DITHER_SCALE + DITHER_SCALE * 0.5; | |
| } | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord ) | |
| { | |
| vec2 uv = square_coord(fragCoord) / iResolution.xy; | |
| vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4)); | |
| ivec2 pixelPos = ivec2(fragCoord / DITHER_SCALE) % 4; | |
| float threshold = BAYER_MATRIX[pixelPos.x][pixelPos.y]; | |
| float dithered = step(threshold, dot(col, LUM_VECTOR)); | |
| fragColor = vec4(vec3(dithered), 1.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const float DITHER_SCALE = 4.0; | |
| const vec3 LUM_VECTOR = vec3(0.299, 0.587, 0.114); | |
| const mat4 BAYER_MATRIX = mat4( | |
| 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, | |
| 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, | |
| 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, | |
| 15.0/16.0, 7.0/16.0, 13.0/16.0, 5.0/16.0 | |
| ); | |
| vec2 square_coord(vec2 frag_coord) { | |
| return floor(frag_coord / DITHER_SCALE) * DITHER_SCALE + DITHER_SCALE * 0.5; | |
| } | |
| /** | |
| * This is based on this guys tweet, with some changes. | |
| * | |
| * https://x.com/XorDev/status/1995634971030196401 | |
| */ | |
| vec3 colour_fn(vec2 coord, float time) { | |
| vec2 p = coord * 6.0 / iResolution.y; | |
| for (float i = 1.0; i <= 32.0; i++) { | |
| p += sin(p.yx * i + i * i + time * i + iResolution.xy) / i; | |
| } | |
| vec4 fragColor = tanh(0.2 / tan(p.y + vec4(0.0, 0.1, 0.3, 0.0))); | |
| return (fragColor * fragColor * fragColor * fragColor).xyz; | |
| } | |
| const vec3 DARK_BLUE = vec3(0.0, 0.0, 0.2); | |
| const vec3 CYAN = vec3(0.0, 0.2, 0.8); | |
| const vec3 YELLOW = vec3(1.0, 0.9, 0.0); | |
| const vec3 WHITE = vec3(1.0, 1.0, 1.0); | |
| vec3 gradient_map(float t) { | |
| if (t < 0.33) { | |
| return mix(DARK_BLUE, CYAN, t / 0.33); | |
| } else if (t < 0.66) { | |
| return mix(CYAN, YELLOW, (t - 0.33) / 0.33); | |
| } else { | |
| return mix(YELLOW, WHITE, (t - 0.66) / 0.34); | |
| } | |
| } | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord) { | |
| float wave = sin(fragCoord.y * 0.02 + iTime / 16.0) * 0.5 + 0.5; | |
| vec2 coord_dist = vec2( | |
| fragCoord.x + 300.0 * wave, | |
| fragCoord.y | |
| ); | |
| vec3 col = colour_fn(square_coord(coord_dist), 1.0 * iTime); | |
| float lum = dot(col, LUM_VECTOR); | |
| vec3 mapped_col = gradient_map(lum); | |
| ivec2 pixelPos = ivec2(fragCoord / DITHER_SCALE) % 4; | |
| float threshold = BAYER_MATRIX[pixelPos.x][pixelPos.y]; | |
| vec3 dithered = step(threshold, mapped_col); | |
| fragColor = vec4(vec3(dithered), 1.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const float DITHER_SCALE = 4.0; | |
| const vec3 LUM_VECTOR = vec3(0.299, 0.587, 0.114); | |
| const mat4 BAYER_MATRIX = mat4( | |
| 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, | |
| 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, | |
| 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, | |
| 15.0/16.0, 7.0/16.0, 13.0/16.0, 5.0/16.0 | |
| ); | |
| vec2 square_coord(vec2 frag_coord) { | |
| return floor(frag_coord / DITHER_SCALE) * DITHER_SCALE + DITHER_SCALE * 0.5; | |
| } | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord) { | |
| vec2 uv = square_coord(fragCoord) / iResolution.xy; | |
| vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4)); | |
| ivec2 pixelPos = ivec2(fragCoord / DITHER_SCALE) % 4; | |
| float threshold = BAYER_MATRIX[pixelPos.x][pixelPos.y]; | |
| float dithered = step(threshold, dot(col, LUM_VECTOR)); | |
| float g = 0.3 + 0.7 * dithered; | |
| float b = 1.0 - 0.5 * dithered; | |
| fragColor = vec4(1.0, g, b, 1.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * This is my first attempt at dithering, I just adapted the default shader | |
| */ | |
| const float DITHER_SCALE = 4.0; | |
| const float RGB_LEVEL = 8.0; | |
| const vec3 LUM_VECTOR = vec3(0.299, 0.587, 0.114); | |
| const mat4 BAYER_MATRIX = mat4( | |
| 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, | |
| 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, | |
| 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, | |
| 15.0/16.0, 7.0/16.0, 13.0/16.0, 5.0/16.0 | |
| ); | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord ) { | |
| vec2 uv = fragCoord/iResolution.xy; | |
| vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4)); | |
| ivec2 pixelPos = ivec2(fragCoord / DITHER_SCALE) % 4; | |
| float threshold = BAYER_MATRIX[pixelPos.x][pixelPos.y]; | |
| float dithered = step(threshold, dot(col, LUM_VECTOR)); | |
| col = floor(col * RGB_LEVEL + threshold) / RGB_LEVEL; | |
| fragColor = vec4(col / vec3(dithered), 1.0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const float DITHER_SCALE = 4.0; | |
| const float TARGET_FPS = 30.0; | |
| const float SCANLINE_FPS = 60.0; | |
| const vec3 LUM_VECTOR = vec3(0.299, 0.587, 0.114); | |
| const mat4 BAYER_MATRIX = mat4( | |
| 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, | |
| 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, | |
| 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, | |
| 15.0/16.0, 7.0/16.0, 13.0/16.0, 5.0/16.0 | |
| ); | |
| vec2 square_coord(vec2 frag_coord) { | |
| return floor(frag_coord / DITHER_SCALE) * DITHER_SCALE + DITHER_SCALE * 0.5; | |
| } | |
| /** | |
| * This is based on this guys tweet, with some changes. | |
| * | |
| * https://x.com/XorDev/status/1995634971030196401 | |
| */ | |
| vec3 colour_fn(vec2 coord, float time) { | |
| vec2 p = coord * 6.0 / iResolution.y; | |
| for (float i = 1.0; i <= 32.0; i++) { | |
| p += sin(p.yx * i + i * i + time * i + iResolution.xy) / i; | |
| } | |
| vec4 fragColor = tanh(0.2 / tan(p.y + vec4(0.0, 0.1, 0.3, 0.0))); | |
| return (fragColor * fragColor).xyz; | |
| } | |
| const vec3 DARK_BLUE = vec3(0.0, 0.0, 0.2); | |
| const vec3 CYAN = vec3(0.0, 0.2, 0.8); | |
| const vec3 YELLOW = vec3(1.0, 0.9, 0.0); | |
| const vec3 WHITE = vec3(1.0, 1.0, 1.0); | |
| vec3 gradient_map(float t) { | |
| if (t < 0.33) { | |
| return mix(DARK_BLUE, CYAN, t / 0.33); | |
| } else if (t < 0.66) { | |
| return mix(CYAN, YELLOW, (t - 0.33) / 0.33); | |
| } else { | |
| return mix(YELLOW, WHITE, (t - 0.66) / 0.34); | |
| } | |
| } | |
| vec3 render_cell(vec2 coord, float time) { | |
| float wave = sin(coord.y * 0.02 + time / 16.0) * 0.5 + 0.5; | |
| vec2 coord_dist = vec2(coord.x + 200.0 * wave, coord.y); | |
| vec3 col_base = colour_fn(square_coord(coord_dist), 2.0 * time); | |
| ivec2 pixelPos = ivec2(coord / DITHER_SCALE) % 4; | |
| float threshold = BAYER_MATRIX[pixelPos.x][pixelPos.y]; | |
| float lum = dot(col_base, LUM_VECTOR); | |
| vec3 mapped_col = gradient_map(lum); | |
| return step(threshold, mapped_col); | |
| } | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord) { | |
| float quantized_time = floor(iTime * TARGET_FPS) / TARGET_FPS; | |
| float scanline_time = floor(iTime * SCANLINE_FPS) / SCANLINE_FPS; | |
| float is_even_frame = mod(floor(scanline_time * SCANLINE_FPS), 2.0); | |
| float a = mod(fragCoord.y, DITHER_SCALE); | |
| float b = DITHER_SCALE / 2.0; | |
| float refresh = mix(step(a, b), step(b, a), is_even_frame); | |
| if (refresh == 1.0) { | |
| vec3 cell_base = render_cell(fragCoord, quantized_time); | |
| fragColor = vec4(mix(cell_base, vec3(1.0), 0.1), 1.0); | |
| } else { | |
| float last_frame = (floor(iTime * TARGET_FPS) - 1.0) / TARGET_FPS; | |
| vec3 cell_base = render_cell(fragCoord, last_frame) * 0.5; | |
| vec2 coord_u = fragCoord - vec2(0.0, DITHER_SCALE); | |
| vec2 coord_b = fragCoord + vec2(0.0, DITHER_SCALE); | |
| vec3 col_u = render_cell(coord_u, quantized_time) * 0.5; | |
| vec3 col_b = render_cell(coord_b, quantized_time) * 0.5; | |
| vec3 col_bleed = mix(col_u, col_b, 0.5); | |
| fragColor = vec4(mix(col_bleed, cell_base, 0.5), 1.0); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const float DITHER_SCALE = 3.0; | |
| const vec3 LUM_VECTOR = vec3(0.299, 0.587, 0.114); | |
| const mat4 BAYER_MATRIX = mat4( | |
| 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, | |
| 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, | |
| 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, | |
| 15.0/16.0, 7.0/16.0, 13.0/16.0, 5.0/16.0 | |
| ); | |
| vec2 square_coord(vec2 frag_coord) { | |
| return floor(frag_coord / DITHER_SCALE) * DITHER_SCALE + DITHER_SCALE * 0.5; | |
| } | |
| /** | |
| * This is basically this guys tweet | |
| * | |
| * https://x.com/XorDev/status/1995634971030196401 | |
| */ | |
| vec3 colour_fn(vec2 coord) { | |
| vec2 p = coord * 6.0 / iResolution.y; | |
| for (float i = 1.0; i <= 10.0; i++) { | |
| p += sin(p.yx * i + i * i + iTime * i + iResolution.xy) / i; | |
| } | |
| vec4 fragColor = tanh(0.2 / tan(p.y + vec4(0.0, 0.1, 0.3, 0.0))); | |
| return (fragColor * fragColor).xyz; | |
| } | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord) { | |
| vec3 col = colour_fn(square_coord(fragCoord)); | |
| ivec2 pixelPos = ivec2(fragCoord / DITHER_SCALE) % 4; | |
| float threshold = BAYER_MATRIX[pixelPos.x][pixelPos.y]; | |
| float dithered = step(threshold, dot(col, LUM_VECTOR)); | |
| fragColor = vec4(vec3(dithered), 1.0); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment