├── .gitignore ├── jetson_nano.jpg ├── raspberry_pi.jpg ├── presets ├── tex_bayer.png ├── tex_stars.jpg ├── tex_wood.jpg ├── cube_forest.png ├── tex_font_01.png ├── tex_lichen.jpg ├── tex_london.jpg ├── tex_nyancat.png ├── tex_pebbles.png ├── tex_organic_01.jpg ├── tex_organic_02.jpg ├── tex_organic_03.jpg ├── tex_organic_04.jpg ├── tex_rock_tiles.jpg ├── tex_abstract_01.jpg ├── tex_abstract_02.jpg ├── tex_abstract_03.jpg ├── tex_rusty_metal.jpg ├── vid_google_logo.png ├── cube_forest_blurred.png ├── cube_uffizi_gallery.jpg ├── vid_1961_commercial.png ├── vid_britney_spears.png ├── vol_RGBA_noise_3D.bin ├── vol_grey_noise_3D.bin ├── tex_RGBA_noise_medium.png ├── tex_RGBA_noise_small.png ├── tex_gray_noise_medium.png ├── tex_gray_noise_small.png ├── vid_claude_van_damme.png ├── cube_st_peter_basilica.jpg ├── cube_uffizi_gallery_blurred.png └── cube_st_peter_basilica_blurred.png ├── examples ├── old_skool_3d_driving.glsl ├── creation_by_silexars.glsl ├── viscosity.glsl ├── breathing_spirals.glsl ├── clockwork_spacetime.glsl ├── blobs.glsl ├── stripey_torus_interior.glsl ├── flower_of_life_rgb.glsl ├── white_drops.glsl ├── orbital_2d.glsl ├── ring_twister.glsl ├── bokeh_parallax.glsl ├── menger_sponge_tunnel.glsl ├── duality2.glsl ├── odd_structures.glsl ├── planetary_gears.glsl ├── the_inversion_machine.glsl ├── universe_within_314.glsl ├── complex_field_lines.glsl ├── truchet_trip.glsl ├── 2d_clouds.glsl ├── infinite_gamecube.glsl ├── warping_boxes.glsl ├── smooth_contours.glsl ├── linear_to_hilbert.glsl ├── gyroidal_morphoma.glsl ├── glossy_cubes.glsl ├── synthwave_road.glsl ├── oklab_based_tonemapper.glsl ├── grid_blend.glsl ├── the_secret_place.glsl ├── weaving_bridges.glsl ├── plasma_globe.glsl ├── tilings.glsl ├── saturday_torus.glsl ├── starry_landscape.glsl ├── rainbow_smith_cells.glsl ├── cyber_fuji_2020.glsl ├── surveillance_mosaic.glsl ├── lonely_waters.glsl ├── cross_galactic_ocean.glsl └── torus_loop.glsl ├── Makefile ├── LICENSE ├── lib.py ├── glsl.h ├── lease.h ├── tests ├── mouse.glsl ├── touch.glsl ├── input.py └── keyboard.glsl ├── inotify.py ├── drm-common.h ├── lease.c ├── drm-legacy.c └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | glsl 4 | 5 | __pycache__/ 6 | .venv 7 | venv/ 8 | -------------------------------------------------------------------------------- /jetson_nano.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/jetson_nano.jpg -------------------------------------------------------------------------------- /raspberry_pi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/raspberry_pi.jpg -------------------------------------------------------------------------------- /presets/tex_bayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_bayer.png -------------------------------------------------------------------------------- /presets/tex_stars.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_stars.jpg -------------------------------------------------------------------------------- /presets/tex_wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_wood.jpg -------------------------------------------------------------------------------- /presets/cube_forest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/cube_forest.png -------------------------------------------------------------------------------- /presets/tex_font_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_font_01.png -------------------------------------------------------------------------------- /presets/tex_lichen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_lichen.jpg -------------------------------------------------------------------------------- /presets/tex_london.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_london.jpg -------------------------------------------------------------------------------- /presets/tex_nyancat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_nyancat.png -------------------------------------------------------------------------------- /presets/tex_pebbles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_pebbles.png -------------------------------------------------------------------------------- /presets/tex_organic_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_organic_01.jpg -------------------------------------------------------------------------------- /presets/tex_organic_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_organic_02.jpg -------------------------------------------------------------------------------- /presets/tex_organic_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_organic_03.jpg -------------------------------------------------------------------------------- /presets/tex_organic_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_organic_04.jpg -------------------------------------------------------------------------------- /presets/tex_rock_tiles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_rock_tiles.jpg -------------------------------------------------------------------------------- /presets/tex_abstract_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_abstract_01.jpg -------------------------------------------------------------------------------- /presets/tex_abstract_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_abstract_02.jpg -------------------------------------------------------------------------------- /presets/tex_abstract_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_abstract_03.jpg -------------------------------------------------------------------------------- /presets/tex_rusty_metal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_rusty_metal.jpg -------------------------------------------------------------------------------- /presets/vid_google_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/vid_google_logo.png -------------------------------------------------------------------------------- /presets/cube_forest_blurred.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/cube_forest_blurred.png -------------------------------------------------------------------------------- /presets/cube_uffizi_gallery.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/cube_uffizi_gallery.jpg -------------------------------------------------------------------------------- /presets/vid_1961_commercial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/vid_1961_commercial.png -------------------------------------------------------------------------------- /presets/vid_britney_spears.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/vid_britney_spears.png -------------------------------------------------------------------------------- /presets/vol_RGBA_noise_3D.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/vol_RGBA_noise_3D.bin -------------------------------------------------------------------------------- /presets/vol_grey_noise_3D.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/vol_grey_noise_3D.bin -------------------------------------------------------------------------------- /presets/tex_RGBA_noise_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_RGBA_noise_medium.png -------------------------------------------------------------------------------- /presets/tex_RGBA_noise_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_RGBA_noise_small.png -------------------------------------------------------------------------------- /presets/tex_gray_noise_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_gray_noise_medium.png -------------------------------------------------------------------------------- /presets/tex_gray_noise_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/tex_gray_noise_small.png -------------------------------------------------------------------------------- /presets/vid_claude_van_damme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/vid_claude_van_damme.png -------------------------------------------------------------------------------- /presets/cube_st_peter_basilica.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/cube_st_peter_basilica.jpg -------------------------------------------------------------------------------- /presets/cube_uffizi_gallery_blurred.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/cube_uffizi_gallery_blurred.png -------------------------------------------------------------------------------- /presets/cube_st_peter_basilica_blurred.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/astefanutti/kms-glsl/HEAD/presets/cube_st_peter_basilica_blurred.png -------------------------------------------------------------------------------- /examples/old_skool_3d_driving.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/XtlGW4 2 | // Created by https://www.shadertoy.com/user/mattz 3 | 4 | void mainImage( out vec4 f, vec2 p ){ 5 | 6 | vec3 q=iResolution,d=vec3(p-.5*q.xy,q.y)/q.y,c=vec3(0,.5,.7); 7 | 8 | q=d/(.1-d.y); 9 | float a=iTime, k=sin(.2*a), w = q.x *= q.x-=.05*k*k*k*q.z*q.z; 10 | 11 | f.xyz=d.y>.04?c: 12 | sin(4.*q.z+40.*a)>0.? 13 | w>2.?c.xyx:w>1.2?d.zzz:c.yyy: 14 | w>2.?c.xzx:w>1.2?c.yxx*2.:(w>.004?c:d).zzz; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /examples/creation_by_silexars.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/XsXXDn 2 | // Created by https://www.shadertoy.com/user/Danguafer 3 | 4 | // http://www.pouet.net/prod.php?which=57245 5 | // If you intend to reuse this shader, please add credits to 'Danilo Guanabara' 6 | 7 | #define t iTime 8 | #define r iResolution.xy 9 | 10 | void mainImage( out vec4 fragColor, in vec2 fragCoord ){ 11 | vec3 c; 12 | float l,z=t; 13 | for(int i=0;i<3;i++) { 14 | vec2 uv,p=fragCoord.xy/r; 15 | uv=p; 16 | p-=.5; 17 | p.x*=r.x/r.y; 18 | z+=.07; 19 | l=length(p); 20 | uv+=p/l*(sin(z)+1.)*abs(sin(l*9.-z*2.)); 21 | c[i]=.01/length(abs(mod(uv,1.)-.5)); 22 | } 23 | fragColor=vec4(c/l,t); 24 | } 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-c -g -Wall -O3 -Winvalid-pch -Wextra -std=gnu99 -fPIC -fdiagnostics-color=always -pipe -pthread -I/usr/include/libdrm 3 | LDFLAGS=-Wl,--no-as-needed -lGLESv2 -Wl,--as-needed,--no-undefined 4 | LDLIBS=-lGLESv2 -lEGL -ldrm -lgbm -lxcb-randr -lxcb -lpthread 5 | SOURCES=common.c drm-atomic.c drm-common.c drm-legacy.c glsl.c lease.c perfcntrs.c shadertoy.c 6 | OBJECTS=$(SOURCES:%.c=%.o) 7 | EXECUTABLE=glsl 8 | LIBRARY=glsl.so 9 | 10 | all: $(SOURCES) $(EXECUTABLE) $(LIBRARY) 11 | 12 | $(EXECUTABLE): $(OBJECTS) 13 | $(CC) $(LDFLAGS) $(OBJECTS) $(LDLIBS) -o $@ 14 | 15 | $(LIBRARY): $(OBJECTS) 16 | $(CC) $(LDFLAGS) $(OBJECTS) $(LDLIBS) -shared -o $@ 17 | 18 | .c.o: 19 | $(CC) $(CFLAGS) $< -o $@ 20 | 21 | clean : 22 | rm -f *.o $(EXECUTABLE) $(LIBRARY) 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Antonin Stefanutti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /lib.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | 3 | glsl = CDLL("./glsl.so") 4 | 5 | 6 | class OPTIONS(Structure): 7 | _fields_ = [ 8 | ("device", c_char_p), 9 | ("mode", c_ubyte * 32), 10 | ("format", c_uint32), 11 | ("modifier", c_uint64), 12 | ("connector", c_int), 13 | ("async_page_flip", c_bool), 14 | ("atomic_drm_mode", c_bool), 15 | ("surfaceless", c_bool), 16 | ("vrefresh", c_int), 17 | ("frames", c_uint), 18 | ] 19 | 20 | 21 | def options(args): 22 | c_opts = OPTIONS() 23 | if args.async_page_flip: 24 | c_opts.async_page_flip = c_bool(True) 25 | if args.atomic_drm_mode: 26 | c_opts.atomic_drm_mode = c_bool(True) 27 | if args.connector: 28 | c_opts.connector = c_int(args.connector) 29 | else: 30 | c_opts.connector = -1 31 | if args.device: 32 | c_opts.device = bytes(args.device.as_posix(), 'utf-8') 33 | if args.mode: 34 | c_opts.mode = (c_ubyte * 32)(*bytes(args.mode, 'utf-8')) 35 | if args.frames: 36 | c_opts.frames = c_uint(args.frames) 37 | return c_opts 38 | -------------------------------------------------------------------------------- /examples/viscosity.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/tdyBRt 2 | // Created by https://www.shadertoy.com/user/klk 3 | 4 | // Created by Alex Kluchikov 5 | 6 | #define PI 3.141592654 7 | 8 | vec2 rot(vec2 p,float a) 9 | { 10 | float c=cos(a*15.83); 11 | float s=sin(a*15.83); 12 | return p*mat2(s,c,c,-s); 13 | } 14 | 15 | void mainImage(out vec4 o, in vec2 uv) 16 | { 17 | uv/=iResolution.xx; 18 | uv=vec2(.125,.75)+(uv-vec2(.125,.75))*.03; 19 | float T=iTime*.25; 20 | 21 | vec3 c = clamp(1.-.7*vec3( 22 | length(uv-vec2(.1,0)), 23 | length(uv-vec2(.9,0)), 24 | length(uv-vec2(.5,1)) 25 | ),0.,1.)*2.-1.; 26 | 27 | vec3 c0=vec3(0); 28 | float w0=0.; 29 | const float N=16.; 30 | for(float i=0.;i 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the 12 | * next paragraph) shall be included in all copies or substantial portions 13 | * of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef _GLSL_H 25 | #define _GLSL_H 26 | 27 | #include "common.h" 28 | 29 | extern int init(const char *shadertoy, const struct options *options); 30 | extern int run(); 31 | extern int join(); 32 | extern void stop(); 33 | 34 | extern void onInit(void callback(uint program, uint width, uint height)); 35 | extern void onRender(void callback(uint64_t frame, float time)); 36 | 37 | #endif /* _GLSL_H */ 38 | -------------------------------------------------------------------------------- /examples/breathing_spirals.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/NsBSRt 2 | // Created by https://www.shadertoy.com/user/ykcwa 3 | 4 | // from https://www.shadertoy.com/view/Mls3R7 5 | void rotate(inout vec2 p,float angle,vec2 rotationOrigin) 6 | { 7 | p -= rotationOrigin; 8 | p *= mat2(cos(angle),-sin(angle),sin(angle),cos(angle)); 9 | p += rotationOrigin; 10 | } 11 | 12 | 13 | float stripe(float x, float stripeWidth) { 14 | float s = mod(x + 0.5 * stripeWidth, 2.0 * stripeWidth); 15 | if (s > stripeWidth) { 16 | s = 2.0 * stripeWidth - s; 17 | } 18 | float smoothness = 4./iResolution.y; 19 | return smoothstep(stripeWidth * 0.5, stripeWidth * 0.5 - smoothness, s); 20 | } 21 | 22 | float xorBW(float color1, float color2) { 23 | return abs(color1 - color2); 24 | } 25 | 26 | float spiralColor(vec2 uv, int numStripes, float curveRate) { 27 | float r = length(uv); 28 | float angle = atan(uv.x, uv.y) + curveRate * r; 29 | return stripe(angle, 2.0 * 3.14159 / float(numStripes)); 30 | } 31 | 32 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 33 | { 34 | // Normalized pixel coordinates (y from -0.5 to 0.5, x scaled appropriately) 35 | vec2 uv = ( fragCoord - .5* iResolution.xy) / iResolution.y; 36 | 37 | int numStripes = 16; 38 | float curveRate = 2.0; 39 | float rotAngle = cos(iTime / 3.0); 40 | 41 | vec2 uv1 = vec2(uv.x, uv.y); 42 | rotate(uv1, 0.0 * rotAngle, vec2(0)); 43 | 44 | vec2 uv2 = vec2(-1.0 * uv.x, uv.y); 45 | rotate(uv2, 3.0 * rotAngle, vec2(0)); 46 | 47 | float spiral1 = spiralColor(uv1, numStripes, curveRate); 48 | float spiral2 = spiralColor(uv2, numStripes, curveRate); 49 | 50 | 51 | fragColor = vec4(vec3(xorBW(spiral1, spiral2)), 1.0); 52 | } 53 | -------------------------------------------------------------------------------- /lease.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Arvin Schnell 3 | * Copyright (c) 2012 Rob Clark 4 | * Copyright (c) 2020 Antonin Stefanutti 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a 7 | * copy of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sub license, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice (including the 14 | * next paragraph) shall be included in all copies or substantial portions 15 | * of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | * DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #ifndef _LEASE_H 27 | #define _LEASE_H 28 | 29 | #ifndef XCB_LEASE 30 | #if __has_include() && __has_include() 31 | #define XCB_LEASE 1 32 | #endif 33 | #endif 34 | 35 | #if XCB_LEASE 36 | 37 | #include 38 | #include 39 | 40 | int xcb_lease(xcb_connection_t *connection, int *screen); 41 | 42 | #endif 43 | 44 | #endif /* _LEASE_H */ 45 | -------------------------------------------------------------------------------- /examples/clockwork_spacetime.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/7d23R3 2 | // Created by https://www.shadertoy.com/user/Tater 3 | 4 | #define pi 3.14159265359 5 | #define rot(a) mat2( cos(a),-sin(a),sin(a),cos(a) ) 6 | #define a(c) float( clamp(c,0.0,1.0) ) 7 | float gear(vec2 uv, float aa,float tth){ 8 | float inn = 0.275; //Inner Circle Size 9 | float th = atan(-uv.y,-uv.x)/(2.0*pi)+0.5; 10 | float id = mod(floor(th*tth),2.0); 11 | th = mod(th,1./tth)*tth; 12 | float r = length(uv); 13 | float c = smoothstep(r-aa,r+aa,inn); 14 | th = abs(th-0.5)*1.05; 15 | float end = (-pow(th,3.4)+1.0)*0.425; //Tooth Shape 16 | c += smoothstep(r-aa,r+aa,end)*id* 17 | smoothstep(th-aa*tth/2.5,th+aa*tth/2.5,0.5); 18 | return c; 19 | } 20 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 21 | { 22 | vec2 R = iResolution.xy; 23 | vec2 uv = (fragCoord-.5*R.xy)/R.y; 24 | float aa = 1./R.y; 25 | 26 | float t = iTime*1.5; 27 | //Time Warping 28 | t = pow(fract(t),3.5)+floor(t); 29 | 30 | //Size of rotation steps 31 | t*=pi/(6.0); 32 | 33 | //Whole Screen Rotation + direction flip 34 | uv*=rot(-t*sign(sin(t))); 35 | vec2 uv2 = uv; 36 | 37 | //Gear Tooth Count /2 (works well with 20,16,12,8,4) 38 | float tth =12.0; 39 | 40 | //Overall Scale 41 | float scl = 3.7; 42 | 43 | //Zoom In/Out 44 | scl-=cos(t)*0.75; 45 | 46 | //Slight Initial Offset 47 | t+=pi/tth; 48 | 49 | //Edge of screen warping 50 | scl*=1.0+pow(length(uv),10.0); 51 | 52 | //The Gears 53 | aa*=scl; 54 | vec3 gearCol = vec3(1.0); //I like it b/w but you can change it 55 | uv = 0.5-fract(uv*scl); 56 | uv *= rot(-t); 57 | vec3 col = gearCol*a(gear(uv,aa,tth))*(1.0-length(uv)); 58 | 59 | t+=pi/2.; 60 | uv2 += 0.5/scl; 61 | uv = 0.5-fract(uv2*scl); 62 | uv *= rot(t); 63 | col += gearCol*a(gear(uv,aa,tth))*(0.05+length(uv)); 64 | 65 | fragColor = vec4(col,1.0); 66 | } 67 | -------------------------------------------------------------------------------- /tests/mouse.glsl: -------------------------------------------------------------------------------- 1 | // python glsl.py tests/mouse.glsl 2 | 3 | // Created by inigo quilez - iq/2013 4 | // https://www.youtube.com/c/InigoQuilez 5 | // https://iquilezles.org/ 6 | 7 | // Shows how to use the mouse input (only left button supported): 8 | // 9 | // mouse.xy = mouse position during last button down 10 | // abs(mouse.zw) = mouse position during last button click 11 | // sign(mouze.z) = button is down 12 | // sign(mouze.w) = button is clicked 13 | 14 | // See also: 15 | // 16 | // Input - Keyboard : https://www.shadertoy.com/view/lsXGzf 17 | // Input - Microphone : https://www.shadertoy.com/view/llSGDh 18 | // Input - Mouse : https://www.shadertoy.com/view/Mss3zH 19 | // Input - Sound : https://www.shadertoy.com/view/Xds3Rr 20 | // Input - SoundCloud : https://www.shadertoy.com/view/MsdGzn 21 | // Input - Time : https://www.shadertoy.com/view/lsXGz8 22 | // Input - TimeDelta : https://www.shadertoy.com/view/lsKGWV 23 | // Inout - 3D Texture : https://www.shadertoy.com/view/4llcR4 24 | 25 | float distanceToSegment( vec2 a, vec2 b, vec2 p ) 26 | { 27 | vec2 pa = p - a, ba = b - a; 28 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); 29 | return length( pa - ba*h ); 30 | } 31 | 32 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 33 | { 34 | vec2 p = fragCoord / iResolution.x; 35 | vec2 cen = 0.5*iResolution.xy/iResolution.x; 36 | vec4 m = iMouse / iResolution.x; 37 | 38 | vec3 col = vec3(0.0); 39 | 40 | if( m.z>0.0 ) // button is down 41 | { 42 | float d = distanceToSegment( m.xy, abs(m.zw), p ); 43 | col = mix( col, vec3(1.0,1.0,0.0), 1.0-smoothstep(.004,0.008, d) ); 44 | } 45 | if( m.w>0.0 ) // button click 46 | { 47 | col = mix( col, vec3(1.0,1.0,1.0), 1.0-smoothstep(0.1,0.105, length(p-cen)) ); 48 | } 49 | 50 | col = mix( col, vec3(1.0,0.0,0.0), 1.0-smoothstep(0.03,0.035, length(p- m.xy )) ); 51 | col = mix( col, vec3(0.0,0.0,1.0), 1.0-smoothstep(0.03,0.035, length(p-abs(m.zw))) ); 52 | 53 | fragColor = vec4( col, 1.0 ); 54 | } 55 | -------------------------------------------------------------------------------- /examples/blobs.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/lsfGzr 2 | // Created by https://www.shadertoy.com/user/PauloFalcao 3 | 4 | // Blobs by @paulofalcao 5 | 6 | #define time iTime 7 | 8 | float makePoint(float x,float y,float fx,float fy,float sx,float sy,float t){ 9 | float xx=x+sin(t*fx)*sx; 10 | float yy=y+cos(t*fy)*sy; 11 | return 1.0/sqrt(xx*xx+yy*yy); 12 | } 13 | 14 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 15 | 16 | vec2 p=(fragCoord.xy/iResolution.x)*2.0-vec2(1.0,iResolution.y/iResolution.x); 17 | 18 | p=p*2.0; 19 | 20 | float x=p.x; 21 | float y=p.y; 22 | 23 | float a= 24 | makePoint(x,y,3.3,2.9,0.3,0.3,time); 25 | a=a+makePoint(x,y,1.9,2.0,0.4,0.4,time); 26 | a=a+makePoint(x,y,0.8,0.7,0.4,0.5,time); 27 | a=a+makePoint(x,y,2.3,0.1,0.6,0.3,time); 28 | a=a+makePoint(x,y,0.8,1.7,0.5,0.4,time); 29 | a=a+makePoint(x,y,0.3,1.0,0.4,0.4,time); 30 | a=a+makePoint(x,y,1.4,1.7,0.4,0.5,time); 31 | a=a+makePoint(x,y,1.3,2.1,0.6,0.3,time); 32 | a=a+makePoint(x,y,1.8,1.7,0.5,0.4,time); 33 | 34 | float b= 35 | makePoint(x,y,1.2,1.9,0.3,0.3,time); 36 | b=b+makePoint(x,y,0.7,2.7,0.4,0.4,time); 37 | b=b+makePoint(x,y,1.4,0.6,0.4,0.5,time); 38 | b=b+makePoint(x,y,2.6,0.4,0.6,0.3,time); 39 | b=b+makePoint(x,y,0.7,1.4,0.5,0.4,time); 40 | b=b+makePoint(x,y,0.7,1.7,0.4,0.4,time); 41 | b=b+makePoint(x,y,0.8,0.5,0.4,0.5,time); 42 | b=b+makePoint(x,y,1.4,0.9,0.6,0.3,time); 43 | b=b+makePoint(x,y,0.7,1.3,0.5,0.4,time); 44 | 45 | float c= 46 | makePoint(x,y,3.7,0.3,0.3,0.3,time); 47 | c=c+makePoint(x,y,1.9,1.3,0.4,0.4,time); 48 | c=c+makePoint(x,y,0.8,0.9,0.4,0.5,time); 49 | c=c+makePoint(x,y,1.2,1.7,0.6,0.3,time); 50 | c=c+makePoint(x,y,0.3,0.6,0.5,0.4,time); 51 | c=c+makePoint(x,y,0.3,0.3,0.4,0.4,time); 52 | c=c+makePoint(x,y,1.4,0.8,0.4,0.5,time); 53 | c=c+makePoint(x,y,0.2,0.6,0.6,0.3,time); 54 | c=c+makePoint(x,y,1.3,0.5,0.5,0.4,time); 55 | 56 | vec3 d=vec3(a,b,c)/32.0; 57 | 58 | fragColor = vec4(d.x,d.y,d.z,(d.x+d.y+d.z)/3.0); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /inotify.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | from ctypes import CDLL, c_int 3 | from ctypes.util import find_library 4 | from fcntl import ioctl 5 | from io import FileIO 6 | from os import fsencode, fsdecode, read, O_CLOEXEC 7 | from select import poll 8 | from struct import unpack_from, calcsize 9 | from termios import FIONREAD 10 | 11 | try: 12 | libc_so = find_library('c') 13 | except RuntimeError: 14 | libc_so = None 15 | _libc = CDLL(libc_so or 'libc.so.6', use_errno=True) 16 | 17 | Event = namedtuple('Event', ['wd', 'mask', 'cookie', 'name']) 18 | 19 | IN_ATTRIB = 0x00000004 # Metadata changed 20 | IN_CREATE = 0x00000100 # Subfile was created 21 | 22 | _EVENT_FMT = 'iIII' 23 | _EVENT_SIZE = calcsize(_EVENT_FMT) 24 | 25 | 26 | class INotify(FileIO): 27 | 28 | fd = property(FileIO.fileno) 29 | 30 | def __init__(self, flags=O_CLOEXEC): 31 | FileIO.__init__(self, _libc.inotify_init1(flags), mode='rb') 32 | 33 | self._poller = poll() 34 | self._poller.register(self.fileno()) 35 | 36 | def add_watch(self, path, mask): 37 | return _libc.inotify_add_watch(self.fileno(), fsencode(path), mask) 38 | 39 | def rm_watch(self, wd): 40 | _libc.inotify_rm_watch(self.fileno(), wd) 41 | 42 | def read(self, timeout=None) -> [Event]: 43 | data = self._readall() 44 | if not data and timeout != 0 and self._poller.poll(timeout): 45 | data = self._readall() 46 | return parse_events(data) 47 | 48 | def _readall(self): 49 | bytes_avail = c_int() 50 | ioctl(self, FIONREAD, bytes_avail) 51 | if not bytes_avail.value: 52 | return b'' 53 | return read(self.fileno(), bytes_avail.value) 54 | 55 | 56 | def parse_events(data): 57 | pos = 0 58 | events = [] 59 | while pos < len(data): 60 | wd, mask, cookie, name_size = unpack_from(_EVENT_FMT, data, pos) 61 | pos += _EVENT_SIZE + name_size 62 | name = data[pos - name_size:pos].split(b'\x00', 1)[0] 63 | events.append(Event(wd, mask, cookie, fsdecode(name))) 64 | return events 65 | -------------------------------------------------------------------------------- /tests/touch.glsl: -------------------------------------------------------------------------------- 1 | // python glsl.py tests/touch.glsl --trackpad iTouch 2 | 3 | // Created by inigo quilez - iq/2013 4 | // https://www.youtube.com/c/InigoQuilez 5 | // https://iquilezles.org/ 6 | 7 | // Shows how to use the mouse input (only left button supported): 8 | // 9 | // mouse.xy = mouse position during last button down 10 | // abs(mouse.zw) = mouse position during last button click 11 | // sign(mouze.z) = button is down 12 | // sign(mouze.w) = button is clicked 13 | 14 | // See also: 15 | // 16 | // Input - Keyboard : https://www.shadertoy.com/view/lsXGzf 17 | // Input - Microphone : https://www.shadertoy.com/view/llSGDh 18 | // Input - Mouse : https://www.shadertoy.com/view/Mss3zH 19 | // Input - Sound : https://www.shadertoy.com/view/Xds3Rr 20 | // Input - SoundCloud : https://www.shadertoy.com/view/MsdGzn 21 | // Input - Time : https://www.shadertoy.com/view/lsXGz8 22 | // Input - TimeDelta : https://www.shadertoy.com/view/lsKGWV 23 | // Inout - 3D Texture : https://www.shadertoy.com/view/4llcR4 24 | 25 | uniform vec4[10] iTouch; 26 | 27 | float distanceToSegment( vec2 a, vec2 b, vec2 p ) 28 | { 29 | vec2 pa = p - a, ba = b - a; 30 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); 31 | return length( pa - ba*h ); 32 | } 33 | 34 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 35 | { 36 | vec2 p = fragCoord / iResolution.x; 37 | vec2 cen = 0.5*iResolution.xy/iResolution.x; 38 | 39 | vec3 col = vec3(0.0); 40 | 41 | for (int i = 0; i < 10; i++) { 42 | vec4 m = iTouch[i] / iResolution.x; 43 | 44 | if (m.z > 0.0) // button is down 45 | { 46 | float d = distanceToSegment(m.xy, abs(m.zw), p); 47 | col = mix(col, vec3(1.0, 1.0, 0.0), 1.0 - smoothstep(.004, 0.008, d)); 48 | } 49 | if (m.w > 0.0) // button click 50 | { 51 | col = mix(col, vec3(1.0, 1.0, 1.0), 1.0 - smoothstep(0.1, 0.105, length(p - cen))); 52 | } 53 | 54 | if (m.z > 0.0) { 55 | col = mix(col, vec3(1.0, 0.0, 0.0), 1.0 - smoothstep(0.03, 0.035, length(p - m.xy))); 56 | col = mix(col, vec3(0.0, 0.0, 1.0), 1.0 - smoothstep(0.03, 0.035, length(p - abs(m.zw)))); 57 | } 58 | } 59 | 60 | fragColor = vec4( col, 1.0 ); 61 | } 62 | -------------------------------------------------------------------------------- /examples/stripey_torus_interior.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/MsX3Wj 2 | // Created by https://www.shadertoy.com/user/fb39ca4 3 | 4 | //Thank you iquilez for some of the primitive distance functions! 5 | 6 | 7 | const float PI = 3.14159265358979323846264; 8 | 9 | 10 | const int MAX_PRIMARY_RAY_STEPS = 64; //decrease this number if it runs slow on your computer 11 | 12 | vec2 rotate2d(vec2 v, float a) { 13 | return vec2(v.x * cos(a) - v.y * sin(a), v.y * cos(a) + v.x * sin(a)); 14 | } 15 | 16 | float sdTorus( vec3 p, vec2 t ) { 17 | vec2 q = vec2(length(p.xz)-t.x,p.y); 18 | return length(q)-t.y; 19 | } 20 | 21 | float distanceField(vec3 p) { 22 | return -sdTorus(p, vec2(4.0, 3.0)); 23 | } 24 | 25 | vec3 castRay(vec3 pos, vec3 dir, float treshold) { 26 | for (int i = 0; i < MAX_PRIMARY_RAY_STEPS; i++) { 27 | float dist = distanceField(pos); 28 | //if (abs(dist) < treshold) break; 29 | pos += dist * dir; 30 | } 31 | return pos; 32 | } 33 | 34 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 35 | { 36 | vec4 mousePos = (iMouse / iResolution.xyxy) * 2.0 - 1.0; 37 | vec2 screenPos = (fragCoord.xy / iResolution.xy) * 2.0 - 1.0; 38 | vec3 cameraPos = vec3(0.0, 0.0, -3.8); 39 | 40 | vec3 cameraDir = vec3(0.0, 0.0, 0.5); 41 | vec3 planeU = vec3(1.0, 0.0, 0.0) * 0.8; 42 | vec3 planeV = vec3(0.0, iResolution.y / iResolution.x * 1.0, 0.0); 43 | vec3 rayDir = normalize(cameraDir + screenPos.x * planeU + screenPos.y * planeV); 44 | 45 | //cameraPos.yz = rotate2d(cameraPos.yz, mousePos.y); 46 | //rayDir.yz = rotate2d(rayDir.yz, mousePos.y); 47 | 48 | //cameraPos.xz = rotate2d(cameraPos.xz, mousePos.x); 49 | //rayDir.xz = rotate2d(rayDir.xz, mousePos.x); 50 | 51 | vec3 rayPos = castRay(cameraPos, rayDir, 0.01); 52 | 53 | float majorAngle = atan(rayPos.z, rayPos.x); 54 | float minorAngle = atan(rayPos.y, length(rayPos.xz) - 4.0); 55 | 56 | float edge = mod(8.0 * (minorAngle + majorAngle + iTime) / PI, 1.0); 57 | float color = edge < 0.7 ? smoothstep(edge, edge+0.03, 0.5) : 1.0-smoothstep(edge, edge+0.03, 0.96); 58 | //float color = step(mod(8.0 * (minorAngle + majorAngle + iTime) / PI, 1.0), 0.5); 59 | //color -= 0.20 * step(mod(1.0 * (minorAngle + 1.0 * majorAngle + PI / 2.0) / PI, 1.0), 0.2); 60 | 61 | fragColor = vec4(color); 62 | } 63 | -------------------------------------------------------------------------------- /examples/flower_of_life_rgb.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/4dGGzc 2 | // Created by https://www.shadertoy.com/user/xoihazard 3 | 4 | // (c) 2016 xoihazard 5 | 6 | #define TWO_PI 6.2831853072 7 | #define PI 3.14159265359 8 | 9 | const float timeScale = 0.2; 10 | const float displace = 0.01; 11 | const float gridSize = 20.0; 12 | const float wave = 5.0; 13 | const float brightness = 1.5; 14 | 15 | vec2 rotate(in vec2 v, in float angle) { 16 | float c = cos(angle); 17 | float s = sin(angle); 18 | return v * mat2(c, -s, s, c); 19 | } 20 | 21 | vec3 coordToHex(in vec2 coord, in float scale, in float angle) { 22 | vec2 c = rotate(coord, angle); 23 | float q = (1.0 / 3.0 * sqrt(3.0) * c.x - 1.0 / 3.0 * c.y) * scale; 24 | float r = 2.0 / 3.0 * c.y * scale; 25 | return vec3(q, r, -q - r); 26 | } 27 | 28 | vec3 hexToCell(in vec3 hex, in float m) { 29 | return fract(hex / m) * 2.0 - 1.0; 30 | } 31 | 32 | float absMax(in vec3 v) { 33 | return max(max(abs(v.x), abs(v.y)), abs(v.z)); 34 | } 35 | 36 | float nsin(in float value) { 37 | return sin(value * TWO_PI) * 0.5 + 0.5; 38 | } 39 | 40 | float hexToFloat(in vec3 hex, in float amt) { 41 | return mix(absMax(hex), 1.0 - length(hex) / sqrt(3.0), amt); 42 | } 43 | 44 | float calc(in vec2 tx, in float time) { 45 | float angle = PI * nsin(time * 0.1) + PI / 6.0; 46 | float len = 1.0 - length(tx) * nsin(time); 47 | float value = 0.0; 48 | vec3 hex = coordToHex(tx, gridSize * nsin(time * 0.1), angle); 49 | 50 | for (int i = 0; i < 3; i++) { 51 | float offset = float(i) / 3.0; 52 | vec3 cell = hexToCell(hex, 1.0 + float(i)); 53 | value += nsin(hexToFloat(cell,nsin(len + time + offset)) * 54 | wave * nsin(time * 0.5 + offset) + len + time); 55 | } 56 | 57 | return value / 3.0; 58 | } 59 | 60 | 61 | void mainImage(out vec4 fragColor, in vec2 fragCoord) { 62 | vec2 tx = (fragCoord / iResolution.xy) - 0.5; 63 | tx.x *= iResolution.x / iResolution.y; 64 | float time = iTime * timeScale; 65 | vec3 rgb = vec3(0.0, 0.0, 0.0); 66 | for (int i = 0; i < 3; i++) { 67 | float time2 = time + float(i) * displace; 68 | rgb[i] += pow(calc(tx, time2), 2.0); 69 | } 70 | fragColor = vec4(rgb * brightness, 1.0); 71 | } 72 | -------------------------------------------------------------------------------- /examples/white_drops.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/fdXXWH 2 | // Created by https://www.shadertoy.com/user/Xor 3 | 4 | //Anti-Aliasing (SSAA). Use 1.0 on slower computers 5 | #define AA 2. 6 | 7 | //Background gradient 8 | vec3 background(vec3 d) 9 | { 10 | float light = dot(d,sqrt(vec3(.3,.5,.2))); 11 | 12 | return vec3(max(light*.5+.5,.0)); 13 | } 14 | //Smooth minimum (based off IQ's work) 15 | float smin(float d1, float d2) 16 | { 17 | const float e = -6.; 18 | return log(exp(d1*e)+exp(d2*e))/e; 19 | } 20 | //Ripple and drop distance function 21 | float dist(vec3 p) 22 | { 23 | float l = pow(dot(p.xz,p.xz),.8); 24 | float ripple = p.y+.8+.4*sin(l*3.-iTime+.5)/(1.+l); 25 | 26 | float h1 = -sin(iTime); 27 | float h2 = cos(iTime+.1); 28 | float drop = length(p+vec3(0,1.2,0)*h1)-.4; 29 | drop = smin(drop,length(p+vec3(.1,.8,0)*h2)-.2); 30 | return smin(ripple,drop); 31 | } 32 | //Typical SDF normal function 33 | vec3 normal(vec3 p) 34 | { 35 | vec2 e = vec2(1,-1)*.01; 36 | 37 | return normalize(dist(p-e.yxx)*e.yxx+dist(p-e.xyx)*e.xyx+ 38 | dist(p-e.xxy)*e.xxy+dist(p-e.y)*e.y); 39 | } 40 | //Basic raymarcher 41 | vec4 march(vec3 p, vec3 d) 42 | { 43 | vec4 m = vec4(p,0); 44 | for(int i = 0; i<99; i++) 45 | { 46 | float s = dist(m.xyz); 47 | m += vec4(d,1)*s; 48 | 49 | if (s<.01 || m.w>20.) break; 50 | } 51 | return m; 52 | } 53 | 54 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 55 | { 56 | vec2 res = iResolution.xy; 57 | vec3 col = vec3(0); 58 | 59 | vec3 pos = vec3(.05*cos(iTime),.1*sin(iTime),-4); 60 | 61 | //Sample 62 | for(float x = 0.;x orange gradient is where the wavefunction is positive, 11 | the purple --> green gradient is where the wavefunction is negative. 12 | The blue and purple colors represent low probability of the 13 | wavefunction collapsing to that specific position apon observation. 14 | The orange and green colors represent a high probability (of what 15 | I just mentioned, no need to repeat). 16 | */ 17 | 18 | float pi = 3.141592653589793; 19 | float sq2 = sqrt(2.); 20 | float transitionSpeed = 60.; //Higher is faster 21 | 22 | float sw(float x, float s){ 23 | return(atan(s*sin(pi*x)))/(.5*pi); 24 | } 25 | 26 | void mainImage(out vec4 fragColor, in vec2 fragCoord){ 27 | vec3 col = vec3(0.); 28 | float contour = 0.1; 29 | int AA = 4; //Default value is 4x4 anti-aliasing 30 | float AAA = float(AA*AA); 31 | for(int i=0; i= 0.0 && u <= 1.0) && (x0 < x1)); 48 | #endif 49 | 50 | return vec4(col, clip); 51 | } 52 | 53 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 54 | { 55 | aaSize = 2.0 / iResolution.y; //Scale anti aliasing with resolution 56 | vec2 res = iResolution.xy / iResolution.y; 57 | vec2 uv = fragCoord.xy / iResolution.y; 58 | uv -= res / 2.0; 59 | uv *= 2.0; 60 | 61 | //Polar coordinates 62 | vec2 uvr = vec2(length(uv), atan(uv.y, uv.x) + pi); 63 | uvr.x -= OUT_RADIUS; 64 | 65 | vec3 col = vec3(0.05); 66 | 67 | //Twisting angle 68 | float angle = uvr.y + 2.0*iTime + sin(uvr.y) * sin(iTime) * pi; 69 | 70 | for(int i = 0;i < NUM_FACES;i++) 71 | { 72 | float x0 = IN_RADIUS * sin(angle + tau * (float(i) / float(NUM_FACES))); 73 | float x1 = IN_RADIUS * sin(angle + tau * (float(i + 1) / float(NUM_FACES))); 74 | 75 | vec4 face = slice(x0, x1, uvr); 76 | 77 | col = mix(col, face.rgb, face.a); 78 | } 79 | 80 | //col = (abs(uv.x) > 1.0) ? vec3(1) : col; 81 | 82 | fragColor = vec4(col, 1.0); 83 | } 84 | -------------------------------------------------------------------------------- /examples/bokeh_parallax.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/4s2yW1 2 | // Created by https://www.shadertoy.com/user/knarkowicz 3 | 4 | const float MATH_PI = float( 3.14159265359 ); 5 | 6 | void Rotate( inout vec2 p, float a ) 7 | { 8 | p = cos( a ) * p + sin( a ) * vec2( p.y, -p.x ); 9 | } 10 | 11 | float Circle( vec2 p, float r ) 12 | { 13 | return ( length( p / r ) - 1.0 ) * r; 14 | } 15 | 16 | float Rand( vec2 c ) 17 | { 18 | return fract( sin( dot( c.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 ); 19 | } 20 | 21 | float saturate( float x ) 22 | { 23 | return clamp( x, 0.0, 1.0 ); 24 | } 25 | 26 | void BokehLayer( inout vec3 color, vec2 p, vec3 c ) 27 | { 28 | float wrap = 450.0; 29 | if ( mod( floor( p.y / wrap + 0.5 ), 2.0 ) == 0.0 ) 30 | { 31 | p.x += wrap * 0.5; 32 | } 33 | 34 | vec2 p2 = mod( p + 0.5 * wrap, wrap ) - 0.5 * wrap; 35 | vec2 cell = floor( p / wrap + 0.5 ); 36 | float cellR = Rand( cell ); 37 | 38 | c *= fract( cellR * 3.33 + 3.33 ); 39 | float radius = mix( 30.0, 70.0, fract( cellR * 7.77 + 7.77 ) ); 40 | p2.x *= mix( 0.9, 1.1, fract( cellR * 11.13 + 11.13 ) ); 41 | p2.y *= mix( 0.9, 1.1, fract( cellR * 17.17 + 17.17 ) ); 42 | 43 | float sdf = Circle( p2, radius ); 44 | float circle = 1.0 - smoothstep( 0.0, 1.0, sdf * 0.04 ); 45 | float glow = exp( -sdf * 0.025 ) * 0.3 * ( 1.0 - circle ); 46 | color += c * ( circle + glow ); 47 | } 48 | 49 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 50 | { 51 | vec2 uv = fragCoord.xy / iResolution.xy; 52 | vec2 p = ( 2.0 * fragCoord - iResolution.xy ) / iResolution.x * 1000.0; 53 | 54 | // background 55 | vec3 color = mix( vec3( 0.3, 0.1, 0.3 ), vec3( 0.1, 0.4, 0.5 ), dot( uv, vec2( 0.2, 0.7 ) ) ); 56 | 57 | float time = iTime - 15.0; 58 | 59 | Rotate( p, 0.2 + time * 0.03 ); 60 | BokehLayer( color, p + vec2( -50.0 * time + 0.0, 0.0 ), 3.0 * vec3( 0.4, 0.1, 0.2 ) ); 61 | Rotate( p, 0.3 - time * 0.05 ); 62 | BokehLayer( color, p + vec2( -70.0 * time + 33.0, -33.0 ), 3.5 * vec3( 0.6, 0.4, 0.2 ) ); 63 | Rotate( p, 0.5 + time * 0.07 ); 64 | BokehLayer( color, p + vec2( -60.0 * time + 55.0, 55.0 ), 3.0 * vec3( 0.4, 0.3, 0.2 ) ); 65 | Rotate( p, 0.9 - time * 0.03 ); 66 | BokehLayer( color, p + vec2( -25.0 * time + 77.0, 77.0 ), 3.0 * vec3( 0.4, 0.2, 0.1 ) ); 67 | Rotate( p, 0.0 + time * 0.05 ); 68 | BokehLayer( color, p + vec2( -15.0 * time + 99.0, 99.0 ), 3.0 * vec3( 0.2, 0.0, 0.4 ) ); 69 | 70 | fragColor = vec4( color, 1.0 ); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /examples/menger_sponge_tunnel.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/fd23zz 2 | // Created by https://www.shadertoy.com/user/kithy 3 | 4 | #define MAX_STEPS 64 5 | #define EPS 0.001 6 | #define ITR 5 7 | 8 | 9 | mat2 rotate(float r){ 10 | float c=cos(r); 11 | float s=sin(r); 12 | return mat2(c,s,-s,c); 13 | } 14 | 15 | float maxcomp(vec2 p){ 16 | return max(p.x,p.y); 17 | } 18 | 19 | 20 | float sdCross(vec3 p){ 21 | p=abs(p); 22 | vec3 d=vec3(max(p.x,p.y), 23 | max(p.y,p.z), 24 | max(p.z,p.x)); 25 | return min(d.x,min(d.y,d.z))-(1.0/3.0); 26 | } 27 | 28 | 29 | float sdCrossRep(vec3 p){ 30 | vec3 q=mod(p+1.0,2.0)-1.0; 31 | return sdCross(q); 32 | } 33 | 34 | 35 | float sdCrossRepScale(vec3 p,float s){ 36 | return sdCrossRep(p*s)/s; 37 | } 38 | 39 | 40 | float scene(vec3 p){ 41 | 42 | float scale=1.0; 43 | float dist=0.0; 44 | for(int i=0;i 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the 12 | * next paragraph) shall be included in all copies or substantial portions 13 | * of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef _DRM_COMMON_H 25 | #define _DRM_COMMON_H 26 | 27 | #include 28 | #include 29 | 30 | struct plane { 31 | drmModePlane *plane; 32 | drmModeObjectProperties *props; 33 | drmModePropertyRes **props_info; 34 | uint32_t num_formats; 35 | uint32_t *formats; 36 | uint32_t num_modifiers; 37 | uint64_t *modifiers; 38 | }; 39 | 40 | struct crtc { 41 | drmModeCrtc *crtc; 42 | drmModeObjectProperties *props; 43 | drmModePropertyRes **props_info; 44 | }; 45 | 46 | struct connector { 47 | drmModeConnector *connector; 48 | drmModeObjectProperties *props; 49 | drmModePropertyRes **props_info; 50 | }; 51 | 52 | struct drm { 53 | int fd; 54 | 55 | struct plane *plane; 56 | struct crtc *crtc; 57 | struct connector *connector; 58 | int crtc_index; 59 | 60 | drmModeModeInfo *mode; 61 | uint32_t crtc_id; 62 | uint32_t connector_id; 63 | 64 | bool async_page_flip; 65 | 66 | /* number of frames to run for: */ 67 | unsigned int frames; 68 | 69 | int (*run)(const struct gbm *gbm, const struct egl *egl); 70 | }; 71 | 72 | struct drm_fb { 73 | struct gbm_bo *bo; 74 | uint32_t fb_id; 75 | }; 76 | 77 | struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo); 78 | 79 | int find_drm_device(); 80 | 81 | int find_plane_prop(const struct drm *drm, const char *name, unsigned int *prop_idx); 82 | 83 | const uint64_t *get_drm_format_modifiers(const struct drm *drm, unsigned int *count); 84 | 85 | int init_drm(struct drm *drm, int fd, const struct options *options); 86 | 87 | const struct drm *init_drm_legacy(int fd, const struct options *options); 88 | 89 | const struct drm *init_drm_atomic(int fd, const struct options *options); 90 | 91 | #endif /* _DRM_COMMON_H */ 92 | -------------------------------------------------------------------------------- /examples/planetary_gears.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/MsGczV 2 | // Created by https://www.shadertoy.com/user/AntoineC 3 | 4 | // Inspired by: 5 | // http://cmdrkitten.tumblr.com/post/172173936860 6 | 7 | 8 | #define Pi 3.14159265359 9 | 10 | struct Gear 11 | { 12 | float t; // Time 13 | float gearR; // Gear radius 14 | float teethH; // Teeth height 15 | float teethR; // Teeth "roundness" 16 | float teethCount; // Teeth count 17 | float diskR; // Inner or outer border radius 18 | vec3 color; // Color 19 | }; 20 | 21 | 22 | 23 | float GearFunction(vec2 uv, Gear g) 24 | { 25 | float r = length(uv); 26 | float a = atan(uv.y, uv.x); 27 | 28 | // Gear polar function: 29 | // A sine squashed by a logistic function gives a convincing 30 | // gear shape! 31 | float p = g.gearR-0.5*g.teethH + 32 | g.teethH/(1.0+exp(g.teethR*sin(g.t + g.teethCount*a))); 33 | 34 | float gear = r - p; 35 | float disk = r - g.diskR; 36 | 37 | return g.gearR > g.diskR ? max(-disk, gear) : max(disk, -gear); 38 | } 39 | 40 | 41 | float GearDe(vec2 uv, Gear g) 42 | { 43 | // IQ's f/|Grad(f)| distance estimator: 44 | float f = GearFunction(uv, g); 45 | vec2 eps = vec2(0.0001, 0); 46 | vec2 grad = vec2( 47 | GearFunction(uv + eps.xy, g) - GearFunction(uv - eps.xy, g), 48 | GearFunction(uv + eps.yx, g) - GearFunction(uv - eps.yx, g)) / (2.0*eps.x); 49 | 50 | return (f)/length(grad); 51 | } 52 | 53 | 54 | 55 | float GearShadow(vec2 uv, Gear g) 56 | { 57 | float r = length(uv+vec2(0.1)); 58 | float de = r - g.diskR + 0.0*(g.diskR - g.gearR); 59 | float eps = 0.4*g.diskR; 60 | return smoothstep(eps, 0., abs(de)); 61 | } 62 | 63 | 64 | void DrawGear(inout vec3 color, vec2 uv, Gear g, float eps) 65 | { 66 | float d = smoothstep(eps, -eps, GearDe(uv, g)); 67 | float s = 1.0 - 0.7*GearShadow(uv, g); 68 | color = mix(s*color, g.color, d); 69 | } 70 | 71 | 72 | 73 | 74 | 75 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 76 | { 77 | float t = 0.5*iTime; 78 | vec2 uv = 2.0*(fragCoord - 0.5*iResolution.xy)/iResolution.y; 79 | float eps = 2.0/iResolution.y; 80 | 81 | // Scene parameters; 82 | vec3 base = vec3(0.95, 0.7, 0.2); 83 | const float count = 8.0; 84 | 85 | Gear outer = Gear(0.0, 0.8, 0.08, 4.0, 32.0, 0.9, base); 86 | Gear inner = Gear(0.0, 0.4, 0.08, 4.0, 16.0, 0.3, base); 87 | 88 | 89 | // Draw inner gears back to front: 90 | vec3 color = vec3(0.0); 91 | for(float i=0.0; i2.) break; 67 | totdist+=d; 68 | st+=max(0.,.04-d); 69 | } 70 | vec2 li=uv*rot; 71 | float backg=.45*pow(1.5-min(1.,length(li+vec2(0.,-.6))),1.5); 72 | if (d.7) col=col*.7+(.3+ra+ral*.5)*mod(uv.y+iTime*2.,.25); 82 | col = mix(col, .5+ra+ral*.5, max(0.,3.-iTime)/3.); 83 | return col+ra*.03+(ral*.1+ra*.1)*rab; 84 | } 85 | 86 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 87 | { 88 | float t=iTime*.2; 89 | vec2 uv = fragCoord.xy / iResolution.xy*2.-1.; 90 | uv.y*=iResolution.y/iResolution.x; 91 | vec3 from=vec3(0.,0.1,-1.2); 92 | vec3 dir=normalize(vec3(uv,1.)); 93 | rot=mat2(cos(t),sin(t),-sin(t),cos(t)); 94 | dir.xy=dir.xy*rot; 95 | float col=raymarch(from,dir,fragCoord); 96 | col=pow(col,1.25)*clamp(60.-iTime,0.,1.); 97 | fragColor = vec4(col); 98 | } 99 | 100 | 101 | -------------------------------------------------------------------------------- /examples/universe_within_314.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/sdSGDW 2 | // Created by https://www.shadertoy.com/user/Domain314 3 | 4 | #define S(a, b, t) smoothstep(a, b, t) 5 | 6 | float DistLine(vec2 p, vec2 a, vec2 b) { 7 | vec2 pa = p-a; 8 | vec2 ba = b-a; 9 | float t = clamp(dot(pa, ba)/dot(ba, ba), 0., 1.); 10 | return length(pa - ba*t); 11 | } 12 | 13 | float N21 (vec2 p) { 14 | p = fract(p*vec2(233.34, 851.73)); 15 | p += dot(p, p+23.45); 16 | return fract(p.x*p.y); 17 | } 18 | 19 | vec2 N22(vec2 p) { 20 | float n = N21(p); 21 | return vec2(n, N21(p+n)); 22 | } 23 | 24 | // Get random position 25 | vec2 GetPos(vec2 id, vec2 offs) { 26 | vec2 n = N22(id+offs)*iTime; 27 | //float x = sin(iTime * n.x); 28 | //float y = cos(iTime * n.y); 29 | return offs+sin(n)*.4; 30 | } 31 | 32 | float Line(vec2 p, vec2 a, vec2 b) { 33 | float d = DistLine(p, a, b); 34 | float m = S(.03, .01, d); 35 | float d2 = length(a-b); 36 | m *= S(1.2, .8, d2)*.5+S(.05, .03, abs(d2-.75)); 37 | return m; 38 | } 39 | 40 | float Layer(vec2 uv) { 41 | float m = 0.; 42 | vec2 gv = fract(uv)-.5; 43 | vec2 id = floor(uv); 44 | 45 | //m = S(.1, .05, d); 46 | 47 | vec2 p[9]; 48 | 49 | int i = 0; 50 | for (float y = -1.; y <= 1.; y++) { 51 | for (float x = -1.; x <= 1.; x++) { 52 | p[i++] = GetPos(id, vec2(x,y)); 53 | } 54 | } 55 | float t = iTime*10.; 56 | 57 | for (int i = 0; i < 9; i++) { 58 | m += Line(gv, p[4], p[i]); 59 | 60 | vec2 j = (p[i]-gv)*20.; 61 | float sparkle = 1./dot(j,j); 62 | 63 | m += sparkle*(sin(t+fract(p[i].x)*10.)*.5 +.5); 64 | } 65 | m += Line(gv, p[1], p[3]); 66 | m += Line(gv, p[1], p[5]); 67 | m += Line(gv, p[7], p[3]); 68 | m += Line(gv, p[7], p[5]); 69 | 70 | return m; 71 | } 72 | 73 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 74 | { 75 | vec2 uv = (fragCoord-.5*iResolution.xy)/iResolution.y; 76 | vec2 mouse = (iMouse.xy/iResolution.xy) -.5; 77 | 78 | float gradient = uv.y; 79 | 80 | float m = 0.; 81 | float t = iTime * .1; 82 | 83 | float s = sin(t); 84 | float c = cos(t); 85 | 86 | mat2 rot = mat2(c, -s, s, c); 87 | uv *= rot; 88 | mouse *= rot; 89 | 90 | // fract snaps Layer back, after he moved away => continuous Layer behind Layer 91 | for (float i=0.; i<1.; i+= 1./4.) { 92 | float z = fract(i+t); 93 | float size = mix(10., .5, z); 94 | float fade = S(0., .5, z) * S(1., .8, z); 95 | m += Layer(uv * size + i*20. - mouse)*fade; 96 | } 97 | 98 | // different colours, bc of 3 different sin-speeds 99 | vec3 base = sin(t*5.*vec3(.345, .456, .657))*.4 + .6; 100 | vec3 col = m*base; 101 | 102 | //float fft = texelFetch(iChannel0, ivec2(.7,0), 0).x; 103 | //gradient *= fft; 104 | 105 | col -= gradient*base*0.4; 106 | 107 | 108 | // Grid 109 | //if (gv.x > .48 || gv.y > .48)col = vec3(1,0,0); 110 | 111 | fragColor = vec4(col,1.0); 112 | } -------------------------------------------------------------------------------- /examples/complex_field_lines.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/7ds3W2 2 | // Created by https://www.shadertoy.com/user/jllusty 3 | 4 | float pi = 4.0 * atan(1.0); 5 | 6 | vec2 mult(in vec2 a, in vec2 b) { 7 | return vec2(a.x * b.x - a.y * b.y, a.y * b.x + a.x * b.y); 8 | } 9 | 10 | 11 | vec2 div(in vec2 a, in vec2 b) { 12 | return mult(a,vec2(b.x,-b.y))/length(b); 13 | } 14 | 15 | vec2 clog(in vec2 z) { 16 | return vec2(log(length(z)), atan(z.y, z.x)); 17 | } 18 | 19 | vec2 func(in vec2 z) { 20 | //return mult(z - vec2(2.0f, 0.0), div(vec2(1.0,0.0), z + vec2(sin(iTime), 0.0))); 21 | return clog(z-vec2(-4.,1.)) + clog(z-vec2(0.,2.)) - mult(vec2(2.,0.), clog(z-vec2(2.,-2.))); 22 | } 23 | 24 | vec3 checkerboard(in vec2 uv) { 25 | int parity = int(floor(uv.x)) + int(floor(uv.y)); 26 | if(mod(float(parity),2.0) == 0.0) { 27 | return vec3(0.0); 28 | } 29 | else { 30 | return vec3(1.0); 31 | } 32 | } 33 | 34 | //float wrap(float x, float a) { 35 | // return x - a * floor(x / a); 36 | //} 37 | 38 | 39 | // Smooth wrap. 40 | float wrap(float x, float a){ 41 | x -= a*floor(x/a); 42 | // Smoothing factor. 43 | const float sf = 16.; 44 | // Rough smoothing. 45 | return min(x, (1. - x)*x*16.); 46 | } 47 | 48 | float angdist(in float theta1, in float theta2) { 49 | return wrap(theta2 - theta1 + pi, 2.0*pi) - pi; 50 | } 51 | 52 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 53 | { 54 | // Normalized pixel coordinates (from 0 to 1) 55 | vec2 uv = 4.0*(2.0*fragCoord/iResolution.xy - 1.); 56 | float aspect = iResolution.y/iResolution.x; 57 | uv.x = uv.x/aspect; 58 | 59 | // Save Pixel Position 60 | vec2 pos = uv; 61 | 62 | // Apply Function 63 | uv = func(uv); 64 | 65 | // Get distance to closest arg(z)-isocurve 66 | float n = 22.; 67 | float arg = uv.y; //atan(uv.y, uv.x); 68 | float gEps = 0.001; 69 | float stretch = length(func(pos+vec2(gEps,gEps))-func(pos))/(sqrt(2.)*gEps); 70 | float eps = 0.05; 71 | float d = abs(fract(arg*n/(2.*pi)+.5)-.5)/stretch; 72 | float r = length(uv); 73 | //if (r >= 1.) d = d*r; 74 | float c = 1. - smoothstep(eps, 2.*eps, d); 75 | 76 | // 77 | float n1 = 22.; 78 | float arg1 = uv.x-iTime/4.; //atan(uv.y, uv.x); 79 | float gEps1 = 0.001; 80 | float stretch1 = length(func(pos+vec2(gEps1,gEps1))-func(pos))/(sqrt(2.)*gEps1); 81 | float eps1 = 0.05; 82 | float d1 = abs(fract(arg1*n1/(2.*pi)+.5)-.5)/stretch1; 83 | float r1 = length(uv); 84 | //if (r >= 1.) d = d*r; 85 | float c1 = 1. - smoothstep(eps1, 2.*eps1, d1); 86 | 87 | // Stack onto Base Image (Contours) 88 | // background color 89 | float bc = 1.0-wrap(length(uv.x-iTime),1.); 90 | // line color 91 | c = max(c,c1); 92 | vec3 lcol = vec3(1.0,0.0,0.0); 93 | //vec3 col = (1.0 - c) * bcol + c * vec3(abs(sin(uv.x-iTime)), 0.0, 0.0); 94 | vec3 col = vec3(0.); 95 | if (bc > c) { 96 | col = c*vec3(abs(sin(uv.x)),0.,0.); 97 | } else { 98 | col = bc*vec3(1.); 99 | } 100 | 101 | // Output to screen 102 | fragColor = vec4(col,1.0); 103 | } 104 | -------------------------------------------------------------------------------- /tests/input.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import libevdev 3 | 4 | parser = argparse.ArgumentParser(description='Test input device') 5 | parser.add_argument('path', metavar='PATH', type=str, help='the path to the input device') 6 | args = parser.parse_args() 7 | 8 | 9 | def print_event(ev): 10 | print("Event: time {}.{:06d}, ".format(ev.sec, ev.usec), end='') 11 | if ev.matches(libevdev.EV_SYN): 12 | if ev.matches(libevdev.EV_SYN.SYN_MT_REPORT): 13 | print("++++++++++++++ {} ++++++++++++".format(ev.code.name)) 14 | elif ev.matches(libevdev.EV_SYN.SYN_DROPPED): 15 | print(">>>>>>>>>>>>>> {} >>>>>>>>>>>>".format(ev.code.name)) 16 | else: 17 | print("-------------- {} ------------".format(ev.code.name)) 18 | else: 19 | print("type {:02x} {} code {:03x} {:20s} value {:4d}". 20 | format(ev.type.value, ev.type.name, ev.code.value, ev.code.name, ev.value)) 21 | 22 | 23 | def print_capabilities(device): 24 | v = device.driver_version 25 | print("Input driver version is {}.{}.{}".format(v >> 16, (v >> 8) & 0xff, v & 0xff)) 26 | print("Input device ID: bus {:#x} vendor {:#x} product {:#x} version {:#x}". 27 | format(device.id["bustype"], device.id["vendor"], device.id["product"], device.id["version"])) 28 | print("Input device name: {}".format(device.name)) 29 | print("Supported events:") 30 | 31 | for t, cs in device.evbits.items(): 32 | print(" Event type {} ({})".format(t.value, t.name)) 33 | 34 | for c in cs: 35 | if t in [libevdev.EV_LED, libevdev.EV_SND, libevdev.EV_SW]: 36 | v = device.value[c] 37 | print(" Event code {} ({}) state {}".format(c.value, c.name, v)) 38 | else: 39 | print(" Event code {} ({})".format(c.value, c.name)) 40 | 41 | if t == libevdev.EV_ABS: 42 | a = device.absinfo[c] 43 | print(" {:10s} {:6d}".format('Value', a.value)) 44 | print(" {:10s} {:6d}".format('Minimum', a.minimum)) 45 | print(" {:10s} {:6d}".format('Maximum', a.maximum)) 46 | print(" {:10s} {:6d}".format('Fuzz', a.fuzz)) 47 | print(" {:10s} {:6d}".format('Flat', a.flat)) 48 | print(" {:10s} {:6d}".format('Resolution', a.resolution)) 49 | 50 | print("Properties:") 51 | for p in device.properties: 52 | print(" Property type {} ({})".format(p.value, p.name)) 53 | 54 | 55 | try: 56 | with open(args.path, "rb") as fd: 57 | dev = libevdev.Device(fd) 58 | print_capabilities(dev) 59 | print("################################\n" 60 | "# Waiting for events #\n" 61 | "################################") 62 | 63 | while True: 64 | try: 65 | for e in dev.events(): 66 | print_event(e) 67 | except libevdev.EventsDroppedException: 68 | for e in dev.sync(): 69 | print_event(e) 70 | 71 | except KeyboardInterrupt: 72 | pass 73 | except IOError as e: 74 | import errno 75 | if e.errno == errno.EACCES: 76 | print("Insufficient permissions to access {}".format(args.path)) 77 | elif e.errno == errno.ENOENT: 78 | print("Device {} does not exist".format(args.path)) 79 | else: 80 | raise e 81 | -------------------------------------------------------------------------------- /tests/keyboard.glsl: -------------------------------------------------------------------------------- 1 | // python glsl.py tests/keyboard.glsl -k iChannel1 -t iChannel0 presets/tex_font_01.png -m iChannel0.transpose FLIP_TOP_BOTTOM 2 | 3 | // Copied from https://www.shadertoy.com/view/4dGyDm 4 | // Created by https://www.shadertoy.com/user/mattz 5 | 6 | // just debugging keyboard texture and scan codes! 7 | 8 | uniform sampler2D iChannel0; 9 | uniform sampler2D iChannel1; 10 | 11 | uniform int iAux0; 12 | uniform vec4 iAux1; 13 | 14 | const float GLYPHS_PER_UV = 16.; 15 | const float FONT_TEX_BIAS = 127./255.; 16 | 17 | 18 | vec2 font_from_screen(vec2 tpos, float font_size, vec2 char_pos) { 19 | return (tpos/font_size + char_pos + 0.5)/GLYPHS_PER_UV; 20 | } 21 | 22 | vec3 sample_grad_dist(vec2 uv, float font_size) { 23 | 24 | vec3 grad_dist = (textureLod(iChannel0, uv, 0.).yzw - FONT_TEX_BIAS) * font_size; 25 | 26 | grad_dist.y = -grad_dist.y; 27 | grad_dist.xy = normalize(grad_dist.xy + 1e-5); 28 | 29 | return grad_dist; 30 | 31 | } 32 | 33 | const vec2 TABLE_RES = vec2(16, 16); 34 | const vec2 CELL_DIMS = vec2(1.5, 1); 35 | const vec2 TABLE_DIMS = TABLE_RES * CELL_DIMS; 36 | 37 | float MARGIN = 2.0; 38 | 39 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 40 | 41 | vec3 color = vec3(1); 42 | 43 | float scl = 1.0 / floor( iResolution.y / (TABLE_RES.y + MARGIN) ); 44 | 45 | vec2 p = (fragCoord - 0.5 - 0.5*iResolution.xy)*scl + 0.5*TABLE_DIMS; 46 | 47 | vec2 b = abs(p - 0.5*TABLE_DIMS) - 0.5*TABLE_DIMS; 48 | float dbox = max(b.x, b.y); 49 | 50 | if (dbox < 0.) { 51 | 52 | vec2 cell = floor(p/CELL_DIMS); 53 | 54 | int keycode = int(cell.x) + int((15.-cell.y)*16.); 55 | 56 | bool hit = false; 57 | 58 | bvec3 ktex; 59 | for (int i=0; i<3; ++i) { 60 | ktex[i] = texelFetch(iChannel1, ivec2(keycode, i), 0).x > 0.; 61 | } 62 | 63 | color = ktex[0] ? vec3(1, 0.25, 0.25) : vec3(0.8); 64 | 65 | float dtext = 1e5; 66 | 67 | const int place[3] = int[3]( 100, 10, 1 ); 68 | bool nonzero = false; 69 | 70 | float i0 = (keycode >= 100 ? 1.0 : keycode >= 10 ? 1.5 : 2.0); 71 | 72 | for (int i=0; i<3; ++i) { 73 | 74 | int digit = keycode / place[i]; 75 | keycode -= digit * place[i]; 76 | 77 | if (digit > 0 || nonzero || i == 2) { 78 | 79 | vec2 p0 = (cell + vec2(0.5 + (float(i)-i0)*0.3, 0.5))*CELL_DIMS; 80 | vec2 uv = font_from_screen((p - p0), 1.0, vec2(digit, 12)); 81 | vec2 dbox = abs(p - p0) - 0.5; 82 | dtext = min(dtext, max(max(dbox.x, dbox.y), sample_grad_dist(uv, 1.0).z)); 83 | nonzero = true; 84 | 85 | } 86 | 87 | } 88 | 89 | vec3 textcolor = ktex[2] ? vec3(0) : (ktex[1] || ktex[0]) ? vec3(1) : vec3(0.9); 90 | 91 | if (ktex[1]) { 92 | vec2 q = (p/CELL_DIMS - cell); 93 | float b = pow( 24.0*q.x*q.y*(1.0-q.x)*(1.0-q.y), 0.5 ); 94 | color = mix(color, vec3(1.0, 1.0, 0.25), 1.0-b); 95 | } 96 | 97 | color = mix(color, textcolor, smoothstep(0.5*scl, -0.5*scl, dtext)); 98 | 99 | vec2 p0 = floor(p/CELL_DIMS + 0.5)*CELL_DIMS; 100 | vec2 dp0 = abs(p - p0); 101 | dbox = min(abs(dbox), min(abs(dp0.x), abs(dp0.y))); 102 | 103 | } 104 | 105 | color *= smoothstep(0., scl, abs(dbox)); 106 | 107 | fragColor = vec4(color, 1); 108 | } 109 | -------------------------------------------------------------------------------- /examples/truchet_trip.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/st3BDf 2 | // Created by https://www.shadertoy.com/user/BigWIngs 3 | 4 | // "Truchet Trip" 5 | // by Martijn Steinrucken aka BigWings/The Art of Code - 2021 6 | // 7 | // I recently made a tutorial on how to make a weave of two quad truchet layers. 8 | // Check it out here: 9 | // https://youtu.be/pmS-F6RJhAk 10 | // 11 | // Here is a 'sketch' I had lying around that makes use of this. 12 | 13 | #define S smoothstep 14 | #define TAU 6.283185 15 | #define AA 3 16 | 17 | mat2 Rot(float a) { 18 | float s=sin(a),c=cos(a); 19 | return mat2(c,-s,s,c); 20 | } 21 | 22 | vec2 Tile(vec2 p) { 23 | bool corner = p.x>-p.y; 24 | p -= corner?.5:-.5; 25 | float d = length(p); 26 | 27 | float a = atan(p.x,p.y)/TAU +.5; 28 | a = fract(a*4.); 29 | 30 | float m = cos(d*TAU*2.); 31 | 32 | return vec2(a-.5, d-.5); 33 | } 34 | 35 | float Hash21(vec2 p) { 36 | p = fract(p*vec2(123.489,234.95)); 37 | p += dot(p, p+34.4); 38 | return fract(p.x*p.y); 39 | } 40 | 41 | float Xor(float a, float b) { 42 | return a*(1.-b) + b*(1.-a); 43 | } 44 | 45 | vec3 TileLayer(vec2 p, float w) { 46 | vec2 gv = fract(p)-.5; 47 | 48 | p.y = mod(p.y, 6.); 49 | vec2 id = floor(p); 50 | // id = mod(id, 16.); 51 | 52 | float checker = mod(id.x+id.y, 2.); 53 | 54 | float n = Hash21(id); 55 | //n = .3; 56 | float flip = step(n, .5); 57 | 58 | if(flip==1.) gv.x *= -1.; 59 | 60 | vec2 st = Tile(gv); 61 | 62 | st.x = mix(st.x, 1.-st.x, checker); 63 | st.x = (st.x-.5)/2.+.5; 64 | st.y = st.y*(Xor(checker, flip)*2.-1.)/(w*2.); 65 | 66 | float z = gv.x>.48 || gv.y>.48 ? 1. : 0.; 67 | return vec3(st, z); 68 | } 69 | 70 | vec3 Render(vec2 fragCoord) { 71 | vec2 uv = (fragCoord-.5*iResolution.xy)/iResolution.y; 72 | vec2 M = iMouse.xy/iResolution.xy; 73 | 74 | vec3 col = vec3(0); 75 | float r = 16., r2=r/2., r4=r/4.; 76 | float t = iTime+M.x*17.; 77 | t = mod(t, r); 78 | 79 | vec2 p = uv; 80 | float cd = length(p), lcd = log(cd); 81 | 82 | p*= Rot(sin(t*TAU/r+lcd)*.2); 83 | float a = atan(p.x,p.y); 84 | p = vec2(a/TAU+.5, lcd); 85 | p*= vec2(4.,1.); 86 | 87 | p.y -= t/r4; 88 | 89 | float scale = 3.; 90 | float w = .2; 91 | vec3 st1 = TileLayer(p*scale, w); 92 | 93 | // st.x = fract(st.x+t*.1); 94 | float m1 = S(.01,.0,abs(st1.y)-w); 95 | float h1 = S(.0,.5, .5-abs(st1.x-.5)); 96 | 97 | vec3 st2 = TileLayer((p+.5)*scale, .5); 98 | float m2 = S(.01,.0,abs(st2.y)-w); 99 | float h2 = S(0., .5, .5-abs(st2.x-.5)); 100 | 101 | float t1 = st1.x+sin(st1.x*TAU)*.0; 102 | float t2 = st2.x; 103 | float arrow = st1.x+abs(st1.y); 104 | arrow = fract(arrow-t/2.+a/TAU+lcd); 105 | 106 | col += vec3(1,.02,.02)*t1*h1*m1 * arrow; 107 | 108 | vec3 ribbon = vec3(.02,1,.02)*t2; 109 | ribbon += sin(st2.x*TAU*4.+t*TAU/r4-a-lcd)*.1; 110 | ribbon += sin(st2.y*TAU*20.)*.01; 111 | 112 | col += ribbon*h2*m2; 113 | 114 | return col; 115 | } 116 | 117 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 118 | { 119 | vec3 col = vec3(0); 120 | 121 | for(int x=0; xa.y) ? vec2(1.0,0.0) : vec2(0.0,1.0); //vec2 of = 0.5 + 0.5*vec2(sign(a.x-a.y), sign(a.y-a.x)); 27 | vec2 b = a - o + K2; 28 | vec2 c = a - 1.0 + 2.0*K2; 29 | vec3 h = max(0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 ); 30 | vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); 31 | return dot(n, vec3(70.0)); 32 | } 33 | 34 | float fbm(vec2 n) { 35 | float total = 0.0, amplitude = 0.1; 36 | for (int i = 0; i < 7; i++) { 37 | total += noise(n) * amplitude; 38 | n = m * n; 39 | amplitude *= 0.4; 40 | } 41 | return total; 42 | } 43 | 44 | // ----------------------------------------------- 45 | 46 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 47 | vec2 p = fragCoord.xy / iResolution.xy; 48 | vec2 uv = p*vec2(iResolution.x/iResolution.y,1.0); 49 | float time = iTime * speed; 50 | float q = fbm(uv * cloudscale * 0.5); 51 | 52 | //ridged noise shape 53 | float r = 0.0; 54 | uv *= cloudscale; 55 | uv -= q - time; 56 | float weight = 0.8; 57 | for (int i=0; i<8; i++){ 58 | r += abs(weight*noise( uv )); 59 | uv = m*uv + time; 60 | weight *= 0.7; 61 | } 62 | 63 | //noise shape 64 | float f = 0.0; 65 | uv = p*vec2(iResolution.x/iResolution.y,1.0); 66 | uv *= cloudscale; 67 | uv -= q - time; 68 | weight = 0.7; 69 | for (int i=0; i<8; i++){ 70 | f += weight*noise( uv ); 71 | uv = m*uv + time; 72 | weight *= 0.6; 73 | } 74 | 75 | f *= r + f; 76 | 77 | //noise colour 78 | float c = 0.0; 79 | time = iTime * speed * 2.0; 80 | uv = p*vec2(iResolution.x/iResolution.y,1.0); 81 | uv *= cloudscale*2.0; 82 | uv -= q - time; 83 | weight = 0.4; 84 | for (int i=0; i<7; i++){ 85 | c += weight*noise( uv ); 86 | uv = m*uv + time; 87 | weight *= 0.6; 88 | } 89 | 90 | //noise ridge colour 91 | float c1 = 0.0; 92 | time = iTime * speed * 3.0; 93 | uv = p*vec2(iResolution.x/iResolution.y,1.0); 94 | uv *= cloudscale*3.0; 95 | uv -= q - time; 96 | weight = 0.4; 97 | for (int i=0; i<7; i++){ 98 | c1 += abs(weight*noise( uv )); 99 | uv = m*uv + time; 100 | weight *= 0.6; 101 | } 102 | 103 | c += c1; 104 | 105 | vec3 skycolour = mix(skycolour2, skycolour1, p.y); 106 | vec3 cloudcolour = vec3(1.1, 1.1, 0.9) * clamp((clouddark + cloudlight*c), 0.0, 1.0); 107 | 108 | f = cloudcover + cloudalpha*f*r; 109 | 110 | vec3 result = mix(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 1.0), clamp(f + c, 0.0, 1.0)); 111 | 112 | fragColor = vec4( result, 1.0 ); 113 | } 114 | -------------------------------------------------------------------------------- /examples/infinite_gamecube.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/wdVyRt 2 | // Created by https://www.shadertoy.com/user/athibaul 3 | 4 | // Remake of "Infinite Gamecube" by Jinkweiq 5 | // https://www.shadertoy.com/view/tdKyz3 6 | 7 | 8 | #define PI 3.1415926535 9 | #define TAU (2.*PI) 10 | #define R(a) mat2(cos(a), sin(a), -sin(a), cos(a)) 11 | #define SPEED 5. 12 | 13 | float random(in float v){ 14 | return fract(sin(dot(vec2(v+2.),vec2(12.9898,78.233)))*43758.5453123); 15 | } 16 | 17 | 18 | 19 | float sdBox(vec3 p,vec3 r) 20 | { 21 | p=abs(p)-r; 22 | return length(max(p,0.))+min(max(p.x,max(p.y,p.z)),0.); 23 | } 24 | 25 | float map(vec3 p) 26 | { 27 | float t = SPEED*iTime; 28 | vec3 q = p; 29 | if(random(floor(t)) > 0.5) 30 | { 31 | q.xy = q.yx; 32 | } 33 | // Rotate in the y direction 34 | q -= vec3(0,fract(t),0); 35 | q -= vec3(0,-0.5,0.); 36 | float th = PI/2.*fract(t); 37 | q.yz *= R(th); 38 | q -= vec3(0,0.5,0.5); 39 | float rounded = 0.07; 40 | float box = sdBox(q, vec3(0.5)-rounded)-rounded; 41 | return min(p.z, box); 42 | } 43 | 44 | 45 | vec3 surfColor(vec3 p) 46 | { 47 | if(p.z > 0.01) return vec3(0.3,0.2,1.); 48 | 49 | float t = SPEED*iTime; 50 | 51 | vec3 tileCenter = random(floor(t)) > 0.5 ? vec3(fract(t), 0,0) : vec3(0, fract(t),0); 52 | float rounded = 0.1; 53 | vec3 col = vec3(0); 54 | for(float t_ = floor(t)-1.; t_ > floor(t) - 10.; t_--) 55 | { 56 | float d = sdBox(p-tileCenter, vec3(0.45)-rounded)-rounded; 57 | float intensity = clamp(t-t_-1.2,0.,1.); 58 | col += vec3(0.3,0.2,1.) * smoothstep(0.01,-0.01,d) * intensity; 59 | if(random(floor(t_)) > 0.5) 60 | tileCenter += vec3(1,0,0); 61 | else 62 | tileCenter += vec3(0,1,0); 63 | } 64 | return col; 65 | } 66 | 67 | vec3 normal(vec3 p) 68 | { 69 | vec2 e = 0.002 * vec2(1,-1); 70 | return normalize(e.xxx*map(p+e.xxx) 71 | +e.xyy*map(p+e.xyy) 72 | +e.yxy*map(p+e.yxy) 73 | +e.yyx*map(p+e.yyx)); 74 | } 75 | 76 | 77 | vec3 render(vec3 ro, vec3 rd) 78 | { 79 | float d, t=0.; 80 | for(int i=0; i<256; i++) 81 | { 82 | d = map(ro+t*rd); 83 | if(d < 0.001 || t > 100.) break; 84 | t += d; 85 | } 86 | vec3 p = ro+t*rd; 87 | vec3 n = normal(p); 88 | vec3 c = surfColor(p); 89 | 90 | //return 0.5+0.5*n; 91 | vec3 lig = normalize(vec3(0,-1,1)); 92 | float NdotL = dot(n, lig); 93 | float RdotL = dot(reflect(rd, n), lig); 94 | vec3 spec = pow(clamp(RdotL,0.,1.),5.) * vec3(p.z) * 0.5; 95 | return c * (0.5+0.5*NdotL) + spec; 96 | } 97 | 98 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 99 | { 100 | vec2 uv = (fragCoord*2.-iResolution.xy)/iResolution.y; 101 | 102 | // Perspective camera 103 | /* 104 | vec3 ro = vec3(2); 105 | vec3 camFwd = normalize(vec3(0,0,0.5) - ro); 106 | vec3 camRight = normalize(cross(camFwd, vec3(0,0,1))); 107 | vec3 camUp = cross(camRight, camFwd); 108 | vec3 rd = normalize(camFwd + 0.5*(uv.x*camRight+uv.y*camUp)); 109 | */ 110 | 111 | // Orthographic camera 112 | vec3 rd = normalize(vec3(-1)); 113 | vec3 camRight = normalize(cross(rd, vec3(0,0,1))); 114 | vec3 camUp = cross(camRight, rd); 115 | vec3 ro = vec3(0,0,0.5) + (vec3(1)+uv.x*camRight + uv.y*camUp) * 2.5; 116 | 117 | vec3 col = render(ro, rd); 118 | 119 | col = sqrt(col); 120 | fragColor = vec4(col,1.0); 121 | } 122 | 123 | -------------------------------------------------------------------------------- /lease.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Antonin Stefanutti 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice (including the 12 | * next paragraph) shall be included in all copies or substantial portions 13 | * of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "lease.h" 29 | 30 | #if XCB_LEASE 31 | 32 | int xcb_lease(xcb_connection_t *connection, int *screen) { 33 | xcb_screen_iterator_t s_i; 34 | int i_s = 0; 35 | for (s_i = xcb_setup_roots_iterator(xcb_get_setup(connection)); s_i.rem; xcb_screen_next(&s_i), i_s++) { 36 | if (i_s == *screen) 37 | break; 38 | } 39 | 40 | xcb_window_t root = s_i.data->root; 41 | 42 | xcb_randr_get_screen_resources_cookie_t gsr_c = xcb_randr_get_screen_resources(connection, root); 43 | xcb_randr_get_screen_resources_reply_t *gsr_r = xcb_randr_get_screen_resources_reply(connection, gsr_c, NULL); 44 | if (!gsr_r) { 45 | printf("xcb_randr_get_screen_resources failed\n"); 46 | return -1; 47 | } 48 | 49 | xcb_randr_output_t *ro = xcb_randr_get_screen_resources_outputs(gsr_r); 50 | int o, c; 51 | 52 | xcb_randr_output_t output = 0; 53 | 54 | /* Use the first connected output */ 55 | for (o = 0; output == 0 && o < gsr_r->num_outputs; o++) { 56 | xcb_randr_get_output_info_cookie_t goi_c = xcb_randr_get_output_info(connection, ro[o], gsr_r->config_timestamp); 57 | xcb_randr_get_output_info_reply_t *goi_r = xcb_randr_get_output_info_reply(connection, goi_c, NULL); 58 | if (!goi_r) { 59 | printf("xcb_randr_get_output_info failed\n"); 60 | return -1; 61 | } 62 | 63 | if (goi_r->connection == XCB_RANDR_CONNECTION_CONNECTED && goi_r->crtc != 0) { 64 | output = ro[o]; 65 | } 66 | 67 | free(goi_r); 68 | } 69 | 70 | xcb_randr_crtc_t *rc = xcb_randr_get_screen_resources_crtcs(gsr_r); 71 | xcb_randr_crtc_t crtc = 0; 72 | 73 | /* Use the first connected crtc */ 74 | for (c = 0; crtc == 0 && c < gsr_r->num_crtcs; c++) { 75 | xcb_randr_get_crtc_info_cookie_t gci_c = xcb_randr_get_crtc_info(connection, rc[c], gsr_r->config_timestamp); 76 | xcb_randr_get_crtc_info_reply_t *gci_r = xcb_randr_get_crtc_info_reply(connection, gci_c, NULL); 77 | if (!gci_r) { 78 | printf("xcb_randr_get_crtc_info failed\n"); 79 | return -1; 80 | } 81 | 82 | // if (gci_r->mode != 0) { 83 | crtc = rc[c]; 84 | // } 85 | 86 | free(gci_r); 87 | } 88 | 89 | free(gsr_r); 90 | 91 | xcb_randr_lease_t lease = xcb_generate_id(connection); 92 | 93 | xcb_randr_create_lease_cookie_t rcl_c = xcb_randr_create_lease(connection,root,lease,1,1,&crtc,&output); 94 | xcb_randr_create_lease_reply_t *rcl_r = xcb_randr_create_lease_reply(connection, rcl_c, NULL); 95 | if (!rcl_r) { 96 | printf("xcb_randr_create_lease failed\n"); 97 | return -1; 98 | } 99 | 100 | int *rcl_f = xcb_randr_create_lease_reply_fds(connection, rcl_r); 101 | int fd = rcl_f[0]; 102 | free(rcl_r); 103 | 104 | return fd; 105 | } 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /examples/warping_boxes.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/dlSGWm 2 | // Created by https://www.shadertoy.com/user/mrange 3 | 4 | // CC0: Warping boxes 5 | // I tinkered with the multi-level metaballs of yesterday 6 | // and used boxes instead of circles. This + random tinkering 7 | // turned out quite nice in the end IMHO. 8 | 9 | #define TIME iTime 10 | #define RESOLUTION iResolution 11 | #define PI 3.141592654 12 | #define TAU (2.0*PI) 13 | #define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a)) 14 | 15 | // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm 16 | float box(vec2 p, vec2 b) { 17 | vec2 d = abs(p)-b; 18 | return length(max(d,0.0)) + min(max(d.x,d.y),0.0); 19 | } 20 | 21 | // License: MIT OR CC-BY-NC-4.0, author: mercury, found: https://mercury.sexy/hg_sdf/ 22 | vec2 mod2(inout vec2 p, vec2 size) { 23 | vec2 c = floor((p + size*0.5)/size); 24 | p = mod(p + size*0.5,size) - size*0.5; 25 | return c; 26 | } 27 | 28 | // License: Unknown, author: Hexler, found: Kodelife example Grid 29 | float hash(vec2 uv) { 30 | return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); 31 | } 32 | 33 | // License: Unknown, author: Unknown, found: don't remember 34 | float tanh_approx(float x) { 35 | // Found this somewhere on the interwebs 36 | // return tanh(x); 37 | float x2 = x*x; 38 | return clamp(x*(27.0 + x2)/(27.0+9.0*x2), -1.0, 1.0); 39 | } 40 | 41 | float dot2(vec2 p) { 42 | return dot(p, p); 43 | } 44 | 45 | vec2 df(vec2 p, float aa, out float h, out float sc) { 46 | vec2 pp = p; 47 | 48 | float sz = 2.0; 49 | 50 | float r = 0.0; 51 | 52 | for (int i = 0; i < 5; ++i) { 53 | vec2 nn = mod2(pp, vec2(sz)); 54 | sz /= 3.0; 55 | float rr = hash(nn+123.4); 56 | r += rr; 57 | if (rr < 0.5) break; 58 | } 59 | 60 | float d0 = box(pp, vec2(1.45*sz-0.75*aa))-0.05*sz; 61 | float d1 = sqrt(sqrt(dot2(pp*pp))); 62 | h = fract(r); 63 | sc = sz; 64 | return vec2(d0, d1); 65 | } 66 | 67 | vec2 toSmith(vec2 p) { 68 | // z = (p + 1)/(-p + 1) 69 | // (x,y) = ((1+x)*(1-x)-y*y,2y)/((1-x)*(1-x) + y*y) 70 | float d = (1.0 - p.x)*(1.0 - p.x) + p.y*p.y; 71 | float x = (1.0 + p.x)*(1.0 - p.x) - p.y*p.y; 72 | float y = 2.0*p.y; 73 | return vec2(x,y)/d; 74 | } 75 | 76 | vec2 fromSmith(vec2 p) { 77 | // z = (p - 1)/(p + 1) 78 | // (x,y) = ((x+1)*(x-1)+y*y,2y)/((x+1)*(x+1) + y*y) 79 | float d = (p.x + 1.0)*(p.x + 1.0) + p.y*p.y; 80 | float x = (p.x + 1.0)*(p.x - 1.0) + p.y*p.y; 81 | float y = 2.0*p.y; 82 | return vec2(x,y)/d; 83 | } 84 | 85 | vec2 transform(vec2 p) { 86 | p *= 2.0; 87 | const mat2 rot0 = ROT(1.0); 88 | const mat2 rot1 = ROT(-2.0); 89 | vec2 off0 = 4.0*cos(vec2(1.0, sqrt(0.5))*0.23*TIME); 90 | vec2 off1 = 3.0*cos(vec2(1.0, sqrt(0.5))*0.13*TIME); 91 | vec2 sp0 = toSmith(p); 92 | vec2 sp1 = toSmith((p+off0)*rot0); 93 | vec2 sp2 = toSmith((p-off1)*rot1); 94 | vec2 pp = fromSmith(sp0+sp1-sp2); 95 | p = pp; 96 | p += 0.25*TIME; 97 | 98 | return p; 99 | } 100 | 101 | vec3 effect(vec2 p, vec2 np, vec2 pp) { 102 | p = transform(p); 103 | np = transform(np); 104 | float aa = distance(p, np)*sqrt(2.0); 105 | 106 | float h = 0.0; 107 | float sc = 0.0; 108 | vec2 d2 = df(p, aa, h, sc); 109 | 110 | vec3 col = vec3(0.0); 111 | 112 | vec3 rgb = ((2.0/3.0)*(cos(TAU*h+vec3(0.0, 1.0, 2.0))+vec3(1.0))-d2.y/(3.0*sc)); 113 | col = mix(col, rgb, smoothstep(aa, -aa, d2.x)); 114 | 115 | const vec3 gcol1 = vec3(.5, 2.0, 3.0); 116 | col += gcol1*tanh_approx(0.025*aa); 117 | 118 | col = clamp(col, 0.0, 1.0); 119 | col = sqrt(col); 120 | 121 | return col; 122 | } 123 | 124 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 125 | vec2 q = fragCoord/RESOLUTION.xy; 126 | vec2 p = -1. + 2. * q; 127 | vec2 pp = p; 128 | p.x *= RESOLUTION.x/RESOLUTION.y; 129 | vec2 np = p+1.0/RESOLUTION.y; 130 | vec3 col = effect(p, np, pp); 131 | fragColor = vec4(col, 1.0); 132 | } 133 | -------------------------------------------------------------------------------- /examples/smooth_contours.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/WtdyzS 2 | // Created by https://www.shadertoy.com/user/Vectornaut 3 | 4 | // draw an antialiased contour plot using automatic differentiation. this method 5 | // works well when the contour stripes are many pixels wide. at each pixel, we 6 | // use the linearized pattern function to estimate the distance to the nearest 7 | // stripe edge. then we mix the colors on the near and far sides of the edge by 8 | // area samping with a gaussian weight. for more on area sampling, see 9 | // 10 | // Andries van Dam. "Image Processing & Antialiasing, Part II" 11 | // https://www.slideserve.com/shannon-dominguez/image-processing-antialiasing 12 | 13 | // --- automatic differentiation --- 14 | 15 | // a 1-jet of a map R^2 --> R^2, with image point `pt` and derivative `push` 16 | struct jet2 { 17 | vec2 pt; 18 | mat2 push; 19 | }; 20 | 21 | jet2 add(jet2 f, jet2 g) { 22 | return jet2(f.pt + g.pt, f.push + g.push); 23 | } 24 | 25 | jet2 apply(mat2 a, jet2 f) { 26 | return jet2(a*f.pt, a*f.push); 27 | } 28 | 29 | jet2 wave(jet2 f) { 30 | return jet2(sin(f.pt), mat2(cos(f.pt.x), 0., 0., cos(f.pt.y)) * f.push); 31 | } 32 | 33 | // a 1-jet of a map R^2 --> R, with image point `pt` and derivative `push` 34 | struct jet21 { 35 | float pt; 36 | vec2 push; 37 | }; 38 | 39 | jet21 proj_y(jet2 f) { 40 | return jet21(f.pt.y, vec2(f.push[0].y, f.push[1].y)); 41 | } 42 | 43 | jet21 dmod(jet21 t, float period) { 44 | return jet21(mod(t.pt, period), t.push); 45 | } 46 | 47 | // --- approximate error function --- 48 | 49 | const float A1 = 0.278393; 50 | const float A2 = 0.230389; 51 | const float A3 = 0.000972; 52 | const float A4 = 0.078108; 53 | 54 | // Abramowitz and Stegun, equation 7.1.27 55 | float erfc_appx(float t) { 56 | float p = 1. + A1*(t + A2*(t + A3*(t + A4*t))); 57 | float p_sq = p*p; 58 | return 1. / (p_sq*p_sq); 59 | } 60 | 61 | // --- antialiased stripe pattern --- 62 | 63 | const int N = 4; 64 | 65 | vec3 stripe(jet2 f, float r_px) { 66 | // set up stripe colors 67 | vec3 colors [N]; 68 | colors[0] = vec3(0.82, 0.77, 0.71); 69 | colors[1] = vec3(0.18, 0.09, 0.00); 70 | colors[2] = vec3(0.02, 0.36, 0.51); 71 | colors[3] = vec3(0.24, 0.62, 0.67); 72 | 73 | // find the displacement to the nearest stripe edge in the pattern space 74 | jet21 t = dmod(proj_y(f), float(N)); // the pattern coordinate 75 | int n = int(t.pt); // the index of the nearest stripe edge 76 | float pattern_disp = t.pt - (float(n) + 0.5); 77 | 78 | // the edges of the stripes on the screen are level sets of the pattern 79 | // coordinate `t`. linearizing, we get stripes on the screen tangent space, 80 | // whose edges are level sets of `t.push`. find the distance to the nearest 81 | // stripe edge in the screen tangent space 82 | float screen_dist = abs(pattern_disp) / length(t.push); 83 | 84 | // now we can integrate our pixel's sampling distribution on the screen 85 | // tangent space to find out how much of the pixel falls on the other side 86 | // of the nearest edge 87 | float overflow = 0.5*erfc_appx(screen_dist / r_px); 88 | return mix(colors[n], colors[(n+1)%N], pattern_disp < 0. ? overflow : 1.-overflow); 89 | } 90 | 91 | // --- test image --- 92 | 93 | const float VIEW = 2.; 94 | 95 | mat2 rot(float t) { 96 | float a = cos(t); 97 | float b = sin(t); 98 | return mat2(a, b, -b, a); 99 | } 100 | 101 | void mainImage(out vec4 fragColor, in vec2 fragCoord) { 102 | // find screen point 103 | float small_dim = min(iResolution.x, iResolution.y); 104 | float r_px = VIEW / small_dim; // the inner radius of a pixel in the Euclidean metric of the screen 105 | jet2 p = jet2(r_px * (2.*fragCoord - iResolution.xy), mat2(1.)); 106 | 107 | // choose time-varying linear maps 108 | float t = 0.125*iTime; 109 | mat2 pre = (2.+cos(0.5*t)) * mat2(1., 1., 1., -1.); 110 | mat2 post = 2.*rot(t); 111 | 112 | // get pixel color 113 | vec3 color = stripe(apply(post, add(p, wave(apply(pre, p)))), r_px); 114 | fragColor = vec4(color, 1.); 115 | } 116 | -------------------------------------------------------------------------------- /examples/linear_to_hilbert.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/llGcDm 2 | // Created by https://www.shadertoy.com/user/iq 3 | 4 | // Created by inigo quilez - iq/2022 5 | 6 | // I'm drawing some shapes in a pixel buffer as usual where pixels are ordered 7 | // in "raster" or "linear", that is, left to right one row at a time, and then 8 | // repositioning all pixels back into the buffer following a hilbert curve. 9 | // 10 | // That is the TRANSFORM set to 0 below. You can set TRANSFORM to 1 to see the 11 | // opposite - drawing shapes into a buffer that has a hilbert curve in it just 12 | // to then stretch it into a linear string that we lay again over the plane in 13 | // regular "raster" order. 14 | 15 | 16 | // 0: linear -> hilbert 17 | // 1: hilbert -> linear 18 | #define TRANSFORM 0 19 | 20 | 21 | // adapted from https://en.wikipedia.org/wiki/Hilbert_curve 22 | int hilbert( ivec2 p, int level ) 23 | { 24 | int d = 0; 25 | for( int k=0; k>n)&1; 29 | d += ((3*r.x)^r.y) << (2*n); 30 | if (r.y == 0) { if (r.x == 1) { p = (1<>1, i^(i>>1) ) & 1; 42 | if (r.y==0) { if(r.x==1) { p = (1<>= 2; 45 | } 46 | return p; 47 | } 48 | 49 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 50 | { 51 | // work in integer coordinates please 52 | ivec2 ip = ivec2(fragCoord); 53 | ivec2 ir = ivec2(iResolution); 54 | 55 | // select hilbert resolution 56 | int level = 7; 57 | if( ir.x> 512 ) level = 8; 58 | if( ir.x>1024 ) level = 9; 59 | if( ir.x>2048 ) level = 10; 60 | 61 | // two square's bottom-left corner coordinates 62 | int res = (1<MAX_DIST || abs(dS) 0.01 ? mix(sunDown, sunUp, (p.y + sunPos.y) / sunSize) : skyColor; 57 | 58 | float scroll = buildingsScrollSpeed * cos(bendingRate * iTime); 59 | float height = hash21(floor(scroll + p.xx * buildingsWidthFactor)) * buildingsHeight; 60 | ret = p.y - horizonY < height ? buildingsColor : ret; 61 | 62 | return vec4(ret, 1.); 63 | } 64 | 65 | vec4 road(vec2 p) 66 | { 67 | vec3 q = vec3(p, 1) / (roadScale - p.y); 68 | 69 | float refl = 0.8 * (1. - abs(p.y - horizonY)); 70 | refl = refl * refl * refl; 71 | 72 | float k = zoom * sin(bendingRate * iTime); 73 | float bendFactor = k * q.z * q.z; 74 | 75 | float w = abs(q.x + bendFactor); 76 | float road = sin(roadDetail * q.z + speed * iTime); 77 | 78 | vec3 c; 79 | 80 | if (w > roadWidth) { 81 | bool vGrid = mod(w - roadWidth, 1.) > (1. - gridLineWidth); 82 | bool hGrid = (road < 0. && road > -gridLineWidth * 3.); 83 | 84 | vec3 grid = (vGrid || hGrid) ? mix(gridColor, gridColor2, refl) : groundColor; 85 | float blend = 1. - abs(p.y - horizonY); 86 | c = mix(grid, groundColor, blend * blend); 87 | } 88 | else { 89 | if (road > 0.) { 90 | vec3 fragColor = w > (roadWidth - sideLineWidth) ? paintColor : roadColor; 91 | c = fragColor; 92 | } 93 | else { 94 | vec3 fragColor = w > (roadWidth - sideLineWidth) ? paintColor2 : (w > (centerWidth * 0.5) ? roadColor2 : centerLineColor); 95 | c = fragColor; 96 | } 97 | 98 | vec4 invSky = sky(-p + vec2(sin(30. * p.y + iTime * 2.) * 0.01, horizonY)); 99 | c.rgb = (invSky.rgb * refl) + c.rgb * (1. - refl); 100 | } 101 | 102 | float d = abs(w - roadWidth); 103 | d = min(d, w); 104 | d = max(d, road); 105 | 106 | return vec4(c, d); 107 | } 108 | 109 | vec3 scene(vec2 fragCoord) 110 | { 111 | vec2 normFragCoord = ((fragCoord - 0.5 * iResolution.xy) / iResolution.yy) * 2.; 112 | 113 | vec4 c; 114 | vec3 glowColor; 115 | 116 | if (normFragCoord.y > horizonY) { 117 | c = sky(normFragCoord); 118 | } 119 | else { 120 | vec4 skyColor = sky(normFragCoord); 121 | vec4 roadColor = road(normFragCoord); 122 | 123 | c = roadColor; 124 | glowColor = skyColor.a < roadColor.a ? sunDown : paintColor2; 125 | c.a = min(skyColor.a, roadColor.a); 126 | 127 | c.rgb = roadColor.rgb; 128 | 129 | float glow = pow(glowRadius / c.a, glowIntensity); 130 | c.rgb += glow * glowColor * glowColorFactor; 131 | } 132 | 133 | return c.rgb; 134 | //return 1. - c.aaa; 135 | } 136 | 137 | void mainImage(out vec4 fragColor, in vec2 fragCoord) 138 | { 139 | vec3 c = scene(fragCoord); 140 | fragColor.xyz = c.xyz; 141 | } 142 | -------------------------------------------------------------------------------- /examples/oklab_based_tonemapper.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/3lGyRy 2 | // Created by https://www.shadertoy.com/user/Hatchling 3 | 4 | #define F1 float 5 | #define F3 vec3 6 | 7 | F1 Linear1(F1 c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);} 8 | F3 Linear3(F3 c){return F3(Linear1(c.r),Linear1(c.g),Linear1(c.b));} 9 | F1 Srgb1(F1 c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);} 10 | F3 Srgb3(F3 c){return F3(Srgb1(c.r),Srgb1(c.g),Srgb1(c.b));} 11 | 12 | vec3 rgb_to_oklab(vec3 c) 13 | { 14 | float l = 0.4121656120f * c.r + 0.5362752080f * c.g + 0.0514575653f * c.b; 15 | float m = 0.2118591070f * c.r + 0.6807189584f * c.g + 0.1074065790f * c.b; 16 | float s = 0.0883097947f * c.r + 0.2818474174f * c.g + 0.6302613616f * c.b; 17 | 18 | float l_ = pow(l, 1./3.); 19 | float m_ = pow(m, 1./3.); 20 | float s_ = pow(s, 1./3.); 21 | 22 | vec3 labResult; 23 | labResult.x = 0.2104542553f*l_ + 0.7936177850f*m_ - 0.0040720468f*s_; 24 | labResult.y = 1.9779984951f*l_ - 2.4285922050f*m_ + 0.4505937099f*s_; 25 | labResult.z = 0.0259040371f*l_ + 0.7827717662f*m_ - 0.8086757660f*s_; 26 | return labResult; 27 | } 28 | 29 | vec3 oklab_to_rgb(vec3 c) 30 | { 31 | float l_ = c.x + 0.3963377774f * c.y + 0.2158037573f * c.z; 32 | float m_ = c.x - 0.1055613458f * c.y - 0.0638541728f * c.z; 33 | float s_ = c.x - 0.0894841775f * c.y - 1.2914855480f * c.z; 34 | 35 | float l = l_*l_*l_; 36 | float m = m_*m_*m_; 37 | float s = s_*s_*s_; 38 | 39 | vec3 rgbResult; 40 | rgbResult.r = + 4.0767245293f*l - 3.3072168827f*m + 0.2307590544f*s; 41 | rgbResult.g = - 1.2681437731f*l + 2.6093323231f*m - 0.3411344290f*s; 42 | rgbResult.b = - 0.0041119885f*l - 0.7034763098f*m + 1.7068625689f*s; 43 | return rgbResult; 44 | } 45 | 46 | vec3 tonemap( vec3 linearRGB ) 47 | { 48 | const float limitHardness = 1.5; 49 | 50 | vec3 okl = rgb_to_oklab(linearRGB); 51 | 52 | // Limit luminance. 53 | /*okl.x = okl.x / pow(pow(okl.x, limitHardness) + 1., 1./limitHardness); 54 | 55 | // Limit magnitude of chrominance. 56 | { 57 | float mag = length(okl.yz); 58 | float magAfter = mag; 59 | magAfter *= 4.; 60 | magAfter = magAfter / pow(pow(magAfter, limitHardness) + 1., 1./limitHardness); 61 | magAfter /= 4.; 62 | okl.yz *= magAfter/mag; 63 | }*/ 64 | 65 | linearRGB = oklab_to_rgb(okl); 66 | 67 | // Try to keep the resulting value within the RGB gamut while 68 | // preserving chrominance and compensating for negative clipping. 69 | { 70 | { 71 | // Compensate for negative clipping. 72 | float lumBefore = dot(linearRGB, vec3(0.2126, 0.7152, 0.0722)); 73 | linearRGB = max(vec3(0), linearRGB); 74 | float lumAfter = dot(linearRGB, vec3(0.2126, 0.7152, 0.0722)); 75 | linearRGB *= lumBefore/lumAfter; 76 | 77 | // Keep the resulting value within the RGB gamut. 78 | linearRGB = linearRGB / pow(pow(linearRGB, vec3(limitHardness)) + vec3(1), vec3(1./limitHardness)); 79 | } 80 | 81 | for(int i = 0; i < 2; i++) 82 | { 83 | vec3 okl2 = rgb_to_oklab(linearRGB); 84 | 85 | // Control level of L preservation. 86 | okl2.x = mix(okl2.x, okl.x, 1.0); 87 | 88 | float magBefore = length(okl2.yz); 89 | // Control level of ab preservation. 90 | okl2.yz = mix(okl2.yz, okl.yz, 0.5); 91 | float magAfter = length(okl2.yz); 92 | 93 | // Uncomment this to only preserve hue. 94 | // okl2.yz *= magBefore/magAfter; 95 | 96 | linearRGB = oklab_to_rgb(okl2); 97 | 98 | { 99 | // Compensate for negative clipping. 100 | float lumBefore = dot(linearRGB, vec3(0.2126, 0.7152, 0.0722)); 101 | linearRGB = max(vec3(0), linearRGB); 102 | float lumAfter = dot(linearRGB, vec3(0.2126, 0.7152, 0.0722)); 103 | linearRGB *= lumBefore/lumAfter; 104 | 105 | // Keep the resulting value within the RGB gamut. 106 | linearRGB = linearRGB / pow(pow(linearRGB, vec3(limitHardness)) + vec3(1), vec3(1./limitHardness)); 107 | } 108 | } 109 | } 110 | 111 | 112 | return Srgb3(linearRGB); 113 | } 114 | 115 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 116 | { 117 | vec2 position = (fragCoord/iResolution.xy)* 2.0 - 1.0; 118 | position.x += iTime * 0.2; 119 | 120 | vec3 color = pow(sin(position.x * 4.0 + vec3(0.0, 1.0, 2.0) * 3.1415 * 2.0 / 3.0) * 0.5 + 0.5, vec3(2.0)) * (exp(abs(position.y) * 4.0) - 1.0);; 121 | 122 | if(position.y < 0.0) 123 | { 124 | color = tonemap(color); 125 | } 126 | else 127 | { 128 | color = Srgb3(color); 129 | } 130 | 131 | fragColor = vec4(color,1.0); 132 | } 133 | 134 | -------------------------------------------------------------------------------- /examples/grid_blend.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/fsf3W8 2 | // Created by https://www.shadertoy.com/user/Del 3 | 4 | // Simple grids (SST) 5 | // 6 | // Feel free to optimize, golf and generally improve them :) 7 | // 8 | // Del - 15/03/2021 9 | // 10 | // 11 | // will it blend? (attempt2) er, not really 12 | 13 | vec4 HexGrid(vec2 uv, out vec2 id) 14 | { 15 | uv *= mat2(1.1547,0.0,-0.5773503,1.0); 16 | vec2 f = fract(uv); 17 | float triid = 1.0; 18 | if((f.x+f.y) > 1.0) 19 | { 20 | f = 1.0 - f; 21 | triid = -1.0; 22 | } 23 | vec2 co = step(f.yx,f) * step(1.0-f.x-f.y,max(f.x,f.y)); 24 | id = floor(uv) + (triid < 0.0 ? 1.0 - co : co); 25 | co = (f - co) * triid * mat2(0.866026,0.0,0.5,1.0); 26 | uv = abs(co); 27 | return vec4(0.5-max(uv.y,abs(dot(vec2(0.866026,0.5),uv))),length(co),co); 28 | } 29 | 30 | // EquilateralTriangle distance 31 | float sdEqTri(in vec2 p) 32 | { 33 | const float k = 1.7320508;//sqrt(3.0); 34 | p.x = abs(p.x) - 0.5; 35 | p.y = p.y + 0.5/k; 36 | if( p.x+k*p.y>0.0 ) p = vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; 37 | p.x -= clamp( p.x, -1.0, 0.0 ); 38 | return -length(p)*sign(p.y); 39 | } 40 | 41 | // triangle grid equiv 42 | vec4 TriGrid(vec2 uv, out vec2 id) 43 | { 44 | const vec2 s = vec2(1, .8660254); // Sqrt (3)/2 45 | uv /= s; 46 | float ys = mod(floor(uv.y), 2.)*.5; 47 | vec4 ipY = vec4(ys, 0, ys + .5, 0); 48 | vec4 ip4 = floor(uv.xyxy + ipY) - ipY + .5; 49 | vec4 p4 = fract(uv.xyxy - ipY) - .5; 50 | float itri = (abs(p4.x)*2. + p4.y<.5)? 1. : -1.; 51 | p4 = itri>0.? vec4(p4.xy*s, ip4.xy) : vec4(p4.zw*s, ip4.zw); 52 | 53 | vec2 ep = p4.xy; 54 | ep.y = (ep.y + 0.14433766666667*itri) * itri; 55 | float edge = sdEqTri(ep); // dist to edge 56 | id = p4.zw; 57 | id *= mat2(1.1547,0.0,-0.5773503,1.0); // adjust ID (optional) 58 | p4.y+=0.14433766666667*itri; 59 | return vec4(abs(edge),length(p4.xy),p4.xy); 60 | } 61 | 62 | // simple square grid equiv 63 | vec4 SquareGrid(vec2 uv, out vec2 id) 64 | { 65 | vec2 fs = fract(uv)-0.5; 66 | id = floor(uv); 67 | id *= mat2(1.1547,0.0,-0.5773503,1.0); // adjust ID (optional) 68 | vec2 d = abs(fs)-0.5; 69 | float edge = length(max(d,0.0)) + min(max(d.x,d.y),0.0); 70 | return vec4(abs(edge),length(fs),fs.xy); 71 | } 72 | 73 | float hbar(vec2 p, float nline, float t) 74 | { 75 | return 0.5+sin((p.y*nline)+t)*0.5; 76 | } 77 | 78 | 79 | #define PI 3.14159 80 | #define TAU 6.28318 81 | // out: 0->val->0 82 | float SmoothTri2(float t, float val) 83 | { 84 | return val * (1.0-(0.5+cos(t*TAU)*0.5)); 85 | } 86 | mat2 rot( float th ){ vec2 a = sin(vec2(1.5707963, 0) + th); return mat2(a, -a.y, a.x); } 87 | float smin( float a, float b, float k ) 88 | { 89 | float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 ); 90 | return mix( b, a, h ) - k*h*(1.0-h); 91 | } 92 | 93 | vec2 smin( vec2 a, vec2 b, float k ) 94 | { 95 | a.x = smin(a.x,b.x,k); 96 | a.y = smin(a.y,b.y,k); 97 | return a; 98 | } 99 | vec4 smin( vec4 a, vec4 b, float k ) 100 | { 101 | a.x = smin(a.x,b.x,k); 102 | a.y = smin(a.y,b.y,k); 103 | a.z = smin(a.z,b.z,k); 104 | a.w = smin(a.w,b.w,k); 105 | return a; 106 | } 107 | 108 | 109 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 110 | { 111 | float t = iTime; 112 | vec2 uv = (fragCoord.xy - 0.5 * iResolution.xy) / iResolution.y; 113 | float xx = ((fragCoord.x-.5*iResolution.x) / iResolution.x)+0.5; 114 | 115 | // dirty grid blend! 116 | vec2 id,id2; 117 | vec4 h,h2; 118 | 119 | //h2 = SquareGrid(uv*8.0, id2); 120 | vec2 uv2 = uv; 121 | vec2 uv1 = uv; 122 | uv1 *= rot(t*0.1); 123 | uv2 *= rot(-t*0.1); 124 | 125 | h2 = HexGrid(uv1*2.0, id2); 126 | 127 | uv2 *= 1.5+sin(t*0.6)*0.5; 128 | h = TriGrid(uv2*4.0, id); 129 | 130 | float tt = SmoothTri2(fract(t*0.2),3.0)-1.0; 131 | 132 | tt = clamp(tt,0.0,1.0); 133 | 134 | //h = mix(h,h2,tt); 135 | //id = mix(id,id2,tt); 136 | 137 | h = smin(h,h2,0.25); 138 | id = smin(id,id2,0.25); 139 | 140 | 141 | vec3 bordercol = vec3(1.0,1.0,1.0); 142 | vec3 shapecol = vec3(0.2,0.25,0.35); 143 | 144 | // just do a simple patterned shape tint based on cell IDs 145 | float patternVal = 132.5; // 4.1 146 | float cm = 1.0 + pow(abs(sin(length(id)*patternVal + t*0.65)), 4.0); // pulse mult 147 | cm *= 1.0 + (hbar(uv,250.0,t*12.0)*0.1); // bars mult 148 | shapecol *= cm; 149 | 150 | // Output to screen 151 | vec3 finalcol = mix(bordercol,shapecol, smoothstep(0.0,0.015,h.x)); // edge 152 | //finalcol = mix(bordercol,finalcol, smoothstep(0.0,0.065,h.y)); // centre 153 | 154 | // vignetting 155 | uv = fragCoord/iResolution.xy; 156 | finalcol *= 0.5 + 0.5*pow( 16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y), 0.1 ); 157 | 158 | //finalcol = vec3(h.zw,0.0); // just show cell uv 159 | 160 | // divider lines 161 | //float div = (1.0-max( step(abs(xx-0.33),0.0025),step(abs(xx-0.66),0.0025))); 162 | fragColor = vec4(finalcol ,1.0); 163 | } 164 | -------------------------------------------------------------------------------- /examples/the_secret_place.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/7lfXRN 2 | // Created by https://www.shadertoy.com/user/Kamoshika 3 | 4 | #define D(v) sin(snoise2D((v) + c * 5e2) * 10.) 5 | 6 | float snoise2D(vec2 v); 7 | 8 | float hash(float x) 9 | { 10 | return fract(sin(x) * 43758.5453); 11 | } 12 | 13 | vec3 hsv(float h, float s, float v) { 14 | vec4 t = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 15 | vec3 p = abs(fract(vec3(h) + t.xyz) * 6.0 - vec3(t.w)); 16 | return v * mix(vec3(t.x), clamp(p - vec3(t.x), 0.0, 1.0), s); 17 | } 18 | 19 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 20 | { 21 | vec2 p = (fragCoord * 2. - iResolution.xy) / min(iResolution.x, iResolution.y); 22 | vec3 col = vec3(0); 23 | vec3 lightDir = normalize(vec3(-1, 2, 4)); 24 | 25 | vec2 e = vec2(1e-3, 0); 26 | 27 | vec2 q; 28 | float c, s, L; 29 | 30 | for(float i = 0.;i < 20.;i++){ 31 | L = 1. - fract(iTime) + i; 32 | c = hash(i + ceil(iTime)); 33 | q = p / atan(1e-3, L) / 2e3; 34 | s = D(q); 35 | if(s * dot(q, q) > .5){ 36 | break; 37 | } 38 | } 39 | 40 | vec3 normal = normalize(vec3((-D(q + e.xy) + s)/e.x, 41 | (-D(q + e.yx) + s)/e.x, 42 | 1. 43 | )); 44 | col = hsv(hash(c), .5, 1.) + max(dot(normal, lightDir), 0.); 45 | L = dot(q, q) * 10. + L * L; 46 | col *= exp(-L * .01); 47 | 48 | fragColor = vec4(col, 1.); 49 | } 50 | 51 | /*void mainImage( out vec4 fragColor, in vec2 fragCoord ) 52 | { 53 | vec2 p = (fragCoord * 2. - iResolution.xy) / min(iResolution.x, iResolution.y); 54 | vec3 col = vec3(0); 55 | vec3 lightDir = normalize(vec3(-1, 2, 4)); 56 | 57 | vec2 e = vec2(1e-4, 0); 58 | 59 | for(float i = 0.;i < 20.;i++){ 60 | float L = 1. - fract(iTime) + i; 61 | float c = hash(i + ceil(iTime)); 62 | vec2 q = p / atan(1e-3, L) / 2e3; 63 | float s = D(q); 64 | if(col.r == 0. && s * dot(q, q) > .5){ 65 | vec3 normal = normalize(vec3((-D(q + e.xy) + s)/e.x, 66 | (-D(q + e.yx) + s)/e.x, 67 | 1. 68 | )); 69 | col = hsv(hash(c), .5, 1.) + max(dot(normal, lightDir), 0.); 70 | L = dot(q, q) * 20. + L * L; 71 | col *= exp(-L * .01); 72 | } 73 | } 74 | 75 | fragColor = vec4(col, 1.); 76 | }*/ 77 | 78 | //--------------- snoise2D --------------------------------------------------------------------------- 79 | // Description : Array and textureless GLSL 2D simplex noise function. 80 | // Author : Ian McEwan, Ashima Arts. 81 | // Maintainer : stegu 82 | // Lastmod : 20110822 (ijm) 83 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 84 | // Distributed under the MIT License. See LICENSE file. 85 | // https://github.com/ashima/webgl-noise 86 | // https://github.com/stegu/webgl-noise 87 | // 88 | 89 | vec3 mod289(vec3 x) { 90 | return x - floor(x * (1.0 / 289.0)) * 289.0; 91 | } 92 | 93 | vec2 mod289(vec2 x) { 94 | return x - floor(x * (1.0 / 289.0)) * 289.0; 95 | } 96 | 97 | vec3 permute(vec3 x) { 98 | return mod289(((x*34.0)+1.0)*x); 99 | } 100 | 101 | float snoise2D(vec2 v) 102 | { 103 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 104 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 105 | -0.577350269189626, // -1.0 + 2.0 * C.x 106 | 0.024390243902439); // 1.0 / 41.0 107 | // First corner 108 | vec2 i = floor(v + dot(v, C.yy) ); 109 | vec2 x0 = v - i + dot(i, C.xx); 110 | 111 | // Other corners 112 | vec2 i1; 113 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 114 | //i1.y = 1.0 - i1.x; 115 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 116 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 117 | // x1 = x0 - i1 + 1.0 * C.xx ; 118 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 119 | vec4 x12 = x0.xyxy + C.xxzz; 120 | x12.xy -= i1; 121 | 122 | // Permutations 123 | i = mod289(i); // Avoid truncation effects in permutation 124 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 125 | + i.x + vec3(0.0, i1.x, 1.0 )); 126 | 127 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 128 | m = m*m ; 129 | m = m*m ; 130 | 131 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 132 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 133 | 134 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 135 | vec3 h = abs(x) - 0.5; 136 | vec3 ox = floor(x + 0.5); 137 | vec3 a0 = x - ox; 138 | 139 | // Normalise gradients implicitly by scaling m 140 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 141 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 142 | 143 | // Compute final noise value at P 144 | vec3 g; 145 | g.x = a0.x * x0.x + h.x * x0.y; 146 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 147 | return 130.0 * dot(m, g); 148 | } 149 | //--------------- snoise2D --------------------------------------------------------------------------- 150 | -------------------------------------------------------------------------------- /examples/weaving_bridges.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/std3Wn 2 | // Created by https://www.shadertoy.com/user/Plento 3 | 4 | // Cole Peterson (Plento) 5 | 6 | // An endless weaving highway, with no exits. Mouse controls zoom. 7 | 8 | #define R iResolution.xy 9 | #define m ((iMouse.xy - .5*R.xy) / R.y) 10 | #define ss(a, b, x) smoothstep(a, b, x) 11 | #define rot(a) mat2(cos(a), -sin(a), sin(a), cos(a)) 12 | 13 | #define w_scale 5. 14 | #define car_size vec2(0.07, 0.1) 15 | 16 | // Dave Hoshkin 17 | float hash12(vec2 p){ 18 | vec3 p3 = fract(vec3(p.xyx) * .1031); 19 | p3 += dot(p3, p3.yzx + 33.33); 20 | return fract((p3.x + p3.y) * p3.z); 21 | } 22 | float hsh(vec2 p){ 23 | vec3 p3 = fract(vec3(p.xyx) * .1031); 24 | p3 += dot(p3, p3.yzx + 33.33); 25 | return fract((p3.x + p3.y) * p3.z); 26 | } 27 | // Standard perlin 28 | float perlin(vec2 p){ 29 | vec2 i = floor(p); 30 | vec2 f = fract(p); 31 | 32 | float a = hsh(i); 33 | float b = hsh(i+vec2(1., .0)); 34 | float c = hsh(i+vec2(0. ,1 )); 35 | float d = hsh(i+vec2(1., 1. )); 36 | 37 | vec2 u = smoothstep(0., 1., f); 38 | 39 | return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; 40 | } 41 | 42 | // box sdf 43 | float box( in vec2 p, in vec2 b, float r){ 44 | vec2 d = abs(p)-b; 45 | return length(max(d,0.0)) + min(max(d.x,d.y),0.0) - r; 46 | } 47 | 48 | // is a cell be flipped or not 49 | bool flipped(vec2 id){ 50 | float rnd = hash12(id*200.); 51 | if(rnd > .5) return true; 52 | 53 | return false; 54 | } 55 | 56 | 57 | vec3 car(vec3 col, vec2 uv, vec2 uid){ 58 | uv.y *= .6; // stretch in direction of travel so they have more room to move in their cell 59 | 60 | float spd = iTime*.1; 61 | 62 | // Repeated uvs for cars (We only draw one) 63 | vec2 cm = vec2(0., spd ); 64 | vec2 cv = fract((uv-cm)*w_scale*2.)-0.5; 65 | vec2 id = floor((uv-cm)*w_scale*2.); 66 | float idc = floor((uv.x-cm.x)*w_scale); 67 | 68 | // Switch direction "randomly" 69 | if(cos(idc*2.) > 0.){ 70 | cm = vec2(0., -spd ); 71 | cv = fract((uv-cm)*w_scale*2.)-0.5; 72 | id = floor((uv-cm)*w_scale*2.); 73 | } 74 | 75 | if(mod(id.y, float(7)) == float(0)) return col; // Leave some cells empty 76 | 77 | // Make cars move down road in somewhat non uniform way 78 | float t = id.y*114. + id.x*116.; 79 | vec2 p = vec2(.0, .3*cos(iTime*1. + t)); 80 | 81 | // Adjust car position based on side of road 82 | if(mod(id.x, float(2)) == float(0)) p.x -= .2; 83 | else p.x += .2; 84 | 85 | cv += p; 86 | float cars = ss(.01, .0, box(cv, car_size, .03)); // Car mask 87 | 88 | // Car color 89 | float ct = (id.x*3. + id.y*5.); 90 | vec3 carCol = .5+.26*cos(vec3(4., 2., 1.)*ct + vec3(3., 4., 7.)); 91 | carCol *= max(ss(-.1, .21, abs(cv.y + .07)), .45); 92 | carCol += .16*ss(0.055, 0.01, abs(cv.y)); 93 | 94 | // Randomly add some variation 95 | if(cos(ct) > 0.){ 96 | carCol *= max(abs(cos(ct)), .6); 97 | carCol = mix(carCol, .6*vec3(.75, .85, .99), .7*ss(.3, .2, abs(cv.y*2. - .38))); 98 | } 99 | 100 | // Shadow under car 101 | float shdw = max(ss(-.08, .08, box(cv-vec2(0., .01), car_size+vec2(.015, .01), .03)), .3); 102 | 103 | return mix(col * shdw, carCol, cars) + vec3(0., 0., 0.); 104 | } 105 | 106 | 107 | vec3 road(vec2 uv, float y){ 108 | float rd = ss(.02, .00, abs(uv.x)); // road mask 109 | rd *= ss(.25, .35, abs(fract(y*14.)-.5)); // road line 110 | float bdg = ss(.35, .37, abs(uv.x)); // bridge mask 111 | float shdw = ss(.49, .18, abs(uv.x)); // bridge shadow 112 | 113 | float nse = perlin(uv*45.); // perlin noise 114 | float rc = clamp(nse*.4, .22, .24); // road color 115 | float bc = clamp(nse, .46, .5); // bridge color 116 | return mix(shdw * mix(vec3(rc), vec3(1), rd), vec3(bc), bdg); 117 | } 118 | 119 | 120 | void mainImage( out vec4 f, in vec2 u ){ 121 | vec2 uv = vec2(u.xy - 0.5*R.xy)/R.y; 122 | vec2 cv = uv; 123 | uv *= 0.99 + (.5+.5*sin(iTime*.5))*0.77; 124 | 125 | if(iMouse.z > 0.) 126 | uv *= max(0.3, (m.y+.4)*2.5); 127 | 128 | uv*=rot(-0.3); 129 | uv += iTime*.1; 130 | 131 | // Road uvs 132 | vec2 ruv = fract(uv*w_scale)-.5; 133 | vec2 id = floor(uv*w_scale); 134 | 135 | vec3 col = vec3(1); 136 | 137 | // rotate uv 90 degree based on cell 138 | float rnd = hash12(id*200.); 139 | if(flipped(id)){ 140 | ruv = vec2(ruv.y, -ruv.x); 141 | uv = vec2(uv.y, -uv.x); 142 | } 143 | 144 | // cell containing current pixel flipped status 145 | bool me = flipped(id); 146 | 147 | // main color 148 | col = road(ruv, uv.y); 149 | col = car(col, uv, id); 150 | 151 | // neighbooring cells flipped? 152 | bool lft = flipped(id + vec2(-1., 0.)); 153 | bool rgt = flipped(id + vec2(1., 0.)); 154 | bool up = flipped(id + vec2(0., 1.)); 155 | bool dwn = flipped(id + vec2(0., -1.)); 156 | 157 | // Add a shadow based on surrounding cells 158 | if(me && !lft) col *= ss(.78, .12, (ruv.y)); 159 | if(me && !rgt) col *= ss(.78, .12, (-ruv.y)); 160 | if(!me && up) col *= ss(.78, .12, (ruv.y)); 161 | if(!me && dwn) col *= ss(.78, .12, (-ruv.y)); 162 | 163 | col = pow(col*1.2, vec3(1.1)); 164 | 165 | // intro thingy 166 | float r = min(iTime, 3.); 167 | if(iTime < 3.) col *= ss(r, r-.01, length(cv)); 168 | f = vec4(col,1.0); 169 | } 170 | -------------------------------------------------------------------------------- /examples/plasma_globe.glsl: -------------------------------------------------------------------------------- 1 | // python glsl.py examples/plasma_globe.glsl -t iChannel0 presets/tex_RGBA_noise_medium.png 2 | 3 | // Copied from https://www.shadertoy.com/view/XsjXRm 4 | // Created by https://www.shadertoy.com/user/nimitz 5 | 6 | // Plasma Globe by nimitz (twitter: @stormoid) 7 | // https://www.shadertoy.com/view/XsjXRm 8 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License 9 | // Contact the author for other licensing options 10 | 11 | uniform highp sampler2D iChannel0; 12 | 13 | //looks best with around 25 rays 14 | #define NUM_RAYS 13. 15 | 16 | #define VOLUMETRIC_STEPS 19 17 | 18 | #define MAX_ITER 35 19 | #define FAR 6. 20 | 21 | #define time iTime*1.1 22 | 23 | 24 | mat2 mm2(in float a){float c = cos(a), s = sin(a);return mat2(c,-s,s,c);} 25 | float noise( in float x ){return textureLod(iChannel0, vec2(x*.01,1.),0.0).x;} 26 | 27 | float hash( float n ){return fract(sin(n)*43758.5453);} 28 | 29 | float noise(in vec3 p) 30 | { 31 | vec3 ip = floor(p); 32 | vec3 fp = fract(p); 33 | fp = fp*fp*(3.0-2.0*fp); 34 | 35 | vec2 tap = (ip.xy+vec2(37.0,17.0)*ip.z) + fp.xy; 36 | vec2 rg = textureLod( iChannel0, (tap + 0.5)/256.0, 0.0 ).yx; 37 | return mix(rg.x, rg.y, fp.z); 38 | } 39 | 40 | mat3 m3 = mat3( 0.00, 0.80, 0.60, 41 | -0.80, 0.36, -0.48, 42 | -0.60, -0.48, 0.64 ); 43 | 44 | 45 | //See: https://www.shadertoy.com/view/XdfXRj 46 | float flow(in vec3 p, in float t) 47 | { 48 | float z=2.; 49 | float rz = 0.; 50 | vec3 bp = p; 51 | for (float i= 1.;i < 5.;i++ ) 52 | { 53 | p += time*.1; 54 | rz+= (sin(noise(p+t*0.8)*6.)*0.5+0.5) /z; 55 | p = mix(bp,p,0.6); 56 | z *= 2.; 57 | p *= 2.01; 58 | p*= m3; 59 | } 60 | return rz; 61 | } 62 | 63 | //could be improved 64 | float sins(in float x) 65 | { 66 | float rz = 0.; 67 | float z = 2.; 68 | for (float i= 0.;i < 3.;i++ ) 69 | { 70 | rz += abs(fract(x*1.4)-0.5)/z; 71 | x *= 1.3; 72 | z *= 1.15; 73 | x -= time*.65*z; 74 | } 75 | return rz; 76 | } 77 | 78 | float segm( vec3 p, vec3 a, vec3 b) 79 | { 80 | vec3 pa = p - a; 81 | vec3 ba = b - a; 82 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1. ); 83 | return length( pa - ba*h )*.5; 84 | } 85 | 86 | vec3 path(in float i, in float d) 87 | { 88 | vec3 en = vec3(0.,0.,1.); 89 | float sns2 = sins(d+i*0.5)*0.22; 90 | float sns = sins(d+i*.6)*0.21; 91 | en.xz *= mm2((hash(i*10.569)-.5)*6.2+sns2); 92 | en.xy *= mm2((hash(i*4.732)-.5)*6.2+sns); 93 | return en; 94 | } 95 | 96 | vec2 map(vec3 p, float i) 97 | { 98 | float lp = length(p); 99 | vec3 bg = vec3(0.); 100 | vec3 en = path(i,lp); 101 | 102 | float ins = smoothstep(0.11,.46,lp); 103 | float outs = .15+smoothstep(.0,.15,abs(lp-1.)); 104 | p *= ins*outs; 105 | float id = ins*outs; 106 | 107 | float rz = segm(p, bg, en)-0.011; 108 | return vec2(rz,id); 109 | } 110 | 111 | float march(in vec3 ro, in vec3 rd, in float startf, in float maxd, in float j) 112 | { 113 | float precis = 0.001; 114 | float h=0.5; 115 | float d = startf; 116 | for( int i=0; imaxd ) break; 119 | d += h*1.2; 120 | float res = map(ro+rd*d, j).x; 121 | h = res; 122 | } 123 | return d; 124 | } 125 | 126 | //volumetric marching 127 | vec3 vmarch(in vec3 ro, in vec3 rd, in float j, in vec3 orig) 128 | { 129 | vec3 p = ro; 130 | vec2 r = vec2(0.); 131 | vec3 sum = vec3(0); 132 | float w = 0.; 133 | for( int i=0; i= FAR)continue; 187 | vec3 pos = ro+rz*rd; 188 | col = max(col,vmarch(pos,rd,j, bro)); 189 | } 190 | #endif 191 | 192 | ro = bro; 193 | rd = brd; 194 | vec2 sph = iSphere2(ro,rd); 195 | 196 | if (sph.x > 0.) 197 | { 198 | vec3 pos = ro+rd*sph.x; 199 | vec3 pos2 = ro+rd*sph.y; 200 | vec3 rf = reflect( rd, pos ); 201 | vec3 rf2 = reflect( rd, pos2 ); 202 | float nz = (-log(abs(flow(rf*1.2,time)-.01))); 203 | float nz2 = (-log(abs(flow(rf2*1.2,-time)-.01))); 204 | col += (0.1*nz*nz* vec3(0.12,0.12,.5) + 0.05*nz2*nz2*vec3(0.55,0.2,.55))*0.8; 205 | } 206 | 207 | fragColor = vec4(col*1.3, 1.0); 208 | } 209 | -------------------------------------------------------------------------------- /examples/tilings.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/4sf3zX 2 | // Created by https://www.shadertoy.com/user/knighty 3 | 4 | // triangular groups tessellations. Coxeter group p-q-r. Stereographic projection. 5 | // adapted from fragmentarium script.see: http://www.fractalforums.com/fragmentarium/triangle-groups-tessellation/ 6 | // Licence: free. 7 | // the type of the space embedding the tessellation depend on the value: 1/p+1/q+1/r 8 | // if >1 its the sphere 9 | // if =1 its the euclidean plane 10 | // if <1 its the hyperbolic plane 11 | // 12 | // Distance estimation to lines and vertices is used for antialiasing. 13 | // You can still improve quality by using antialiasing. 14 | 15 | 16 | // Iteration number. 17 | const int Iterations=20; 18 | 19 | //these are the p, q and r parameters that define the coxeter/triangle group 20 | const int pParam=3;// Pi/p: angle beween reflexion planes a and b . 21 | const int qParam=3;// Pi/q: angle beween reflexion planes b and c . 22 | const int rParam=4;// Pi/r: angle beween reflexion planes c and a . 23 | 24 | // U,V,W are the 'barycentric' coordinate for the vertex. 25 | float U=1.; 26 | float V=1.; 27 | float W=0.; 28 | 29 | const float SRadius=0.01;//Thikness of the lines 30 | 31 | //Colors 32 | const vec3 segColor=vec3(0.,0.,0.); 33 | const vec3 backGroundColor=vec3(1.,1.,1.); 34 | 35 | #define PI 3.14159 36 | vec3 nb,nc;//with na(=vec3(1,0,0)) these are the normals of the reflexion planes 37 | vec3 p,q;//the vertex 38 | vec3 pA,pB,pC;//"vertices" of the "triangle" made by the reflexion planes 39 | 40 | float spaceType=0.; 41 | 42 | float hdott(vec3 a, vec3 b){//dot product for "time like" vectors. 43 | return spaceType*dot(a.xy,b.xy)+a.z*b.z; 44 | } 45 | float hdots(vec3 a, vec3 b){//dot product for "space like" vectors (these are duals of the "time like" vectors). 46 | return dot(a.xy,b.xy)+spaceType*a.z*b.z; 47 | } 48 | float hlengtht(vec3 v){ 49 | return sqrt(abs(hdott(v,v))); 50 | } 51 | float hlengths(vec3 v){ 52 | return sqrt(abs(hdots(v,v))); 53 | } 54 | 55 | vec3 hnormalizet(vec3 v){//normalization of "time like" vectors. 56 | float l=1./hlengtht(v); 57 | return v*l; 58 | } 59 | /*vec3 hnormalizes(vec3 v){//normalization of "space like" vectors.(not used) 60 | float l=1./hlengths(v); 61 | return v*l; 62 | }*/ 63 | ///////////////////////////////////////////////// 64 | 65 | 66 | void init() { 67 | spaceType=float(sign(qParam*rParam+pParam*rParam+pParam*qParam-pParam*qParam*rParam));//1./pParam+1./qParam+1./rParam-1.; 68 | 69 | float cospip=cos(PI/float(pParam)), sinpip=sin(PI/float(pParam)); 70 | float cospiq=cos(PI/float(qParam)), sinpiq=sin(PI/float(qParam)); 71 | float cospir=cos(PI/float(rParam)), sinpir=sin(PI/float(rParam)); 72 | float ncsincos=(cospiq+cospip*cospir)/sinpip; 73 | 74 | //na is simply vec3(1.,0.,0.). 75 | nb=vec3(-cospip,sinpip,0.); 76 | nc=vec3(-cospir,-ncsincos,sqrt(abs((ncsincos+sinpir)*(-ncsincos+sinpir)))); 77 | 78 | if(spaceType==0.){//This case is a little bit special 79 | nc.z=0.25; 80 | } 81 | 82 | pA=vec3(nb.y*nc.z,-nb.x*nc.z,nb.x*nc.y-nb.y*nc.x); 83 | pB=vec3(0.,nc.z,-nc.y); 84 | pC=vec3(0.,0.,nb.y); 85 | 86 | q=U*pA+V*pB+W*pC;//the vertex is the weighted average of the vertices of the triangle 87 | p=hnormalizet(q); 88 | } 89 | 90 | vec3 fold(vec3 pos) { 91 | for(int i=0;i=1.) return backGroundColor;//We are outside Poincaré disc. 133 | 134 | z3=fold(z3); 135 | 136 | vec3 color=backGroundColor; 137 | 138 | //antialiasing using distance de segments and vertices (ds and dv) (see:http://www.iquilezles.org/www/articles/distance/distance.htm) 139 | { 140 | float ds=dist2Segments(z3, r); 141 | color=mix(segColor,color,smoothstep(-1.,1.,ds*0.5/aaScale));//clamp(ds/aaScale.y,0.,1.)); 142 | } 143 | 144 | //final touch in order to remove jaggies at the edge of the circle (for hyperbolic case) 145 | if(spaceType==-1.) color=mix(backGroundColor,color,smoothstep(0.,1.,(1.-r)*0.5/aaScale));//clamp((1.-r)/aaScale.y,0.,1.)); 146 | return color; 147 | } 148 | 149 | void animUVW(float t){ 150 | U=sin(t)*0.5+0.5; 151 | V=sin(2.*t)*0.5+0.5; 152 | W=sin(4.*t)*0.5+0.5; 153 | } 154 | 155 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 156 | { 157 | const float scaleFactor=2.1; 158 | vec2 uv = scaleFactor*(fragCoord.xy-0.5*iResolution.xy) / iResolution.y; 159 | aaScale=0.5*scaleFactor/iResolution.y; 160 | animUVW(0.5*PI*iTime); 161 | init(); 162 | fragColor = vec4(color(uv),1.0); 163 | } 164 | 165 | -------------------------------------------------------------------------------- /examples/saturday_torus.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/fd33zn 2 | // Created by https://www.shadertoy.com/user/mrange 3 | 4 | // License CC0: Saturday Torus 5 | // Inspired by: https://www.istockphoto.com/photo/black-and-white-stripes-projection-on-torus-gm488221403-39181884 6 | 7 | #define PI 3.141592654 8 | #define TAU (2.0*PI) 9 | #define TIME iTime 10 | #define TTIME (TAU*TIME) 11 | #define RESOLUTION iResolution 12 | #define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a)) 13 | #define PCOS(x) (0.5+0.5*cos(x)) 14 | 15 | // License: MIT, author: Inigo Quilez, found: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm 16 | float rayTorus(vec3 ro, vec3 rd, vec2 tor) { 17 | float po = 1.0; 18 | 19 | float Ra2 = tor.x*tor.x; 20 | float ra2 = tor.y*tor.y; 21 | 22 | float m = dot(ro,ro); 23 | float n = dot(ro,rd); 24 | 25 | // bounding sphere 26 | { 27 | float h = n*n - m + (tor.x+tor.y)*(tor.x+tor.y); 28 | if(h<0.0) return -1.0; 29 | //float t = -n-sqrt(h); // could use this to compute intersections from ro+t*rd 30 | } 31 | 32 | // find quartic equation 33 | float k = (m - ra2 - Ra2)/2.0; 34 | float k3 = n; 35 | float k2 = n*n + Ra2*rd.z*rd.z + k; 36 | float k1 = k*n + Ra2*ro.z*rd.z; 37 | float k0 = k*k + Ra2*ro.z*ro.z - Ra2*ra2; 38 | 39 | #ifndef TORUS_REDUCE_PRECISION 40 | // prevent |c1| from being too close to zero 41 | if(abs(k3*(k3*k3 - k2) + k1) < 0.01) 42 | { 43 | po = -1.0; 44 | float tmp=k1; k1=k3; k3=tmp; 45 | k0 = 1.0/k0; 46 | k1 = k1*k0; 47 | k2 = k2*k0; 48 | k3 = k3*k0; 49 | } 50 | #endif 51 | 52 | float c2 = 2.0*k2 - 3.0*k3*k3; 53 | float c1 = k3*(k3*k3 - k2) + k1; 54 | float c0 = k3*(k3*(-3.0*k3*k3 + 4.0*k2) - 8.0*k1) + 4.0*k0; 55 | 56 | 57 | c2 /= 3.0; 58 | c1 *= 2.0; 59 | c0 /= 3.0; 60 | 61 | float Q = c2*c2 + c0; 62 | float R = 3.0*c0*c2 - c2*c2*c2 - c1*c1; 63 | 64 | float h = R*R - Q*Q*Q; 65 | float z = 0.0; 66 | if(h < 0.0) { 67 | // 4 intersections 68 | float sQ = sqrt(Q); 69 | z = 2.0*sQ*cos(acos(R/(sQ*Q)) / 3.0); 70 | } else { 71 | // 2 intersections 72 | float sQ = pow(sqrt(h) + abs(R), 1.0/3.0); 73 | z = sign(R)*abs(sQ + Q/sQ); 74 | } 75 | z = c2 - z; 76 | 77 | float d1 = z - 3.0*c2; 78 | float d2 = z*z - 3.0*c0; 79 | if(abs(d1) < 1.0e-4) { 80 | if(d2 < 0.0) return -1.0; 81 | d2 = sqrt(d2); 82 | } else { 83 | if(d1 < 0.0) return -1.0; 84 | d1 = sqrt(d1/2.0); 85 | d2 = c1/d1; 86 | } 87 | 88 | //---------------------------------- 89 | 90 | float result = 1e20; 91 | 92 | h = d1*d1 - z + d2; 93 | if(h > 0.0) { 94 | h = sqrt(h); 95 | float t1 = -d1 - h - k3; t1 = (po<0.0)?2.0/t1:t1; 96 | float t2 = -d1 + h - k3; t2 = (po<0.0)?2.0/t2:t2; 97 | if(t1 > 0.0) result=t1; 98 | if(t2 > 0.0) result=min(result,t2); 99 | } 100 | 101 | h = d1*d1 - z - d2; 102 | if(h > 0.0) { 103 | h = sqrt(h); 104 | float t1 = d1 - h - k3; t1 = (po<0.0)?2.0/t1:t1; 105 | float t2 = d1 + h - k3; t2 = (po<0.0)?2.0/t2:t2; 106 | if(t1 > 0.0) result=min(result,t1); 107 | if(t2 > 0.0) result=min(result,t2); 108 | } 109 | 110 | return result; 111 | } 112 | 113 | // License: MIT, author: Inigo Quilez, found: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm 114 | vec3 torusNormal(vec3 pos, vec2 tor) { 115 | return normalize(pos*(dot(pos,pos)- tor.y*tor.y - tor.x*tor.x*vec3(1.0,1.0,-1.0))); 116 | } 117 | 118 | // License: Unknown, author: Unknown, found: don't remember 119 | float tanh_approx(float x) { 120 | // Found this somewhere on the interwebs 121 | // return tanh(x); 122 | float x2 = x*x; 123 | return clamp(x*(27.0 + x2)/(27.0+9.0*x2), -1.0, 1.0); 124 | } 125 | 126 | vec3 color(vec2 p, vec2 q) { 127 | const float rdd = 2.0; 128 | vec3 ro = 1.*vec3(0., 0.75, -0.2); 129 | vec3 la = vec3(0.0, 0.0, 0.2); 130 | vec3 up = vec3(0.3, 0.0, 1.0); 131 | vec3 lp1 = ro; 132 | lp1.xy *= ROT(0.85); 133 | lp1.xz *= ROT(-0.5); 134 | 135 | vec3 ww = normalize(la - ro); 136 | vec3 uu = normalize(cross(up, ww)); 137 | vec3 vv = normalize(cross(ww,uu)); 138 | vec3 rd = normalize(p.x*uu + p.y*vv + rdd*ww); 139 | 140 | const vec2 tor = 0.55*vec2(1.0, 0.75); 141 | float td = rayTorus(ro, rd, tor); 142 | vec3 tpos = ro + rd*td; 143 | vec3 tnor = -torusNormal(tpos, tor); 144 | vec3 tref = reflect(rd, tnor); 145 | 146 | vec3 ldif1 = lp1 - tpos; 147 | float ldd1 = dot(ldif1, ldif1); 148 | float ldl1 = sqrt(ldd1); 149 | vec3 ld1 = ldif1/ldl1; 150 | vec3 sro = tpos+0.05*tnor; 151 | float sd = rayTorus(sro, ld1, tor); 152 | vec3 spos = sro+ld1*sd; 153 | vec3 snor = -torusNormal(spos, tor); 154 | 155 | float dif1 = max(dot(tnor, ld1), 0.0); 156 | float spe1 = pow(max(dot(tref, ld1), 0.0), 10.0); 157 | float r = length(tpos.xy); 158 | float a = atan(tpos.y, tpos.x)-PI*tpos.z/(r+0.5*abs(tpos.z))-TTIME/45.0; 159 | float s = mix(0.05, 0.5, tanh_approx(2.0*abs(td-0.75))); 160 | vec3 bcol0 = vec3(0.3); 161 | vec3 bcol1 = vec3(0.025); 162 | vec3 tcol = mix(bcol0, bcol1, smoothstep(-s, s, sin(9.0*a))); 163 | 164 | vec3 col = vec3(0.0); 165 | 166 | if (td > -1.0) { 167 | col += tcol*mix(0.2, 1.0, dif1/ldd1)+0.25*spe1; 168 | col *= sqrt(abs(dot(rd, tnor))); 169 | } 170 | 171 | if (sd < ldl1) { 172 | col *= mix(1.0, 0.0, pow(abs(dot(ld1, snor)), 3.0*tanh_approx(sd))); 173 | } 174 | 175 | return col; 176 | } 177 | 178 | // License: MIT, author: Inigo Quilez, found: https://www.iquilezles.org/www/index.htm 179 | vec3 postProcess(vec3 col, vec2 q) { 180 | col = clamp(col, 0.0, 1.0); 181 | col = pow(col, 1.0/vec3(2.2)); 182 | col = col*0.6+0.4*col*col*(3.0-2.0*col); 183 | col = mix(col, vec3(dot(col, vec3(0.33))), -0.4); 184 | col *=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); 185 | return col; 186 | } 187 | 188 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 189 | vec2 q = fragCoord/iResolution.xy; 190 | vec2 p = -1. + 2. * q; 191 | p.x *= RESOLUTION.x/RESOLUTION.y; 192 | vec3 col = color(p, q); 193 | col = postProcess(col, q); 194 | fragColor = vec4(col, 1.0); 195 | } 196 | -------------------------------------------------------------------------------- /drm-legacy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Rob Clark 3 | * Copyright (c) 2020 Antonin Stefanutti 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice (including the 13 | * next paragraph) shall be included in all copies or substantial portions 14 | * of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | * DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "common.h" 31 | #include "drm-common.h" 32 | 33 | static struct drm drm; 34 | 35 | static void page_flip_handler(int fd, unsigned int frame, 36 | unsigned int sec, unsigned int usec, void *data) 37 | { 38 | /* suppress 'unused parameter' warnings */ 39 | (void) fd, (void) frame, (void) sec, (void) usec; 40 | 41 | int *waiting_for_flip = data; 42 | *waiting_for_flip = 0; 43 | } 44 | 45 | static int legacy_run(const struct gbm *gbm, const struct egl *egl) 46 | { 47 | fd_set fds; 48 | drmEventContext evctx = { 49 | .version = 2, 50 | .page_flip_handler = page_flip_handler, 51 | }; 52 | struct gbm_bo *bo; 53 | struct drm_fb *fb; 54 | uint32_t i = 0; 55 | uint64_t start_time, report_time, cur_time; 56 | int ret; 57 | 58 | if (gbm->surface) { 59 | eglSwapBuffers(egl->display, egl->surface); 60 | bo = gbm_surface_lock_front_buffer(gbm->surface); 61 | } else { 62 | bo = gbm->bos[0]; 63 | } 64 | fb = drm_fb_get_from_bo(bo); 65 | if (!fb) { 66 | fprintf(stderr, "Failed to get a new framebuffer BO\n"); 67 | return -1; 68 | } 69 | 70 | /* set mode: */ 71 | ret = drmModeSetCrtc(drm.fd, drm.crtc_id, fb->fb_id, 0, 0, 72 | &drm.connector_id, 1, drm.mode); 73 | if (ret) { 74 | printf("Failed to set mode: %s\n", strerror(errno)); 75 | return ret; 76 | } 77 | 78 | uint32_t flags; 79 | 80 | if (drm.async_page_flip) { 81 | flags = DRM_MODE_PAGE_FLIP_ASYNC; 82 | } else { 83 | flags = DRM_MODE_PAGE_FLIP_EVENT; 84 | } 85 | 86 | start_time = report_time = get_time_ns(); 87 | 88 | while (drm.frames == 0 || i < drm.frames) { 89 | unsigned frame = i; 90 | struct gbm_bo *next_bo; 91 | int waiting_for_flip = 1; 92 | 93 | /* Start fps measuring on second frame, to remove the time spent 94 | * compiling shader, etc, from the fps: 95 | */ 96 | if (i == 1) { 97 | start_time = report_time = get_time_ns(); 98 | } 99 | 100 | if (!gbm->surface) { 101 | glBindFramebuffer(GL_FRAMEBUFFER, egl->fbs[frame % NUM_BUFFERS].fb); 102 | } 103 | 104 | egl->draw(start_time, i++); 105 | 106 | /* Block until all the buffered GL operations are completed. 107 | * This is required on NVIDIA GPUs, for which the DRM drivers 108 | * do not wait for the rendering to complete, upon executing 109 | * page flipping operations, such as drmModePageFlip(). 110 | */ 111 | glFinish(); 112 | 113 | if (gbm->surface) { 114 | eglSwapBuffers(egl->display, egl->surface); 115 | next_bo = gbm_surface_lock_front_buffer(gbm->surface); 116 | } else { 117 | next_bo = gbm->bos[frame % NUM_BUFFERS]; 118 | } 119 | fb = drm_fb_get_from_bo(next_bo); 120 | if (!fb) { 121 | fprintf(stderr, "Failed to get a new framebuffer BO\n"); 122 | return -1; 123 | } 124 | 125 | /* 126 | * Here you could also update drm plane layers if you want 127 | * hw composition 128 | */ 129 | 130 | ret = drmModePageFlip(drm.fd, drm.crtc_id, fb->fb_id, 131 | flags, &waiting_for_flip); 132 | if (ret) { 133 | printf("failed to queue page flip: %s\n", strerror(errno)); 134 | return -1; 135 | } 136 | 137 | if (!drm.async_page_flip) { 138 | while (waiting_for_flip) { 139 | FD_ZERO(&fds); 140 | FD_SET(0, &fds); 141 | FD_SET(drm.fd, &fds); 142 | 143 | ret = select(drm.fd + 1, &fds, NULL, NULL, NULL); 144 | if (ret < 0) { 145 | printf("select err: %s\n", strerror(errno)); 146 | return ret; 147 | } else if (ret == 0) { 148 | printf("select timeout!\n"); 149 | return -1; 150 | } else if (FD_ISSET(0, &fds)) { 151 | printf("user interrupted!\n"); 152 | return 0; 153 | } 154 | drmHandleEvent(drm.fd, &evctx); 155 | } 156 | } 157 | 158 | cur_time = get_time_ns(); 159 | if (cur_time > (report_time + 2 * NSEC_PER_SEC)) { 160 | double elapsed_time = cur_time - start_time; 161 | double secs = elapsed_time / (double) NSEC_PER_SEC; 162 | unsigned frames = i - 1; /* first frame ignored */ 163 | printf("Rendered %u frames in %f sec (%f fps)\n", 164 | frames, secs, (double) frames / secs); 165 | report_time = cur_time; 166 | } 167 | 168 | /* release last buffer to render on again: */ 169 | if (gbm->surface) { 170 | gbm_surface_release_buffer(gbm->surface, bo); 171 | } 172 | bo = next_bo; 173 | } 174 | 175 | finish_perfcntrs(); 176 | 177 | cur_time = get_time_ns(); 178 | double elapsed_time = cur_time - start_time; 179 | double secs = elapsed_time / (double) NSEC_PER_SEC; 180 | unsigned frames = i - 1; /* first frame ignored */ 181 | printf("Rendered %u frames in %f sec (%f fps)\n", 182 | frames, secs, (double) frames / secs); 183 | 184 | dump_perfcntrs(frames, elapsed_time); 185 | 186 | return 0; 187 | } 188 | 189 | const struct drm * init_drm_legacy(int fd, const struct options *options) 190 | { 191 | int ret; 192 | 193 | ret = drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); 194 | if (ret) { 195 | printf("No universal planes support: %s\n", strerror(errno)); 196 | return NULL; 197 | } 198 | 199 | ret = init_drm(&drm, fd, options); 200 | if (ret) 201 | return NULL; 202 | 203 | drm.run = legacy_run; 204 | 205 | return &drm; 206 | } 207 | -------------------------------------------------------------------------------- /examples/starry_landscape.glsl: -------------------------------------------------------------------------------- 1 | // python glsl.py examples/starry_landscape.glsl -v iChannel0 presets/vol_grey_noise_3D.bin 2 | 3 | // Copied from https://www.shadertoy.com/view/WlGGRV 4 | // Created by https://www.shadertoy.com/user/Klems 5 | 6 | uniform highp sampler3D iChannel0; 7 | 8 | #define PI 3.14159265359 9 | #define rot(a) mat2(cos(a + PI*0.5*vec4(0,1,3,0))) 10 | 11 | vec3 hash33(vec3 p3) { 12 | p3 = fract(p3 * vec3(.1031, .1030, .0973)); 13 | p3 += dot(p3, p3.yxz+33.33); 14 | return fract((p3.xxy + p3.yxx)*p3.zyx); 15 | } 16 | 17 | float hash12(vec2 p) { 18 | vec3 p3 = fract(vec3(p.xyx) * .1031); 19 | p3 += dot(p3, p3.yzx + 33.33); 20 | return fract((p3.x + p3.y) * p3.z); 21 | } 22 | 23 | // https://research.nvidia.com/sites/default/files/pubs/2017-02_Hashed-Alpha-Testing/Wyman2017Hashed.pdf 24 | const float hashScale = 1.0; 25 | float hashedNoise(vec3 p, vec3 dpdx, vec3 dpdy) { 26 | float maxDeriv = max(length(dpdx), length(dpdy)); 27 | float pixScale = 1.0 / (hashScale*maxDeriv); 28 | vec2 pixScales = vec2(exp2(floor(log2(pixScale))), exp2(ceil(log2(pixScale)))); 29 | float aa = textureGrad(iChannel0, pixScales.x*p.xyz/32.0, pixScales.x*dpdx/32.0, pixScales.x*dpdy/32.0).r; 30 | float bb = textureGrad(iChannel0, pixScales.y*p.xyz/32.0, pixScales.y*dpdx/32.0, pixScales.y*dpdy/32.0).r; 31 | vec2 alpha = vec2(aa, bb); 32 | //alpha = vec2(hash33(floor(pixScales.x*p.xyz)).r, hash33(floor(pixScales.y*p.xyz)).r); 33 | float lerpFactor = fract( log2(pixScale) ); 34 | float x = (1.0-lerpFactor)*alpha.x + lerpFactor*alpha.y; 35 | float a = min( lerpFactor, 1.0-lerpFactor ); 36 | vec3 cases = vec3( x*x/(2.0*a*(1.0-a)),(x-0.5*a)/(1.0-a),1.0-((1.0-x)*(1.0-x)/(2.0*a*(1.0-a))) ); 37 | float alphaRes = (x < (1.0-a)) ? ((x < a) ? cases.x : cases.y) :cases.z; 38 | alphaRes = clamp(alphaRes, 1.0e-6, 1.0); 39 | return alphaRes; 40 | } 41 | 42 | // https://iquilezles.org/articles/filteringrm 43 | void calcDpDxy( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy, in float t, in vec3 nor, 44 | out vec3 dpdx, out vec3 dpdy ) { 45 | dpdx = t*(rdx*dot(rd,nor)/dot(rdx,nor) - rd); 46 | dpdy = t*(rdy*dot(rd,nor)/dot(rdy,nor) - rd); 47 | } 48 | 49 | // noise with smooth derivative 50 | float snoise( in vec3 x, const in float lod ) { 51 | float dim = 32.0 / exp2(lod); 52 | x = x * dim; 53 | vec3 p = floor(x); 54 | vec3 f = fract(x); 55 | f = f*f*(3.0-2.0*f); 56 | x = (p+f+0.5) / dim; 57 | return textureLod(iChannel0, x, lod).r; 58 | } 59 | 60 | // smoother noise 61 | float noise( in vec2 x ) { 62 | x *= 32.0; 63 | const vec2 e = vec2(1, 0); 64 | vec2 i = floor(x); 65 | vec2 f = fract(x); 66 | f = f*f*(3.0-2.0*f); 67 | return mix(mix( hash12(i+e.yy), hash12(i+e.xy),f.x), 68 | mix( hash12(i+e.yx), hash12(i+e.xx),f.x),f.y); 69 | } 70 | 71 | // cascading return to optimize distance function 72 | float height(vec2 p, float y) { 73 | p /= 32.0; 74 | float hei = noise(p*0.04); 75 | hei *= hei*30.0; 76 | if (y > hei+3.0) return hei; 77 | hei += snoise(vec3(p*0.5, 0), 0.0)*1.0; 78 | if (y > hei+2.0) return hei; 79 | hei += snoise(vec3(p*1.0, 10), 10.0)*0.2; 80 | if (y > hei+1.0) return hei; 81 | hei += snoise(vec3(p*2.0, 100), 20.0)*0.1; 82 | return hei; 83 | } 84 | 85 | float de(vec3 p) { 86 | return p.y - height(p.xz, p.y); 87 | } 88 | 89 | vec3 getNormal(vec3 p) { 90 | vec3 e = vec3(0.0, 0.3, 0.0); 91 | return normalize(vec3( 92 | de(p+e.yxx)-de(p-e.yxx), 93 | de(p+e.xyx)-de(p-e.xyx), 94 | de(p+e.xxy)-de(p-e.xxy))); 95 | } 96 | 97 | bool intSphere( in vec4 sp, in vec3 ro, in vec3 rd, out float t ) { 98 | vec3 d = ro - sp.xyz; 99 | float b = dot(rd,d); 100 | float c = dot(d,d) - sp.w*sp.w; 101 | float tt = b*b-c; 102 | if ( tt > 0.0 ) { 103 | t = -b-sqrt(tt); 104 | return true; 105 | } 106 | return false; 107 | } 108 | 109 | float star( in vec3 dir ) { 110 | dir.yz *= rot(-0.7); 111 | float base = step(abs(dir.z), 0.007); 112 | dir.xy *= rot(iTime*0.5); 113 | float trail = (atan(dir.x, dir.y)+PI)/(2.0*PI); 114 | trail = pow(trail+0.05, 20.0); 115 | return base*trail; 116 | } 117 | 118 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 119 | 120 | vec2 uv = (fragCoord - iResolution.xy * 0.5) / iResolution.y; 121 | uv += uv*dot(uv,uv)*0.5; 122 | 123 | vec3 from = vec3(0, 2, -5); 124 | vec3 dir = normalize(vec3(uv, 0.4)); 125 | 126 | vec2 mouse=(iMouse.xy - iResolution.xy*0.5) / iResolution.y * 2.5; 127 | if (iMouse.z < 0.5) mouse = vec2(0); 128 | mat2 rotxz = rot(-mouse.x+sin(iTime*0.1512)*0.75-PI*0.5); 129 | mat2 rotxy = rot(mouse.y+sin(iTime*0.12412)*0.25); 130 | dir.zy *= rotxy; 131 | dir.xz *= rotxz; 132 | 133 | from.x += iTime*10.0; 134 | from.y += height(from.xz, 9e9); 135 | 136 | float totdist = 0.0; 137 | for (int steps = min(iFrame, 0) ; steps < 150 ; steps++) { 138 | vec3 p = from + totdist * dir; 139 | float dist = de(p); 140 | totdist += dist*0.5; 141 | if (dist < 0.001 || totdist > 400.0) { 142 | break; 143 | } 144 | } 145 | 146 | const vec3 light = normalize(vec3(3, 1, 2)); 147 | float noi = hashedNoise(dir, dFdx(dir), dFdy(dir)); 148 | float lig = 0.0; 149 | vec3 test = vec3(0); 150 | if (totdist > 400.0) { 151 | 152 | // add stars 153 | lig = pow(texture(iChannel0, dir*0.7).r, 40.0)*10.0; 154 | 155 | // add a shooting star 156 | lig += star(dir); 157 | 158 | // add a planet 159 | vec3 fromPl = vec3(8, 5, -1); 160 | float toSphere = 0.0; 161 | bool sphere = intSphere( vec4(0, 0, 0, 1), fromPl, dir, toSphere); 162 | if (sphere) { 163 | vec3 normal = fromPl + dir*toSphere; 164 | lig = max(0.0, dot(normal, light))*30.0; 165 | } 166 | 167 | } else { 168 | 169 | vec3 p = from + totdist * dir; 170 | vec3 n = getNormal(p); 171 | vec3 dpdx = vec3(0); 172 | vec3 dpdy = vec3(0); 173 | calcDpDxy(from, dir, dir+dFdx(dir), dir+dFdy(dir), totdist, n, dpdx, dpdy); 174 | 175 | noi = hashedNoise(p, dpdx, dpdy); 176 | 177 | // diffuse 178 | lig = max(0.0, dot(n, light)); 179 | lig *= lig*2.0; 180 | 181 | // some fresnel 182 | float fres = pow(max(0.0, 1.0-dot(n, -dir)), 10.0); 183 | lig += fres*2.0; 184 | } 185 | 186 | // vignette, gamma correction 187 | lig = pow(lig*0.5, 1.0/2.2); 188 | vec2 uu = (fragCoord.xy-iResolution.xy*0.5)/iResolution.xy; 189 | lig = mix(lig, 0.0, dot(uu,uu)*1.3); 190 | 191 | fragColor = vec4(step(noi, lig)); 192 | } 193 | -------------------------------------------------------------------------------- /examples/rainbow_smith_cells.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/dtSGWh 2 | // Created by https://www.shadertoy.com/user/mrange 3 | 4 | // CC0: Rainbow smith cells 5 | // Continuation of earlier experiments 6 | 7 | #define TIME iTime 8 | #define RESOLUTION iResolution 9 | #define PI 3.141592654 10 | #define PI_2 (0.5*PI) 11 | #define TAU (2.0*PI) 12 | #define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a)) 13 | 14 | const float rep = 32.0; 15 | const float over = 4.0; 16 | const float nstep = 1.0/(rep*over); 17 | const float astep = TAU*nstep; 18 | const float pm = 17.0; 19 | 20 | // License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488 21 | const vec4 hsv2rgb_K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 22 | vec3 hsv2rgb(vec3 c) { 23 | vec3 p = abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www); 24 | return c.z * mix(hsv2rgb_K.xxx, clamp(p - hsv2rgb_K.xxx, 0.0, 1.0), c.y); 25 | } 26 | // License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488 27 | // Macro version of above to enable compile-time constants 28 | #define HSV2RGB(c) (c.z * mix(hsv2rgb_K.xxx, clamp(abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www) - hsv2rgb_K.xxx, 0.0, 1.0), c.y)) 29 | 30 | // License: MIT OR CC-BY-NC-4.0, author: mercury, found: https://mercury.sexy/hg_sdf/ 31 | float modPolar(inout vec2 p, float aa) { 32 | const float angle = 2.0*PI/rep; 33 | float a = aa + angle/2.; 34 | float r = length(p); 35 | float c = floor(a/angle); 36 | a = mod(a,angle) - angle/2.; 37 | p = vec2(cos(a), sin(a))*r; 38 | // For an odd number of repetitions, fix cell index of the cell in -x direction 39 | // (cell index would be e.g. -5 and 5 in the two halves of the cell): 40 | if (abs(c) >= (rep/2.0)) c = abs(c); 41 | return c; 42 | } 43 | 44 | // License: Unknown, author: nmz (twitter: @stormoid), found: https://www.shadertoy.com/view/NdfyRM 45 | vec3 sRGB(vec3 t) { 46 | return mix(1.055*pow(t, vec3(1./2.4)) - 0.055, 12.92*t, step(t, vec3(0.0031308))); 47 | } 48 | 49 | // License: Unknown, author: Matt Taylor (https://github.com/64), found: https://64.github.io/tonemapping/ 50 | vec3 aces_approx(vec3 v) { 51 | v = max(v, 0.0); 52 | v *= 0.6f; 53 | float a = 2.51f; 54 | float b = 0.03f; 55 | float c = 2.43f; 56 | float d = 0.59f; 57 | float e = 0.14f; 58 | return clamp((v*(a*v+b))/(v*(c*v+d)+e), 0.0f, 1.0f); 59 | } 60 | 61 | float segmentx(vec2 p, float l, float w) { 62 | p = abs(p); 63 | p.x -= l*0.5-w; 64 | float d0 = length(p)-w; 65 | float d1 = p.y-w; 66 | float d = p.x > 0.0 ? d0 : d1; 67 | return d; 68 | } 69 | 70 | vec2 df(vec2 p, float noff, float a, out float n) { 71 | const float ll = 0.5; 72 | const float ss = 0.0015; 73 | const float bb = ss*4.0; 74 | n = modPolar(p, a)/rep+noff; 75 | float m = 16.0*sin(TIME*TAU); 76 | float anim = sin(TAU*TIME/10.0+pm*noff*TAU); 77 | p.x -= 0.75+0.25*anim; 78 | float l = ll*mix(0.5, 1.0, smoothstep(-0.9, 0.9, anim)); 79 | float s = ss; 80 | float b = bb; 81 | vec2 p0 = p; 82 | vec2 p1 = p; 83 | p1.x = abs(p1.x); 84 | p1.x -= l*0.5-s; 85 | float d0 = segmentx(p0, l, s); 86 | float d1 = length(p1)-b; 87 | return vec2(d0, d1); 88 | } 89 | 90 | // License: Unknown, author: Martijn Steinrucken, found: https://www.youtube.com/watch?v=VmrIDyYiJBA 91 | vec2 hextile(inout vec2 p) { 92 | // See Art of Code: Hexagonal Tiling Explained! 93 | // https://www.youtube.com/watch?v=VmrIDyYiJBA 94 | const vec2 sz = vec2(1.0, sqrt(3.0)); 95 | const vec2 hsz = 0.5*sz; 96 | 97 | vec2 p1 = mod(p, sz)-hsz; 98 | vec2 p2 = mod(p - hsz, sz)-hsz; 99 | vec2 p3 = dot(p1, p1) < dot(p2, p2) ? p1 : p2; 100 | vec2 n = ((p3 - p + hsz)/sz); 101 | p = p3; 102 | 103 | n -= vec2(0.5); 104 | // Rounding to make hextile 0,0 well behaved 105 | return floor(n*2.0)*0.5; 106 | } 107 | 108 | vec3 effect0(vec2 p, float aa) { 109 | const float zz = 2.75; 110 | p /= zz; 111 | vec2 hn = hextile(p); 112 | p *= zz; 113 | float n; 114 | vec3 col = vec3(0.0); 115 | const mat2 rr = ROT(TAU/(rep*over)); 116 | vec2 pp = p; 117 | float a = atan(p.y, p.x); 118 | float ll = length(p); 119 | for (float i = 0.0; i < over; ++i) { 120 | float noff = i*nstep; 121 | float aoff = i*astep; 122 | vec2 d = df(p, noff, a-aoff, n); 123 | d /= aa; 124 | 125 | float g0 = 2.0/max(max(d.x, 0.0), 0.001); 126 | float g1 = 8.0/max((d.y*d.y), 0.000001); 127 | col += hsv2rgb(vec3(0.5*ll+n-0.1*TIME, 0.85, g0)); 128 | col += hsv2rgb(vec3(0.5*ll+n-0.1*TIME, 0.5, g1)); 129 | // col = mix(col, vec3(0.54), smoothstep(1.0, -1.0, d.x)); 130 | // col = mix(col, vec3(1.0), smoothstep(1.0, -1.0, d.y)); 131 | p *= rr; 132 | } 133 | 134 | col *= smoothstep(0.5*zz, 0.25*zz, ll); 135 | const vec3 gcol0 = HSV2RGB(vec3(0.55, 0.75, 10000.0)); 136 | const vec3 gcol1 = HSV2RGB(vec3(0.55, 0.95, 0.025)); 137 | col += gcol0*aa*aa+gcol1/dot(p, p); 138 | col /= (600.0*aa); 139 | return col; 140 | } 141 | 142 | 143 | vec2 toSmith(vec2 p) { 144 | // z = (p + 1)/(-p + 1) 145 | // (x,y) = ((1+x)*(1-x)-y*y,2y)/((1-x)*(1-x) + y*y) 146 | float d = (1.0 - p.x)*(1.0 - p.x) + p.y*p.y; 147 | float x = (1.0 + p.x)*(1.0 - p.x) - p.y*p.y; 148 | float y = 2.0*p.y; 149 | return vec2(x,y)/d; 150 | } 151 | 152 | vec2 fromSmith(vec2 p) { 153 | // z = (p - 1)/(p + 1) 154 | // (x,y) = ((x+1)*(x-1)+y*y,2y)/((x+1)*(x+1) + y*y) 155 | float d = (p.x + 1.0)*(p.x + 1.0) + p.y*p.y; 156 | float x = (p.x + 1.0)*(p.x - 1.0) + p.y*p.y; 157 | float y = 2.0*p.y; 158 | return vec2(x,y)/d; 159 | } 160 | 161 | vec2 transform(vec2 p) { 162 | vec2 off0 = sin(vec2(1.0, sqrt(0.5))*0.23*TIME); 163 | vec2 off1 = sin(vec2(1.0, sqrt(0.5))*0.13*TIME); 164 | vec2 sp0 = toSmith(p); 165 | vec2 sp1 = toSmith(p+off0); 166 | vec2 sp2 = toSmith(p-off1); 167 | vec2 pp = fromSmith(sp0+sp1-sp2); 168 | pp += 0.1*TIME; 169 | return pp; 170 | } 171 | 172 | vec3 effect(vec2 p, vec2 np, vec2 pp) { 173 | p = transform(p); 174 | np = transform(np); 175 | float aa = distance(p, np)*sqrt(2.0); 176 | vec3 col = effect0(p, aa); 177 | return col; 178 | } 179 | 180 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 181 | vec2 q = fragCoord/iResolution.xy; 182 | vec2 p = -1. + 2. * q; 183 | vec2 pp = p; 184 | p.x *= RESOLUTION.x/RESOLUTION.y; 185 | vec2 np = p + 1.0/RESOLUTION.y; 186 | vec3 col = effect(p, np, pp); 187 | col = aces_approx(col); 188 | col = sRGB(col); 189 | fragColor = vec4(col, 1.0); 190 | } 191 | -------------------------------------------------------------------------------- /examples/cyber_fuji_2020.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/Wt33Wf 2 | // Created by https://www.shadertoy.com/user/kaiware007 3 | 4 | float sun(vec2 uv, float battery) 5 | { 6 | float val = smoothstep(0.3, 0.29, length(uv)); 7 | float bloom = smoothstep(0.7, 0.0, length(uv)); 8 | float cut = 3.0 * sin((uv.y + iTime * 0.2 * (battery + 0.02)) * 100.0) 9 | + clamp(uv.y * 14.0 + 1.0, -6.0, 6.0); 10 | cut = clamp(cut, 0.0, 1.0); 11 | return clamp(val * cut, 0.0, 1.0) + bloom * 0.6; 12 | } 13 | 14 | float grid(vec2 uv, float battery) 15 | { 16 | vec2 size = vec2(uv.y, uv.y * uv.y * 0.2) * 0.01; 17 | uv += vec2(0.0, iTime * 4.0 * (battery + 0.05)); 18 | uv = abs(fract(uv) - 0.5); 19 | vec2 lines = smoothstep(size, vec2(0.0), uv); 20 | lines += smoothstep(size * 5.0, vec2(0.0), uv) * 0.4 * battery; 21 | return clamp(lines.x + lines.y, 0.0, 3.0); 22 | } 23 | 24 | float dot2(in vec2 v ) { return dot(v,v); } 25 | 26 | float sdTrapezoid( in vec2 p, in float r1, float r2, float he ) 27 | { 28 | vec2 k1 = vec2(r2,he); 29 | vec2 k2 = vec2(r2-r1,2.0*he); 30 | p.x = abs(p.x); 31 | vec2 ca = vec2(p.x-min(p.x,(p.y<0.0)?r1:r2), abs(p.y)-he); 32 | vec2 cb = p - k1 + k2*clamp( dot(k1-p,k2)/dot2(k2), 0.0, 1.0 ); 33 | float s = (cb.x<0.0 && ca.y<0.0) ? -1.0 : 1.0; 34 | return s*sqrt( min(dot2(ca),dot2(cb)) ); 35 | } 36 | 37 | float sdLine( in vec2 p, in vec2 a, in vec2 b ) 38 | { 39 | vec2 pa = p-a, ba = b-a; 40 | float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); 41 | return length( pa - ba*h ); 42 | } 43 | 44 | float sdBox( in vec2 p, in vec2 b ) 45 | { 46 | vec2 d = abs(p)-b; 47 | return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0); 48 | } 49 | 50 | float opSmoothUnion(float d1, float d2, float k){ 51 | float h = clamp(0.5 + 0.5 * (d2 - d1) /k,0.0,1.0); 52 | return mix(d2, d1 , h) - k * h * ( 1.0 - h); 53 | } 54 | 55 | float sdCloud(in vec2 p, in vec2 a1, in vec2 b1, in vec2 a2, in vec2 b2, float w) 56 | { 57 | //float lineVal1 = smoothstep(w - 0.0001, w, sdLine(p, a1, b1)); 58 | float lineVal1 = sdLine(p, a1, b1); 59 | float lineVal2 = sdLine(p, a2, b2); 60 | vec2 ww = vec2(w*1.5, 0.0); 61 | vec2 left = max(a1 + ww, a2 + ww); 62 | vec2 right = min(b1 - ww, b2 - ww); 63 | vec2 boxCenter = (left + right) * 0.5; 64 | //float boxW = right.x - left.x; 65 | float boxH = abs(a2.y - a1.y) * 0.5; 66 | //float boxVal = sdBox(p - boxCenter, vec2(boxW, boxH)) + w; 67 | float boxVal = sdBox(p - boxCenter, vec2(0.04, boxH)) + w; 68 | 69 | float uniVal1 = opSmoothUnion(lineVal1, boxVal, 0.05); 70 | float uniVal2 = opSmoothUnion(lineVal2, boxVal, 0.05); 71 | 72 | return min(uniVal1, uniVal2); 73 | } 74 | 75 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 76 | { 77 | vec2 uv = (2.0 * fragCoord.xy - iResolution.xy)/iResolution.y; 78 | float battery = 1.0; 79 | //if (iMouse.x > 1.0 && iMouse.y > 1.0) battery = iMouse.y / iResolution.y; 80 | //else battery = 0.8; 81 | 82 | //if (abs(uv.x) < (9.0 / 16.0)) 83 | { 84 | // Grid 85 | float fog = smoothstep(0.1, -0.02, abs(uv.y + 0.2)); 86 | vec3 col = vec3(0.0, 0.1, 0.2); 87 | if (uv.y < -0.2) 88 | { 89 | uv.y = 3.0 / (abs(uv.y + 0.2) + 0.05); 90 | uv.x *= uv.y * 1.0; 91 | float gridVal = grid(uv, battery); 92 | col = mix(col, vec3(1.0, 0.5, 1.0), gridVal); 93 | } 94 | else 95 | { 96 | float fujiD = min(uv.y * 4.5 - 0.5, 1.0); 97 | uv.y -= battery * 1.1 - 0.51; 98 | 99 | vec2 sunUV = uv; 100 | vec2 fujiUV = uv; 101 | 102 | // Sun 103 | sunUV += vec2(0.75, 0.2); 104 | //uv.y -= 1.1 - 0.51; 105 | col = vec3(1.0, 0.2, 1.0); 106 | float sunVal = sun(sunUV, battery); 107 | 108 | col = mix(col, vec3(1.0, 0.4, 0.1), sunUV.y * 2.0 + 0.2); 109 | col = mix(vec3(0.0, 0.0, 0.0), col, sunVal); 110 | 111 | // fuji 112 | float fujiVal = sdTrapezoid( uv + vec2(-0.75+sunUV.y * 0.0, 0.5), 1.75 + pow(uv.y * uv.y, 2.1), 0.2, 0.5); 113 | float waveVal = uv.y + sin(uv.x * 20.0 + iTime * 2.0) * 0.05 + 0.2; 114 | float wave_width = smoothstep(0.0,0.01,(waveVal)); 115 | 116 | // fuji color 117 | col = mix( col, mix(vec3(0.0, 0.0, 0.25), vec3(1.0, 0.0, 0.5), fujiD), step(fujiVal, 0.0)); 118 | // fuji top snow 119 | col = mix( col, vec3(1.0, 0.5, 1.0), wave_width * step(fujiVal, 0.0)); 120 | // fuji outline 121 | col = mix( col, vec3(1.0, 0.5, 1.0), 1.0-smoothstep(0.0,0.01,abs(fujiVal)) ); 122 | //col = mix( col, vec3(1.0, 1.0, 1.0), 1.0-smoothstep(0.03,0.04,abs(fujiVal)) ); 123 | //col = vec3(1.0, 1.0, 1.0) *(1.0-smoothstep(0.03,0.04,abs(fujiVal))); 124 | 125 | // horizon color 126 | col += mix( col, mix(vec3(1.0, 0.12, 0.8), vec3(0.0, 0.0, 0.2), clamp(uv.y * 3.5 + 3.0, 0.0, 1.0)), step(0.0, fujiVal) ); 127 | 128 | // cloud 129 | vec2 cloudUV = uv; 130 | cloudUV.x = mod(cloudUV.x + iTime * 0.1, 4.0) - 2.0; 131 | float cloudTime = iTime * 0.5; 132 | float cloudY = -0.5; 133 | float cloudVal1 = sdCloud(cloudUV, 134 | vec2(0.1 + sin(cloudTime + 140.5)*0.1,cloudY), 135 | vec2(1.05 + cos(cloudTime * 0.9 - 36.56) * 0.1, cloudY), 136 | vec2(0.2 + cos(cloudTime * 0.867 + 387.165) * 0.1,0.25+cloudY), 137 | vec2(0.5 + cos(cloudTime * 0.9675 - 15.162) * 0.09, 0.25+cloudY), 0.075); 138 | cloudY = -0.6; 139 | float cloudVal2 = sdCloud(cloudUV, 140 | vec2(-0.9 + cos(cloudTime * 1.02 + 541.75) * 0.1,cloudY), 141 | vec2(-0.5 + sin(cloudTime * 0.9 - 316.56) * 0.1, cloudY), 142 | vec2(-1.5 + cos(cloudTime * 0.867 + 37.165) * 0.1,0.25+cloudY), 143 | vec2(-0.6 + sin(cloudTime * 0.9675 + 665.162) * 0.09, 0.25+cloudY), 0.075); 144 | 145 | float cloudVal = min(cloudVal1, cloudVal2); 146 | 147 | //col = mix(col, vec3(1.0,1.0,0.0), smoothstep(0.0751, 0.075, cloudVal)); 148 | col = mix(col, vec3(0.0, 0.0, 0.2), 1.0 - smoothstep(0.075 - 0.0001, 0.075, cloudVal)); 149 | col += vec3(1.0, 1.0, 1.0)*(1.0 - smoothstep(0.0,0.01,abs(cloudVal - 0.075))); 150 | } 151 | 152 | col += fog * fog * fog; 153 | col = mix(vec3(col.r, col.r, col.r) * 0.5, col, battery * 0.7); 154 | 155 | fragColor = vec4(col,1.0); 156 | } 157 | //else fragColor = vec4(0.0); 158 | 159 | 160 | } 161 | -------------------------------------------------------------------------------- /examples/surveillance_mosaic.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/7tjSWy 2 | // Created by https://www.shadertoy.com/user/felipetovarhenao 3 | 4 | /* 5 | Author: Felipe Tovar-Henao [www.felipe-tovar-henao.com] 6 | Description: Animated eye mosaic using value noise, and shaping functions. 7 | */ 8 | 9 | #define PI 3.14159265359 10 | #define TWO_PI 6.28318530718 11 | #define edge 0.005 12 | 13 | 14 | /* -------- SHAPERS/MISC -------- */ 15 | float fold(in float x) { 16 | return abs(mod(x+1.0,2.0)-1.0); 17 | } 18 | 19 | float reliRamp(in float x, in float s) { 20 | return floor(x) + clamp((max(1.0, s)*(fract(x) - 0.5)) + 0.5, 0.0, 1.0); 21 | } 22 | 23 | float cosine_ramp(in float x, in float s) { 24 | float y = cos(fract(x)*3.14159265359); 25 | return floor(x) + 0.5 - (0.5*pow(abs(y), 1.0/s)*sign(y)); 26 | } 27 | float camel_ramp(in float x, in float s) { 28 | float y = fract(x); 29 | return floor(x) + pow(0.5 - (0.5 * cos(6.28318530718*y) * cos(3.14159265359*y)), s); 30 | } 31 | 32 | vec2 rotate2D(in vec2 vUV, in float theta) { 33 | return vUV * mat2(cos(theta), -sin(theta), sin(theta), cos(theta)); 34 | } 35 | 36 | float scale(in float x, in float inmin, in float inmax, in float outmin, in float outmax) { 37 | return ((x-inmin)/(inmax-inmin))*(outmax-outmin)+outmin; 38 | } 39 | 40 | /* -------- NOISE -------- */ 41 | float random1D(in vec2 vUV, in int seed) { 42 | return fract(abs(sin(dot(vUV, vec2(11.13, 57.05)) + float(seed)) * 48240.41)); 43 | } 44 | 45 | float value_noise(in vec2 vUV, in int seed) { 46 | vec2 x = floor(vUV); 47 | vec2 m = fract(vUV); 48 | 49 | float bl = random1D(x, seed); 50 | float br = random1D(x + vec2(1.0, 0.0), seed); 51 | float tl = random1D(x + vec2(0.0, 1.0), seed); 52 | float tr = random1D(x + vec2(1.0, 1.0), seed); 53 | 54 | vec2 cf = smoothstep(vec2(0.0), vec2(1.0), m); 55 | 56 | float tm = mix(tl, tr, cf.x); 57 | float bm = mix(bl, br, cf.x); 58 | 59 | return mix(bm, tm, cf.y); 60 | } 61 | 62 | /* -------- EYE FUNCTIONS -------- */ 63 | float eyeSDF(in vec2 vUV, in float s) { 64 | float o = 0.125; 65 | vec2 uv = abs(vUV*vec2(1. + o, 1.0)); 66 | float x = clamp(uv.x*(1.-o),0.0,0.5); 67 | uv -= vec2(0.5, pow(cos(x*PI)/s, s)); 68 | return length(max(vec2(0.0), uv)) + min(0.0, max(uv.x, uv.y)); 69 | } 70 | 71 | vec4 mk_tearduct(in float sdf, in float t) { 72 | vec3 col = mix(vec3(0.0, 0.0, 0.0), vec3(0.8471, 0.8471, 0.8471), cosine_ramp(fold(sdf*60.0 + t*0.25), 2.0)); 73 | float a = smoothstep(edge, 0.0, sdf+edge); 74 | return vec4(col, a); 75 | } 76 | 77 | vec4 mk_eyelids(in float sdf) { 78 | return smoothstep(edge*2.0, 0.0, abs(sdf)-0.01) * vec4(0.6471, 0.6471, 0.6471, 1.0); 79 | } 80 | 81 | vec4 mk_sclera(in vec2 vUV, in float d, in float t) { 82 | float g = rotate2D(vUV, length(vUV)*TWO_PI*sin(t*0.1) + t*0.01).y; 83 | vec3 glow = smoothstep(edge, 0.0, g) * vec3(1.0); 84 | vec4 sclera = smoothstep(edge, 0.0, d-0.25) * vec4(0.8275, 0.8235, 0.8235, 1.0); 85 | vec4 border = smoothstep(edge, 0.0, abs(d-0.25)-0.0025) * vec4(0.2549, 0.2549, 0.2549, 1.0); 86 | sclera.rgb = mix(sclera.rgb, glow, glow.r); 87 | sclera = mix(sclera, border, border.a); 88 | return sclera; 89 | } 90 | 91 | vec4 mk_iris(in vec2 vUV, in float d, in float t) { 92 | float a = atan(vUV.x, vUV.y); 93 | vec3 col = mix(vec3(0.6784, 0.7922, 0.8431), vec3(0.6118, 0.7255, 0.7804), fold(cosine_ramp(sin(a*3.0*cos(a*2.0)+t*0.5), 4.0))); 94 | col = mix(col, vec3(0.7765, 0.8196, 0.8392), cosine_ramp(cos(3.0*a*sin(-a*1.5) + t*0.4)* 0.5 + 0.5, 4.0)); 95 | vec4 iris = smoothstep(edge, 0.0, d-0.125) * vec4(col, 1.0); 96 | vec4 border = smoothstep(edge, 0.0, abs(d-0.125)-0.002) * vec4(0.2627, 0.2353, 0.2353, 1.0); 97 | 98 | float shade = cos(a+t*0.25)*0.5+0.5; 99 | shade *= shade; 100 | shade = cosine_ramp(shade, 4.0); 101 | iris = mix(iris, border, border.a); 102 | iris.rgb = mix(iris.rgb, vec3(0.3529, 0.4627, 0.4941), shade*0.75); 103 | 104 | return iris; 105 | } 106 | 107 | vec4 mk_pupil(in float d, in float t) { 108 | t = sin(d+t*0.125)*0.01; 109 | return smoothstep(edge, 0.0, d-0.05+t) * vec4(0.0627, 0.0588, 0.0588, 1.0); 110 | } 111 | 112 | vec4 mk_glow(in vec2 vUV, in float t) { 113 | float d = length(vUV); 114 | vUV *= vec2(sin(d*2.123 - t*0.798347), cos(d*3.123 + t*0.91823))*0.1 + 1.0; 115 | d = length((vUV-(vUV.y*0.1))-0.05); 116 | 117 | vec4 glow = smoothstep(edge*1.5, 0.0, d-0.03) * vec4(1.0); 118 | 119 | d = length((vUV-(vUV.y*0.1))+0.05); 120 | glow = mix(glow, smoothstep(edge*1.25, 0.0, d-0.02) * vec4(1.0), 1.0-glow.a); 121 | 122 | return glow; 123 | } 124 | 125 | vec4 mk_retina(in vec2 vUV, in float t) { 126 | vec4 retina = vec4(0.0); 127 | vUV *= length(vUV)*1.5+1.0; 128 | vUV += vec2(cos(t*0.98), sin(t*0.234))*0.08; 129 | float d = length(vUV); 130 | vec4 glow = mk_glow(vUV, t); 131 | vec4 iris = mk_iris(vUV, d, t);; 132 | vec4 pupil = mk_pupil(d+sin(t*0.5 + 0.12)*0.005, t); 133 | 134 | retina = mix(retina, iris, iris.a); 135 | retina = mix(retina, pupil, pupil.a*retina.a); 136 | retina = mix(retina, glow, glow.a*0.975*iris.a); 137 | 138 | return retina; 139 | } 140 | 141 | vec4 mk_eyeball(in vec2 vUV, in float t) { 142 | float d = length(vUV); 143 | vec4 eyeball = vec4(0.0); 144 | vec4 sclera = mk_sclera(vUV, d, t); 145 | vec4 retina = mk_retina(vUV, t + reliRamp(t, 2.0)); 146 | 147 | eyeball = mix(eyeball, sclera, sclera.a); 148 | eyeball = mix(eyeball, retina, retina.a*sclera.a); 149 | 150 | return eyeball; 151 | } 152 | 153 | vec4 mk_eye(in vec2 vUV, in float b, in float t) { 154 | vec4 eye = vec4(0.0); 155 | float eye_sdf = eyeSDF(vUV*1.06, b); 156 | vec4 tearduct = mk_tearduct(eye_sdf, t); 157 | vec4 eyelids = mk_eyelids(eye_sdf); 158 | vec4 eyeball = mk_eyeball(vUV, t); 159 | 160 | eye = mix(eye, tearduct, tearduct.a); 161 | eye = mix(eye, eyeball, eyeball.a*tearduct.a); 162 | eye = mix(eye, eyelids, eyelids.a); 163 | 164 | return vec4(eye); 165 | } 166 | 167 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 168 | { 169 | vec2 vUV = fragCoord.xy / iResolution.xy; 170 | vUV.x *= iResolution.x / iResolution.y; 171 | float scl = 1.75; 172 | vec2 pUV = vUV * scl + vec2(iTime * 0.01, iTime * -0.0107); 173 | vec4 color = vec4(0.0); 174 | float sdf = 1.0; 175 | 176 | for (float i = 0.0; i <= 1.0; i ++) { 177 | vUV = pUV + 7.5*(1.0-i); 178 | vec2 iUV = floor(vUV); 179 | vUV = fract(vUV)-0.5; 180 | float rand = value_noise(iUV, int(vUV.x*vUV.y)); 181 | float t = (iTime + 100.0*(i+0.5)) * (rand + 1.0); 182 | vUV = rotate2D(vUV, t*0.01); 183 | float b = scale(pow(fold(t * 0.1), 100.0), 0.0, 1.0, 2.0, 10.0); 184 | vec4 eye = mk_eye(vUV*pow(2.0, rand), b, t * 0.5); 185 | sdf = min(sdf, eyeSDF(vUV*scl, b)); 186 | color = mix(color, eye, eye.a); 187 | } 188 | 189 | sdf = camel_ramp(fold(sdf*(16. + sin(iTime*0.25)*2.0) - iTime*0.1), 1.0); 190 | sdf *= sdf; 191 | color = mix(color, sdf*vec4(0.6824, 0.6824, 0.6824, 1.0), sdf*(1.0-color.a)); 192 | fragColor = color; 193 | } 194 | -------------------------------------------------------------------------------- /examples/lonely_waters.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/NlKGWK 2 | // Created by https://www.shadertoy.com/user/Tater 3 | 4 | //Set to 2.0 for AA 5 | #define AA 1.0 6 | 7 | #define STEPS 80.0 8 | #define MDIST 35.0 9 | #define pi 3.1415926535 10 | #define rot(a) mat2(cos(a),sin(a),-sin(a),cos(a)) 11 | #define sat(a) clamp(a,0.0,1.0) 12 | 13 | #define ITERS_TRACE 9 14 | #define ITERS_NORM 20 15 | 16 | #define HOR_SCALE 1.1 17 | #define OCC_SPEED 1.4 18 | #define DX_DET 0.65 19 | 20 | #define FREQ 0.6 21 | #define HEIGHT_DIV 2.5 22 | #define WEIGHT_SCL 0.8 23 | #define FREQ_SCL 1.2 24 | #define TIME_SCL 1.095 25 | #define WAV_ROT 1.21 26 | #define DRAG 0.9 27 | #define SCRL_SPEED 1.5 28 | vec2 scrollDir = vec2(1,1); 29 | 30 | 31 | //Built with some ideas from 32 | //https://www.shadertoy.com/view/wldBRf 33 | //https://www.shadertoy.com/view/ssG3Wt 34 | //https://www.shadertoy.com/view/4dBcRD 35 | //https://www.shadertoy.com/view/Xdlczl 36 | vec2 wavedx(vec2 wavPos, int iters, float t){ 37 | vec2 dx = vec2(0); 38 | vec2 wavDir = vec2(1,0); 39 | float wavWeight = 1.0; 40 | wavPos+= t*SCRL_SPEED*scrollDir; 41 | wavPos*= HOR_SCALE; 42 | float wavFreq = FREQ; 43 | float wavTime = OCC_SPEED*t; 44 | for(int i=0;i0.) foam+=result*0.3; 49 | result*=wavWeight; 50 | dx+= result*wavDir/pow(wavWeight,DX_DET); 51 | wavFreq*= FREQ_SCL; 52 | wavTime*= TIME_SCL; 53 | wavPos-= wavDir*result*DRAG; 54 | wavWeight*= WEIGHT_SCL; 55 | } 56 | float wavSum = -(pow(WEIGHT_SCL,float(iters))-1.)*HEIGHT_DIV; 57 | return dx/pow(wavSum,1.-DX_DET); 58 | } 59 | 60 | float wave(vec2 wavPos, int iters, float t){ 61 | float wav = 0.0; 62 | vec2 wavDir = vec2(1,0); 63 | float wavWeight = 1.0; 64 | wavPos+= t*SCRL_SPEED*scrollDir; 65 | wavPos*= HOR_SCALE; 66 | float wavFreq = FREQ; 67 | float wavTime = OCC_SPEED*t; 68 | for(int i=0;i10.;s*=0.8){ 131 | p.xz*=rot(s); 132 | p+=s; 133 | e+=abs(dot(sin(p*s+iTime*0.02)/s,vec3(1.65))); 134 | } 135 | e*=smoothstep(0.5,0.4,e-0.095); 136 | 137 | col += (e)*smoothstep(-0.02,0.3,rdo.y)*0.8*(1.0-sun*3.75)*mix(sc,vec3(1),0.4); 138 | 139 | return (col); 140 | } 141 | void render( out vec4 fragColor, in vec2 fragCoord ){ 142 | vec2 uv = (fragCoord-0.5*iResolution.xy)/min(iResolution.y,iResolution.x); 143 | vec3 col = vec3(0); 144 | vec3 ro = vec3(0,2.25,-3)*1.1; 145 | bool click = iMouse.z>0.; 146 | if(click){ 147 | ro.yz*=rot(2.0*min(iMouse.y/iResolution.y-0.5,0.15)); 148 | ro.zx*=rot(-7.0*(iMouse.x/iResolution.x-0.5)); 149 | } 150 | vec3 lk = vec3(0,2,0); 151 | vec3 f = normalize(lk-ro); 152 | vec3 r = normalize(cross(vec3(0,1,0),f)); 153 | vec3 rd = normalize(f*(0.9)+uv.x*r+uv.y*cross(f,r)); 154 | 155 | float dO = 0.; 156 | bool hit = false; 157 | float d = 0.; 158 | vec3 p = ro; 159 | 160 | float tPln = -(ro.y-1.86)/rd.y; 161 | if(tPln>0.||click){ 162 | if(!click)dO+=tPln; 163 | for(float i = 0.; iSTEPS-2.0){ 166 | hit = true; 167 | break; 168 | } 169 | if(dO>MDIST){ 170 | dO = MDIST; 171 | break; 172 | } 173 | } 174 | } 175 | vec3 skyrd = sky(rd); 176 | if(hit){ 177 | vec3 n = norm(p); 178 | vec3 rfl = reflect(rd,n); 179 | rfl.y = abs(rfl.y); 180 | vec3 rf = refract(rd,n,1./1.33); 181 | vec3 sd = normalize(vec3(0,0.3,-1.0)); 182 | float fres = clamp((pow(1. - max(0.0, dot(-n, rd)), 5.0)),0.0,1.0); 183 | 184 | vec3 sunDir = vec3(0,0.15,1.0); 185 | sunDir.xz*=rot(-sunrot.x); 186 | col += sky(rfl)*fres*0.9; 187 | float subRefract =pow(max(0.0, dot(rf,sunDir)),35.0); 188 | //This effect is exaggerated much more than is realistic because I like it :) 189 | col += pow(spc(spec-0.1,0.5),vec3(2.2))*subRefract*2.5; 190 | vec3 rd2 = rd; 191 | rd2.xz*=rot(sunrot.x); 192 | vec3 waterCol = min(sat(spc(spec-0.1,0.4))*0.05*pow(min(p.y+0.5,1.8),4.0)*length(skyrd)*(rd2.z*0.3+0.7),1.0); 193 | 194 | waterCol = sat(spc(spec-0.1,0.4))*(0.4*pow(min(p.y*0.7+0.9,1.8),4.)*length(skyrd)*(rd2.z*0.15+0.85)); 195 | col += waterCol*0.17; 196 | //col+=smoothstep(0.95,1.55,wave(p.xz,25,iTime))*mix(waterCol*0.3,vec3(1),0.2)*0.2; 197 | 198 | col = mix(col,skyrd,dO/MDIST); 199 | } 200 | else{ 201 | col += skyrd; 202 | } 203 | col = sat(col); 204 | col = pow(col,vec3(0.87)); 205 | col *=1.0-0.8*pow(length(uv*vec2(0.8,1.)),2.7); 206 | fragColor = vec4(col,1.0); 207 | 208 | } 209 | 210 | #define ZERO min(0.0,iTime) 211 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 212 | { 213 | float px = 1.0/AA; 214 | vec4 col = vec4(0); 215 | 216 | if(AA==1.0) {render(col,fragCoord); fragColor = col; return;} 217 | 218 | for(float i = ZERO; i 0.0) { 167 | color = getBackgroundColor(dir); 168 | } else { 169 | // project the starting position to z = 0 so we ccan lower the raymarch count 170 | float totdist = from.z / -dir.z; 171 | for (int steps = 0 ; steps < STEPS ; steps++) { 172 | vec3 p = from + totdist * dir; 173 | vec3 projClosest; 174 | vec3 projSecondClosest; 175 | p.x -= iTime * 2.7; 176 | float dist = de(p, projClosest, projSecondClosest); 177 | totdist += dist; 178 | if ( dist < 0.01 || steps == STEPS-1 ) { 179 | color = getWaveColor(p, projClosest, projSecondClosest, 180 | dir, totdist, fragCoord); 181 | break; 182 | } 183 | } 184 | } 185 | 186 | fragColor = vec4(color, 1); 187 | 188 | } 189 | 190 | -------------------------------------------------------------------------------- /examples/torus_loop.glsl: -------------------------------------------------------------------------------- 1 | // Copied from https://www.shadertoy.com/view/ctlXzN 2 | // Created by https://www.shadertoy.com/user/mrange 3 | 4 | // CC0: Torus loop 5 | // Saw some sweet twitter art again with torus that kept folding in on itself 6 | // Tried something similar 7 | 8 | #define TIME iTime 9 | #define RESOLUTION iResolution 10 | 11 | #define PI 3.141592654 12 | #define TAU (2.0*PI) 13 | 14 | #define TOLERANCE 0.0001 15 | #define MAX_RAY_LENGTH 22.0 16 | #define MAX_RAY_MARCHES 60 17 | #define NORM_OFF 0.001 18 | #define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a)) 19 | 20 | // License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488 21 | const vec4 hsv2rgb_K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 22 | vec3 hsv2rgb(vec3 c) { 23 | vec3 p = abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www); 24 | return c.z * mix(hsv2rgb_K.xxx, clamp(p - hsv2rgb_K.xxx, 0.0, 1.0), c.y); 25 | } 26 | // License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488 27 | // Macro version of above to enable compile-time constants 28 | #define HSV2RGB(c) (c.z * mix(hsv2rgb_K.xxx, clamp(abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www) - hsv2rgb_K.xxx, 0.0, 1.0), c.y)) 29 | 30 | const float hoff = 0.0; 31 | const vec3 skyCol = HSV2RGB(vec3(hoff+0.57, 0.70, 0.25)); 32 | const vec3 glowCol = HSV2RGB(vec3(hoff+0.025, 0.85, 0.5)); 33 | const vec3 sunCol1 = HSV2RGB(vec3(hoff+0.60, 0.50, 0.5)); 34 | const vec3 sunCol2 = HSV2RGB(vec3(hoff+0.05, 0.75, 25.0)); 35 | const vec3 diffCol = HSV2RGB(vec3(hoff+0.60, 0.75, 0.25)); 36 | const vec3 sunDir1 = normalize(vec3(3., 3.0, -7.0)); 37 | 38 | mat3 g_rot ; 39 | float g_anim ; 40 | mat2 g_rot_yx; 41 | mat2 g_rot_xz; 42 | 43 | // License: Unknown, author: nmz (twitter: @stormoid), found: https://www.shadertoy.com/view/NdfyRM 44 | vec3 sRGB(vec3 t) { 45 | return mix(1.055*pow(t, vec3(1./2.4)) - 0.055, 12.92*t, step(t, vec3(0.0031308))); 46 | } 47 | 48 | // License: Unknown, author: Matt Taylor (https://github.com/64), found: https://64.github.io/tonemapping/ 49 | vec3 aces_approx(vec3 v) { 50 | v = max(v, 0.0); 51 | v *= 0.6f; 52 | float a = 2.51f; 53 | float b = 0.03f; 54 | float c = 2.43f; 55 | float d = 0.59f; 56 | float e = 0.14f; 57 | return clamp((v*(a*v+b))/(v*(c*v+d)+e), 0.0f, 1.0f); 58 | } 59 | 60 | mat3 rot_z(float a) { 61 | float c = cos(a); 62 | float s = sin(a); 63 | return mat3( 64 | c,s,0 65 | ,-s,c,0 66 | , 0,0,1 67 | ); 68 | } 69 | 70 | mat3 rot_y(float a) { 71 | float c = cos(a); 72 | float s = sin(a); 73 | return mat3( 74 | c,0,s 75 | , 0,1,0 76 | ,-s,0,c 77 | ); 78 | } 79 | 80 | mat3 rot_x(float a) { 81 | float c = cos(a); 82 | float s = sin(a); 83 | return mat3( 84 | 1, 0,0 85 | , 0, c,s 86 | , 0,-s,c 87 | ); 88 | } 89 | 90 | // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/distfunctions/ 91 | float rayPlane(vec3 ro, vec3 rd, vec4 p) { 92 | return -(dot(ro,p.xyz)+p.w)/dot(rd,p.xyz); 93 | } 94 | 95 | // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm 96 | float box(vec2 p, vec2 b) { 97 | vec2 d = abs(p)-b; 98 | return length(max(d,0.0)) + min(max(d.x,d.y),0.0); 99 | } 100 | 101 | // License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/distfunctions/ 102 | float torus(vec3 p, vec2 t) { 103 | vec2 q = vec2(length(p.xz)-t.x,p.y); 104 | return length(q)-t.y; 105 | } 106 | 107 | float df(vec3 p) { 108 | const float zz = 6.0; 109 | 110 | const float r0 = 2.0-0.5; 111 | const float r1 = r0/zz; 112 | const float r2 = r1/zz; 113 | const float r3 = r2/zz; 114 | 115 | float anim = g_anim; 116 | float angle = anim*PI; 117 | float z = mix(zz, 1.0, anim); 118 | 119 | vec3 p0 = p; 120 | p0 *= g_rot; 121 | p0.yz *= g_rot_yx; 122 | p0.x -= mix(r0*zz, 0.0, anim); 123 | p0 /= z; 124 | 125 | vec3 p1 = p0; 126 | 127 | p1.z = abs(p1.z); 128 | p1.xz *= g_rot_xz; 129 | 130 | vec3 p2 = p1; 131 | p2.z = abs(p2.z); 132 | p2.z -= r0; 133 | p2 = p2.zxy; 134 | 135 | vec3 p3 = p0; 136 | 137 | float rr = mix(r3, 0.0, anim); 138 | float d0 = torus(p0, vec2(r0, r1+rr)); 139 | d0 = abs(d0) - r2; 140 | float d1 = p1.x; 141 | float d2 = torus(p2, vec2(r1, r2+rr)); 142 | float d3 = p3.x; 143 | 144 | float d = d0; 145 | d = max(d, d1); 146 | d = min(d, d2); 147 | if (angle < PI/4.0) d = max(d, d3); 148 | if (angle > (TAU-PI/4.0)) d = max(d, -d3); 149 | return d*z; 150 | } 151 | 152 | vec3 normal(vec3 pos) { 153 | vec2 eps = vec2(NORM_OFF,0.0); 154 | vec3 nor; 155 | nor.x = df(pos+eps.xyy) - df(pos-eps.xyy); 156 | nor.y = df(pos+eps.yxy) - df(pos-eps.yxy); 157 | nor.z = df(pos+eps.yyx) - df(pos-eps.yyx); 158 | return normalize(nor); 159 | } 160 | 161 | float rayMarch(vec3 ro, vec3 rd, out vec3 gcol) { 162 | float t = 0.0; 163 | const float tol = TOLERANCE; 164 | vec2 dti = vec2(1e10,0.0); 165 | int i = 0; 166 | vec3 gc = vec3(0.0); 167 | for (i = 0; i < MAX_RAY_MARCHES; ++i) { 168 | float d = df(ro + rd*t); 169 | gc += (0.0125*glowCol)/d; 170 | if (d MAX_RAY_LENGTH) { 172 | break; 173 | } 174 | t += d; 175 | } 176 | gcol = gc; 177 | if(i==MAX_RAY_MARCHES) { t=dti.y; }; 178 | return t; 179 | } 180 | 181 | vec3 render0(vec3 ro, vec3 rd) { 182 | vec3 col = vec3(0.0); 183 | float sd = max(dot(sunDir1, rd), 0.0); 184 | float sf = 1.0001-sd; 185 | col += clamp(vec3(0.0025/abs(rd.y))*glowCol, 0.0, 1.0); 186 | col += 0.75*skyCol*pow((1.0-abs(rd.y)), 8.0); 187 | col += 2.0*sunCol1*pow(sd, 100.0); 188 | col += sunCol2*pow(sd, 800.0); 189 | 190 | float tp1 = rayPlane(ro, rd, vec4(vec3(0.0, -1.0, 0.0), -6.0)); 191 | 192 | if (tp1 > 0.0) { 193 | vec3 pos = ro + tp1*rd; 194 | vec2 pp = pos.xz; 195 | float db = box(pp, vec2(5.0, 9.0))-3.0; 196 | 197 | col += vec3(4.0)*skyCol*rd.y*rd.y*smoothstep(0.25, 0.0, db); 198 | col += vec3(0.8)*skyCol*exp(-0.5*max(db, 0.0)); 199 | col += 0.25*sqrt(skyCol)*max(-db, 0.0); 200 | } 201 | 202 | return clamp(col, 0.0, 10.0);; 203 | } 204 | 205 | vec3 render1(vec3 ro, vec3 rd) { 206 | vec3 gcol; 207 | int iter; 208 | float t = rayMarch(ro, rd, gcol); 209 | vec3 col = render0(ro, rd); 210 | 211 | vec3 p = ro+rd*t; 212 | vec3 n = normal(p); 213 | vec3 r = reflect(rd, n); 214 | float fre = 1.0+dot(rd, n); 215 | fre *= fre; 216 | float dif = dot(sunDir1, n); 217 | 218 | if (t < MAX_RAY_LENGTH) { 219 | col = vec3(0.0); 220 | col += sunCol1*dif*dif*diffCol*0.25; 221 | col += mix(0.33, 1.0, fre)*render0(p, r); 222 | } else { 223 | col += gcol; 224 | } 225 | 226 | return col; 227 | } 228 | 229 | vec3 effect(vec2 p) { 230 | float tm = TIME*0.5+10.0; 231 | g_rot = rot_x(0.11*tm)*rot_y(0.23*tm)*rot_z(0.35*tm); 232 | g_anim = (0.5+0.5*sin(fract(0.1*TIME)*PI-PI/2.0)); 233 | g_rot_yx = ROT(g_anim*(PI*0.5)); 234 | g_rot_xz = ROT(PI/2.0-g_anim*PI); 235 | 236 | 237 | vec3 ro = 2.0*vec3(5.0, 1.0, 0.); 238 | ro.xz *= ROT(-0.1*tm); 239 | const vec3 la = vec3(0.0, 0.0, 0.0); 240 | const vec3 up = normalize(vec3(0.0, 1.0, 0.0)); 241 | 242 | vec3 ww = normalize(la - ro); 243 | vec3 uu = normalize(cross(up, ww )); 244 | vec3 vv = (cross(ww,uu)); 245 | const float fov = tan(TAU/6.); 246 | vec3 rd = normalize(-p.x*uu + p.y*vv + fov*ww); 247 | 248 | vec3 col = render1(ro, rd); 249 | 250 | return col; 251 | } 252 | 253 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) { 254 | vec2 q = fragCoord/iResolution.xy; 255 | vec2 p = -1. + 2. * q; 256 | vec2 pp = p; 257 | p.x *= RESOLUTION.x/RESOLUTION.y; 258 | vec3 col = vec3(0.0); 259 | col = effect(p); 260 | col *= smoothstep(1.5, 0.5, length(pp)); 261 | col = aces_approx(col); 262 | col = sRGB(col); 263 | fragColor = vec4(col, 1.0); 264 | } 265 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KMS GLSL 2 | 3 | KMS GLSL is a command line tool that runs OpenGL fragment shaders, using the [DRM/KMS Linux kernel subsystem](https://en.wikipedia.org/wiki/Direct_Rendering_Manager). 4 | It runs shaders fullscreen, and does not require any windowing system, like X or Wayland. 5 | 6 | It has initially been developed to run shaders from [Shadertoy](https://www.shadertoy.com), on the [Raspberry Pi](https://ttt.io/glsl-raspberry-pi). 7 | However, it works with any GPU and display controller hardware, provided a DRM/KMS driver is available, like on the [Jetson Nano](https://ttt.io/glsl-jetson-nano). 8 | Examples of configuration, where it's been reported to run successfully on, are listed in the [compatibility](#compatibility) section. 9 | 10 | In the following picture, this [Shadertoy shader](https://www.shadertoy.com/view/MsX3Wj) runs on the Raspberry Pi 4, connected to the official Raspberry Pi 7" touchscreen monitor, in WVGA resolution: 11 | 12 | ![A Shadertoy shader running on the Raspberry Pi 4](./raspberry_pi.jpg) 13 | 14 | [Another shader](https://www.shadertoy.com/view/fstyD4) that runs on the Jetson Nano in full HD resolution: 15 | 16 | ![A Shadertoy shader running on the Jetson Nano](./jetson_nano.jpg) 17 | 18 | ## Build 19 | 20 | You need to clone the project, and run the following commands: 21 | 22 | ```shell 23 | $ sudo apt update 24 | # Install the build tools 25 | $ sudo apt install gcc make 26 | # Install the required DRM, GBM, EGL and OpenGL ES API headers 27 | $ sudo apt install libdrm-dev libgbm-dev libegl-dev libgles2-mesa-dev 28 | # Install the X C binding and RandR extension header / library files (optional) 29 | $ sudo apt install libxcb-randr0-dev 30 | # Build the glsl binary and library 31 | $ make 32 | ``` 33 | 34 | ## Usage 35 | 36 | Once you've successfully built the binary / library, you can either run it directly, or use the Python wrapper, that adds a layer for managing shader inputs, that you can also extend to add your own custom inputs. 37 | 38 | ### Native 39 | 40 | ```console 41 | $ ./glsl -h 42 | Usage: ./glsl [-aACDfmnpvx] 43 | 44 | options: 45 | -a, --async use async page flipping 46 | -A, --atomic use atomic mode setting and fencing 47 | -C, --connector=ID use the connector with the provided ID (see drm_info) 48 | -D, --device=DEVICE use the given device 49 | -f, --format=FOURCC framebuffer format 50 | -h, --help print usage 51 | -m, --modifier=MODIFIER hardcode the selected modifier 52 | -n, --frames=N run for the given number of frames and exit 53 | -p, --perfcntr=LIST sample specified performance counters using 54 | the AMD_performance_monitor extension (comma 55 | separated list) 56 | -v, --vmode=VMODE specify the video mode in the format 57 | [-] 58 | -x, --surfaceless use surfaceless mode, instead of GBM surface 59 | ``` 60 | 61 | > [!NOTE] 62 | > [Shaders](https://www.shadertoy.com/howto#q1) from [Shadertoy](https://www.shadertoy.com/) are currently expected as input shader files. 63 | 64 | You can try it with the shaders available in the `examples` directory, e.g.: 65 | 66 | ```shell 67 | $ ./glsl examples/costal_landscape.glsl 68 | ``` 69 | 70 | Press Ctrl+c to exit the program. 71 | You can explore [shadertoy.com](https://www.shadertoy.com) to find additional shaders. 72 | Note the shaders from the `examples` directory assume OpenGL ES 3.1 support, and may not work with lower versions of the specification. 73 | 74 | No inputs can be provided using the native CLI directly. 75 | You can use the Python wrapper, that adds a layer around the native library for managing shader inputs, as explained below. 76 | 77 | ### Python 78 | 79 | ```console 80 | $ python glsl.py -h 81 | usage: glsl.py [-h] [--async-page-flip | --no-async-page-flip] 82 | [--atomic-drm-mode | --no-atomic-drm-mode] [-C CONNECTOR] 83 | [-D DEVICE] [--mode MODE] [-n N] [-k UNIFORM] 84 | [--touchscreen UNIFORM] [--trackpad UNIFORM] [-c UNIFORM FILE] 85 | [-t UNIFORM FILE] [-v UNIFORM FILE] [-m .KEY VALUE] 86 | FILE 87 | 88 | Run OpenGL shaders using DRM/KMS 89 | 90 | positional arguments: 91 | FILE the shader file 92 | 93 | options: 94 | -h, --help show this help message and exit 95 | --async-page-flip, --no-async-page-flip 96 | use async page flipping 97 | --atomic-drm-mode, --no-atomic-drm-mode 98 | use atomic mode setting and fencing 99 | -C CONNECTOR, --connector CONNECTOR 100 | the DRM connector 101 | -D DEVICE, --device DEVICE 102 | the DRM device 103 | --mode MODE specify the video mode in the format 104 | [-] 105 | -n N, --frames N run for the given number of frames and exit 106 | -k UNIFORM, --keyboard UNIFORM 107 | add keyboard 108 | --touchscreen UNIFORM 109 | add touchscreen device 110 | --trackpad UNIFORM add trackpad device 111 | -c UNIFORM FILE, --cubemap UNIFORM FILE 112 | add cubemap 113 | -t UNIFORM FILE, --texture UNIFORM FILE 114 | add texture 115 | -v UNIFORM FILE, --volume UNIFORM FILE 116 | add volume 117 | -m .KEY VALUE, --metadata .KEY VALUE 118 | set uniform metadata 119 | ``` 120 | 121 | > [!NOTE] 122 | > Python 3.10+ is required. 123 | 124 | You'll have to install the required dependencies once, e.g., with [venv](https://docs.python.org/3.10/library/venv.html): 125 | 126 | ```shell 127 | $ python -m venv .venv 128 | $ source .venv/bin/activate 129 | $ pip install libevdev pillow 130 | ``` 131 | 132 | You may also want to be in the `input` group, so `/dev/input/eventX` devices can be open to handle [evdev](https://docs.kernel.org/input/input.html#evdev) events, without running as root, e.g.: 133 | 134 | ```shell 135 | $ sudo adduser $USER input 136 | ``` 137 | 138 | You can then try it with the shaders available in the `examples` directory, e.g.: 139 | 140 | ```shell 141 | $ python glsl.py examples/plasma_globe.glsl -t iChannel0 presets/tex_RGBA_noise_medium.png 142 | ``` 143 | 144 | Press Ctrl+c to exit the program. 145 | You can explore [shadertoy.com](https://www.shadertoy.com) to find additional shaders. 146 | 147 | If you want to add your own inputs, you can find the documentation and some examples in the `glsl.py` file. 148 | 149 | ## Compatibility 150 | 151 | It's been reported to run successfully on the following configurations: 152 | 153 | | Hardware | OS / Kernel | Driver | Date | 154 | |---------------------------------------------|--------------------------------------------|-------------------------|---------| 155 | | NVIDIA GeForce RTX 3060 | Ubuntu 23.10, Linux 6.5 | NVIDIA Driver 545.29.06 | 03/2024 | 156 | | Jetson Orin NX | Jetson Linux 35.3.1, Linux 5.10 | NVIDIA DRM Driver | 09/2023 | 157 | | Jetson Nano (Tegra X1) | Jetson Linux 32.7.4, Linux 4.6 | Mesa NVIDIA Tegra | 06/2023 | 158 | | Raspberry Pi 4 (Broadcom VideoCore VI) | Raspberry Pi OS 2023-02, Linux 5.15 | Mesa VC4 V3D 19.3.2 | 09/2023 | 159 | | Raspberry Pi Zero W (Broadcom VideoCore IV) | Raspberry Pi OS 2022-09, Linux 5.15 | Mesa VC4 V3D 19.3.2 | 05/2023 | 160 | | Raspberry Pi 3B+ (Broadcom VideoCore IV) | Raspberry Pi OS Lite 2020-12, Linux 5.4.79 | Mesa VC4 V3D 19.3.2 | 08/2021 | 161 | 162 | ## Roadmap 163 | 164 | - Add support for texture buffers 165 | - Add support for audio / video inputs 166 | - Parse GLSL files to retrieve uniforms metadata 167 | 168 | ## Credits 169 | 170 | The DRM/KMS ceremony code is copied from [kmscube](https://gitlab.freedesktop.org/mesa/kmscube/). 171 | 172 | The shader examples are copied from the [Shadertoy](https://www.shadertoy.com) website URLs commented at the top of each file. 173 | --------------------------------------------------------------------------------