- Author:
- Matt DesLauriers
- Twitter:
- @
- GitHub:
- Facebook:
- Google+:
- +
- Reddit:
- /r/
- Pouet:
- Website:
- Compo:
- webgl
- Demo link:
- https://js1k.com/2014-dragons/demo/1761
- Shortlink:
- https://js1k.com/1761
- Blog post:
- please update here!
- Bytes:
- 1006
- Chars:
- 1006
- Submission
with(g){b.style.background="#000";for(k in g)g[k.match(/^..|[A-Z]|1f$/g).join("")]=g[k];for(vi(0,S=0,s=256,a.style.cssText=a.width=a.height=s),p=crP(t=2);t;coS(S),atS(p,S))shS(S=crS(35634-t),--t?"precision lowp float;uniform float T;void main(void){vec2 a=gl_FragCoord.xy;vec2 b=a/256.;vec3 c=vec3(b.xy*2.-1.,.9);vec3 d=c;d.z-=15.5;vec3 e=vec3(.0);float f;float g;for(float h=0.;h<20.;h+=1.){float i=T/4.+.01*d.y;float j=cos(i);float k=sin(i);mat2 l=mat2(j,-k,k,j);vec3 m=abs(1.-mod(vec3(l*mix(d.xz,d.xy,abs(sin(T/5.))),d.y),2.));f=max(length(vec2(length(m.xz)-(sin(T)/2.+.5),m.y))-.4,length(d)-10.5);g=h;if(abs(f)<.005) break;d+=c*f;}e=vec3(g/40.)*(1.-length(b-.5))*1.4;e+=fract(sin(dot(b,vec2(12.9,78.2)))*43758.5)*.15;if(mod(a.x+a.y,6.)>2.) e*=.9;gl_FragColor=vec4(vec3(e),1.);}":"attribute vec4 p;void main(){gl_Position=p;}");D=function(){requestAnimationFrame(D),drA(4,un1f(geUL(p,"T"),t+=.01),3)},D(veAP(enVAA(biB(k=34962,crB())),2,5126,liP(p),usP(p),buD(k,new Float32Array([1,1,1,-3,-3,1]),k+82)))}
- Description
- Raymarching shader. See here for details:
http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
I used some WebGL setup tricks from @p01 as seen here:
http://blog.tojicode.com/2012/02/webgl-js1k-entry.html
There is still some room for optimization and compression if I wanted to pack more features in.
- Base64 encoded
d2l0aChnKXtiLnN0eWxlLmJhY2tncm91bmQ9IiMwMDAiO2ZvcihrIGluIGcpZ1trLm1hdGNoKC9eLi58W0EtWl18MWYkL2cpLmpvaW4oIiIpXT1nW2tdO2Zvcih2aSgwLFM9MCxzPTI1NixhLnN0eWxlLmNzc1RleHQ9YS53aWR0aD1hLmhlaWdodD1zKSxwPWNyUCh0PTIpO3Q7Y29TKFMpLGF0UyhwLFMpKXNoUyhTPWNyUygzNTYzNC10KSwtLXQ/InByZWNpc2lvbiBsb3dwIGZsb2F0O3VuaWZvcm0gZmxvYXQgVDt2b2lkIG1haW4odm9pZCl7dmVjMiBhPWdsX0ZyYWdDb29yZC54eTt2ZWMyIGI9YS8yNTYuO3ZlYzMgYz12ZWMzKGIueHkqMi4tMS4sLjkpO3ZlYzMgZD1jO2Quei09MTUuNTt2ZWMzIGU9dmVjMyguMCk7ZmxvYXQgZjtmbG9hdCBnO2ZvcihmbG9hdCBoPTAuO2g8MjAuO2grPTEuKXtmbG9hdCBpPVQvNC4rLjAxKmQueTtmbG9hdCBqPWNvcyhpKTtmbG9hdCBrPXNpbihpKTttYXQyIGw9bWF0MihqLC1rLGssaik7dmVjMyBtPWFicygxLi1tb2QodmVjMyhsKm1peChkLnh6LGQueHksYWJzKHNpbihULzUuKSkpLGQueSksMi4pKTtmPW1heChsZW5ndGgodmVjMihsZW5ndGgobS54eiktKHNpbihUKS8yLisuNSksbS55KSktLjQsbGVuZ3RoKGQpLTEwLjUpO2c9aDtpZihhYnMoZik8LjAwNSkgYnJlYWs7ZCs9YypmO31lPXZlYzMoZy80MC4pKigxLi1sZW5ndGgoYi0uNSkpKjEuNDtlKz1mcmFjdChzaW4oZG90KGIsdmVjMigxMi45LDc4LjIpKSkqNDM3NTguNSkqLjE1O2lmKG1vZChhLngrYS55LDYuKT4yLikgZSo9Ljk7Z2xfRnJhZ0NvbG9yPXZlYzQodmVjMyhlKSwxLik7fSI6ImF0dHJpYnV0ZSB2ZWM0IHA7dm9pZCBtYWluKCl7Z2xfUG9zaXRpb249cDt9Iik7RD1mdW5jdGlvbigpe3JlcXVlc3RBbmltYXRpb25GcmFtZShEKSxkckEoNCx1bjFmKGdlVUwocCwiVCIpLHQrPS4wMSksMyl9LEQodmVBUChlblZBQShiaUIoaz0zNDk2MixjckIoKSkpLDIsNTEyNixsaVAocCksdXNQKHApLGJ1RChrLG5ldyBGbG9hdDMyQXJyYXkoWzEsMSwxLC0zLC0zLDFdKSxrKzgyKSkpfQ==
- Original source
with (g) {
//not really that important, but gives a nicer background..
b.style.background='#000';
//some very well compressed setup code from p01
//here is our aliasing for WebGL context
for(k in g)
g[k.match(/^..|[A-Z]|1f$/g).join('')] = g[k];
//setup viewport and define S (shader) and s (size) variables...
vi(
0,
S=0,
s=256,
a.style.cssText=(a.width=a.height=s));
//uncomment for debugging shader errors
for (p = crP(t=2); t; coS(S), (atS(p, S) /*|| console.log( getShaderInfoLog(S) )*/ )) {
shS(S = crS(35634 - t), --t ? <%= frag %> : 'attribute vec4 p;void main(){gl_Position=p;}');
}
//console.log( getShaderInfoLog(S) )
//setInterval leads to pretty brutal performance in Chrome
D=function() {
requestAnimationFrame(D)
drA(4, un1f(geUL(p,"T"),t+=.01), 3)
}
D(
veAP(
enVAA(
biB(k = 34962, crB())
),
2,
5126,
liP(p),
usP(p),
buD(k, new Float32Array([1,1,1, -3, -3, 1]), k+82)
)
);
}
//////// frag.glsl source: (minified and included in JS file during build step)
precision lowp float;
uniform float T;
void main( void ) {
vec2 fc = gl_FragCoord.xy;
vec2 p = fc / 256.;
vec3 ray_dir = vec3(p.xy*2.-1., .9);
vec3 pos = ray_dir;
pos.z -= 15.5;
// ray_dir = normalize(ray_dir);
vec3 color = vec3(.0);
float dist;
float j;
for( float i = 0.; i < 20.; i += 1. ) {
float a = T/4.+.01*pos.y;
//twist deform
float c = cos(a);
float s = sin(a);
mat2 m = mat2(c,-s,s,c);
//here we repeat the content, lerping from one plane to another
vec3 q = abs(1.-mod(vec3(m*mix(pos.xz, pos.xy, abs(sin(T/5.))),pos.y),2.));
//here is where we model the tori and intersect them with a sphere
dist = max(length(vec2(length(q.xz)-(sin(T)/2.+.5),q.y))-.4, length(pos)-10.5);
j = i;
if(abs(dist)<.005)
break;
pos += ray_dir * dist;
}
//determine our color, with vignette
color = vec3(j/40.) * (1.-length(p-.5)) * 1.4;
//some noise
color += fract(sin(dot(p, vec2(12.9,78.2))) * 43758.5)*.15;
//scanlines
if (mod( fc.x+fc.y, 6. ) > 2. )
color *= .9;
gl_FragColor = vec4(vec3(color),1.);
}