Skip to content

Instantly share code, notes, and snippets.

@yonatan
Last active April 3, 2021 20:20
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yonatan/77c0c0c11c86a10f49504c252638e0e6 to your computer and use it in GitHub Desktop.
Save yonatan/77c0c0c11c86a10f49504c252638e0e6 to your computer and use it in GitHub Desktop.
// This is Twigl's "geekest mode" so the code runs inside a "main" function.
// FC.xy is fragcoord
// r.xy is resolution
// t is time (in seconds I think)
// o.rgba is output color
// This is the original code, before any readability improvements:
/*
#define X(S,D)I=ivec3(S);D=fract(float(I.x^I.y^I.z)*PI
vec3 p;float d=1.,h,H;ivec3 I;for(;h<9.&&d>.9;){p=vec3((FC.xy-r)/r.y,1)*h+vec3(0,2,t);X(p*4.,H)*.9);d=p.y-pow(H,20.);h+=.01;}X(p*1e2,d)+t*.1);o.xyz=p*pow(d,1e2)+h/18.;
*/
// This hairy define takes a vec3 in S, converts to an int vector, xors the x, y and z components,
// converts back to float, multiplies by PI (to make the result a non-integer) and stores the
// fractional part in D.
// #define X(S,D)I=ivec3(S);D=fract(float(I.x^I.y^I.z)*PI
// Well, not exactly - it actually leaves off the last closing paren, so another value can be
// added (time) to animate the result.
// This is used twice. Once for the geometry, which is static, and once for the animated texture
// patterns (with time added). For the readable version I'll just expand it manually.
vec3 position;
vec3 ray_origin = vec3(0,2,t); // z moves forward with time
vec3 ray_direction = vec3((FC.xy-r)/r.y,1);
float ray_length = 0.;
float dist = 1.; // distance from geom (?)
float tmp; // temp var used for unpacking the #define
ivec3 tmp_int; // temp int vector for casting position to int
for(;ray_length < 9.;) { // if length > 9. give up (and paint the back wall)
position = ray_origin + ray_direction * ray_length;
// X(p*4.,H)*.9); // this expands to the version below.
tmp_int = ivec3(position*4.);
// I really don't know why the * .9 is in there... it made sense at the time I guess.
tmp = fract(float(tmp_int.x ^ tmp_int.y ^ tmp_int.z) * PI * .9);
// tmp is now between 0 and 1
float geom_height = pow(tmp, 20.); // raising it to a power makes the geometry sparser
dist = position.y - geom_height;
if(dist < .9) break; // we've hit the geometry
ray_length += .01; // march in a fixed step size
}
// X(p*1e2,d)+t*.1); // this expands to the version below.
tmp_int = ivec3(position * 1e2);
tmp = fract(float(tmp_int.x ^ tmp_int.y ^ tmp_int.z) * PI + t * .1); // t * .1 animates
float pattern_intensity = pow(tmp, 1e2); // again, raise it to a power for more sparseness
vec3 color = position * pattern_intensity; // color by position
float fog = ray_length / 18.; // more fog at the back (between 0 and .5)
o.rgb = color + fog;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment