Skip to content

Instantly share code, notes, and snippets.

@bitnenfer
Last active February 10, 2019 23:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bitnenfer/266cae202738d3d0779ea007ac379b60 to your computer and use it in GitHub Desktop.
Save bitnenfer/266cae202738d3d0779ea007ac379b60 to your computer and use it in GitHub Desktop.
Commented code for the 2019 JS1K demo "X" (https://js1k.com/2019-x/demo/4039)
// This is the WebGL code:
// ======================
// GL function shortcuts taken from: http://xem.github.io/articles/archive.html#webgl_quest
for(i in g)g[i[0]+i[6]]=g[i];
// `with` helps us avoid doing g.xxx() and just do xxx()
with(g)
// Time variable.
T=0,
// ARRAY_BUFFER
k=34962,
// Create and set fragment and vertex shader source.
sS(v=cS(35633),"attribute vec2 v;void main(){gl_Position=vec4(v-1.,0,1);}"),
sS(f=cS(35632),"uniform float T;float m(vec3 m){vec3 f=m,v=m;float l=cos(.6),r=sin(.6);f.yx*=mat2(l,r,-r,l);v.yx*=mat2(l,-r,r,l);return min(min(min(length(max(abs(f)-vec3(.12,.8,.1),0.)),length(max(abs(v)-vec3(.12,.8,.1),0.)))-.1,m.y+.8),length(m)-.3);}void main(){vec3 l=vec3(0),f=normalize(vec3(gl_FragCoord.xy/512.-.5,1)),v=vec3(0,1,-3),r=vec3(.5);f.y-=.4;float i=cos(T),n=sin(T),k=1.;mat2 c=mat2(i,n,-n,i);vec2 d=vec2(0,.01);v.xz*=c;f.xz*=c;for(int x=0;x<4;++x){i=0.;for(int y=0;y<200;++y){float a=m(v+f*i);if(a<.001||i>9.)break;i+=a*.7;}if(i>9.)break;vec3 y=v+f*i,a=normalize(m(y)-vec3(m(y-d.yxx),m(y-d.xyx),m(y-d.xxy)));float g=1.,z=.01;for(int b=0;b<32;++b){float s=m(y+r*.01+r*z);if(s<.001){g=0.;break;}g=min(g,2.*s/z);z+=s;}l+=(vec3(1,.5,.4)*(mod(floor(y.x)+floor(y.z)+floor(y.y),2.)+.1)+pow(max(0.,g*dot(a,normalize(v+r))),32.))*max(g,.1)*k;f=reflect(f,a);v=y+f*.01;k*=.2;}gl_FragColor=vec4(pow(l,vec3(.4)),1);}"),
// Compile shaders
ce(v),
ce(f),
// Attach shaders and create program
aS(p=cP(),v),
aS(p,f),
// Link and use program
lo(p),
ug(p),
// Bind and allocate buffer. I use Int8Array because it's less characters
bf(k,cB(k)),
bD(k,Int8Array.of(0,0,0,6,6,0),35044),
// Enable vertex attribute and define vertex layout
eV(0),
vA(0,2,5120,0,2,0),
// Render loop
(x=()=>{
// Update Time variable and draw a fullscreen triangle.
uniform1f(gf(p,'T'),T+=.004),
dr(4,0,3),
// setTimeout has the less amount of characters to make a loop.
setTimeout(x)
})()
// The GLSL Code:
// =============
// Vertex Shader:
// =============
// attribute vec2 v;
// void main() {
// // Instead of having 2 '-' characters in out vbo allocation we do a single -1.0
// // to all vertex position components.
// gl_Position = vec4(v - 1.0, 0, 1);
// }
// Fragment Shader:
// ===============
// // Time
// uniform float T;
// // I mostly set this as a function because
// // I want to retreive the surface normal
// float map(vec3 v) {
// vec3 f=v,i=v;
// // First we rotate the two positions
// // that'll be used for the two boxes that form the X
// f.yx*=mat2(.8,.6,-.6,.8);
// i.yx*=mat2(.8,-.6,.6,.8);
//
// return min(
// min(
// min(
// length(max(abs(f)-vec3(.12,.8,.1),0.)), // The X
// length(max(abs(i)-vec3(.12,.8,.1),0.)) // The X
// )-.1, // Round the X border
// v.y+.8), // Floor
// length(v)-.3 // Center sphere
// );
// }
//
// void main() {
// vec3 f=vec3(0),
// x=vec3(gl_FragCoord.xy/512.-.5,1), // Ray Direction
// i=vec3(0,1,-3), // Ray Origin
// r=vec3(.5); // Light direction
//
// x.y-=.4;
// x=normalize(x);
// float t=cos(T),
// l=sin(T),
// z=1.;
//
// mat2 n=mat2(t,l,-l,t);
// vec2 d=vec2(0,.01);
//
// // Rotate the camera around the center
// // of the world using the Time variable
// i.xz*=n;
// x.xz*=n;
//
// // Iterate ray bounces
// for(int y=0;y<4;++y) {
// // Sphere tracing
// t=0.;
// for(int k=0;k<200;++k) {
// float d=map(i+x*t);
// if(d<.001||t>9.) break;
// t+=d;
// }
// if (t>9.)break;
// if (y==0) l=1.-t/7.; // save for iteration fog
//
// // Get surface position and surface normal
// vec3 c=i+x*t,
// e=normalize(map(c)-vec3(map(c-d.yxx),map(c-d.xyx),map(c-d.xxy)));
//
// // Implementation of IQ's soft shadowing
// float w=1.,q=.01;
// for(int i=0;i<32;++i) {
// float h = map((c+r*.01) + r*q);
// if(h<.001) {
// w = 0.;
// break;
// }
// w=min(w,2.*h/q);
// q += h;
// }
//
// f+= // Checker pattern
// (vec3(2,.8,.6)*(mod(floor(c.x)+floor(c.z)+floor(c.y),2.)+.1)
//
// // Specular reflection
// +pow(max(0.,w*dot(e,normalize(i+r))),32.))
//
// // Shadow contribution
// *max(w,.1)
//
// // Attenuation based on bounce iteration
// *z;
//
// // Reflect out ray direction by the surface normal
// x=reflect(x,e);
//
// // Set the new ray origin to the surface
// // position offset by epsilon times the ray direction
// i=c+x*.01;
//
// // Attenuation scale
// z*=.2;
// }
//
// // Kind of gamma correction and iteration fog
// gl_FragColor=vec4(pow(f*l,vec3(.4)),1);
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment