-
-
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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is 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