marching
Version:
Marching.js is a JavaScript library that compiles GLSL ray marchers.
392 lines (350 loc) • 12.2 kB
JavaScript
const glsl = require( 'glslify' )
const textures = {
image: {
name:'image',
glsl2d:`
vec3 image2d( vec2 uv, float scale, vec3 mod, float strength ) {
return texture( textures[ _id_ ], (uv+mod)*scale ).xyz * strength;
}
`,
parameters:[
{ name:'scale', type:'float', default:1 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'strength', type:'float', default:1 },
]
},
canvas: {
name:'canvas',
glsl2d:`
vec3 canvas2d( vec2 uv, float scale, vec3 mod, float strength ) {
return texture( textures[ _id_ ], (uv+mod.xy)*scale ).xyz * strength;
}
`,
parameters:[
{ name:'scale', type:'float', default:1 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'strength', type:'float', default:1 },
]
},
feedback: {
name:'feedback',
glsl2d:`
vec3 feedback2d( vec2 uv, float scale, vec3 mod, float strength ) {
return texture( textures[ _id_ ], (uv+mod.xy)*scale ).xyz * strength;
}
`,
parameters:[
{ name:'scale', type:'float', default:1 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'strength', type:'float', default:1 },
]
},
rainbow: {
name:'rainbow',
parameters: [
{ name:'strength', type:'float', default:1 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'shift', type:'float', default:0 },
{ name:'scale', type:'float', default:1 },
],
glsl:`
vec3 rainbow( vec3 pos, float strength, vec3 uvmod, float shift, float scale ) {
pos = (pos+uvmod) * scale;
vec3 a = vec3(0.5,0.5,0.5), b = vec3(0.5,0.5,0.5), c = vec3(1.0,1.0,1.0),d = vec3(0.0,0.33,0.67);
return a + b * cos( 6.283818 * ( c * mod(length(pos) + shift, 1. ) + d ) ) * strength;
}`
},
checkers: {
name:'checkers',
glsl:`
vec3 checkers( vec3 pos, float size, vec3 mod, vec3 color1, vec3 color2 ) {
vec3 tex;
pos = (pos+mod) * size;
if ((int(floor(pos.x) + floor(pos.y) + floor(pos.z)) & 1) == 0) {
tex = color1;
}else{
tex = color2;
}
return tex;
}`,
glsl2d:`
vec3 checkers2d( vec2 uv, float size, vec3 mod, vec3 color1, vec3 color2 ) {
float fmodResult = mod(floor(size * (uv.x+mod.x)) + floor(size * (uv.y+mod.y)), 2.0);
float fin = max(sign(fmodResult), 0.0);
return vec3(fin);
}
`,
parameters: [
{ name:'scale', type:'float', default:5 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'color1', type:'vec3', default:[1,1,1] },
{ name:'color2', type:'vec3', default:[0,0,0] }
],
},
noise: {
name:'noise',
glsl:glsl`
vec3 noise( vec3 pos, float scale, vec3 mod, float strength, float time ) {
float n = snoise( vec4((pos+mod)*scale, time) );
return vec3( n ) * strength;
}`,
glsl2d:glsl`
vec3 noise2d( vec2 st, float scale, vec3 mod, float strength, float time ) {
float col = snoise( vec3( (st+mod.xy), time ) * scale );
return vec3(col) * strength;
}
` ,
parameters: [
{ name:'scale', type:'float', default:2 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'strength', type:'float', default:.1 },
{ name:'time', type:'float', default:1 }
],
},
// adapted from https://thebookofshaders.com/10/
truchet: {
name:'truchet',
glsl2d:`
float random_truchet(in vec2 _st) {
return fract(sin(dot(_st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}
vec2 truchetPattern(in vec2 _st, in float _index){
_index = fract(((_index-0.5)*2.0));
if (_index > 0.75) {
_st = vec2(1.0) - _st;
} else if (_index > 0.5) {
_st = vec2(1.0-_st.x,_st.y);
} else if (_index > 0.25) {
_st = 1.0-vec2(1.0-_st.x,_st.y);
}
return _st;
}
vec3 truchet2d( vec2 st, float scale, vec3 mod, vec3 color ) {
st = (st+mod.xy) * scale;
vec2 ipos = floor(st); // integer
vec2 fpos = fract(st); // fraction
vec2 tile = truchetPattern(fpos, random_truchet( ipos ));
float col = smoothstep(tile.x-0.3,tile.x,tile.y)-smoothstep(tile.x,tile.x+.3,tile.y);
return color * col;
}
` ,
parameters: [
{ name:'scale', type:'float', default:10 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'color', type:'vec3', default:[1,1,1] }
],
},
dots: {
name:'dots',
glsl:`
vec3 dots( vec3 pos, float count, vec3 mod, float radius, vec3 color ) {
vec3 tex;
tex = vec3( color - smoothstep( radius, radius+.02, length(fract(pos*(round(count/2.)+.5)) -.5 )) );
return tex;
}` ,
glsl2d:`
vec2 tile(vec2 _st, float _zoom){
_st *= _zoom;
return fract(_st);
}
float circle(vec2 _st, float _radius){
vec2 pos = vec2(0.5)-_st;
_radius *= 0.75;
return 1.-smoothstep(_radius-(_radius*0.05),_radius+(_radius*0.05),dot(pos,pos)*3.14);
}
vec3 dots2d( vec2 _st, float scale, vec3 mod, float radius, vec3 color ) {
vec2 st = tile((_st+mod.xy,scale);
vec3 fin = vec3(circle(st, radius)) * color;
return fin;
}
`,
parameters: [
{ name:'scale', type:'float', default:5 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'radius', type:'float', default:.3 },
{ name:'color', type:'vec3', default:[1,1,1] }
],
},
stripes: {
name:'stripes',
glsl:`
vec3 stripes( vec3 pos, float scale, vec3 mod, vec3 color ) {
vec3 tex;
pos = pos + mod;
tex = vec3( color - smoothstep(0.3, 0.32, length(fract((pos.x+pos.y+pos.z)*scale) -.5 )) );
return tex;
}` ,
parameters: [
{ name:'scale', type:'float', default:5 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'color', type:'vec3', default:[1,1,1] }
],
},
cellular: {
name:'cellular',
glsl:glsl`
vec3 cellular( vec3 pos, float scale, vec3 mod, float jitter, float mode, float strength, float time ) {
vec2 w = worley3D( (pos+mod) * scale + time, jitter, false );
vec3 o;
if( mode == 0. ) {
o = vec3( w.x );
} else if ( mode == 1. ) {
o = vec3( w.y );
} else{
o = vec3( w.y - w.x );
}
return o * strength;
}
`,
glsl2d:glsl`
vec3 cellular( vec3 pos, float scale, float jitter, float mode, float strength ) {
vec2 w = worley3D( pos, jitter, false );
vec3 o;
if( mode == 0. ) {
o = vec3( w.x );
} else if ( mode == 1. ) {
o = vec3( w.y );
} else{
o = vec3( w.y - w.x );
}
return o * strength;
}
vec3 cellular2d( vec2 st, float scale, vec3 mod, float jitter, float mode, float strength, float time ) {
return cellular( vec3((st+mod.xy) * scale, time), nor, scale, jitter, mode, strength );
}
`,
parameters: [
{ name:'scale', type:'float', default:1 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'jitter', type:'float', default:1 },
{ name:'type', type:'float', default: 0 },
{ name:'strength', type:'float', default:2 },
{ name:'time', type:'float', default:1 }
],
},
voronoi: {
name:'voronoi',
parameters: [
{ name:'scale', type:'float', default:1 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'res', type:'float', default:100 },
{ name:'time', type:'float', default:1 },
{ name:'mode', type:'float', default:0 }
],
glsl:`
vec3 voronoi_hash(vec3 p) {
return fract(
sin(vec3(dot(p, vec3(1.0, 57.0, 113.0)), dot(p, vec3(57.0, 113.0, 1.0)),
dot(p, vec3(113.0, 1.0, 57.0)))) *
43758.5453);
}
vec3 voronoi_3d(const in vec3 x, float _res ) {
vec3 p = floor(x);
vec3 f = fract(x);
float id = 0.0;
vec2 res = vec2( _res );
for (int k = -1; k <= 1; k++) {
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
vec3 b = vec3(float(i), float(j), float(k));
vec3 r = vec3(b) - f + voronoi_hash(p + b);
float d = dot(r, r);
float cond = max(sign(res.x - d), 0.0);
float nCond = 1.0 - cond;
float cond2 = nCond * max(sign(res.y - d), 0.0);
float nCond2 = 1.0 - cond2;
id = (dot(p + b, vec3(1.0, 57.0, 113.0)) * cond) + (id * nCond);
res = vec2(d, res.x) * cond + res * nCond;
res.y = cond2 * d + nCond2 * res.y;
}
}
}
return vec3(sqrt(res), abs(id));
}
vec3 voronoi( vec3 pos, float scale, vec3 mod, float res, float time, float mode ) {
vec3 v = voronoi_3d( (pos+mod) * scale, res );
vec3 fin;
if( mode == 0. ) fin = vec3(v.x);
if( mode == 1. ) fin = vec3(v.y);
if( mode == 2. ) fin = vec3(v.y - v.x);
return fin;
}
`,
glsl2d:glsl`
vec3 voronoi_hash(vec3 p) {
return fract(
sin(vec3(dot(p, vec3(1.0, 57.0, 113.0)), dot(p, vec3(57.0, 113.0, 1.0)),
dot(p, vec3(113.0, 1.0, 57.0)))) * 43758.5453);
}
vec3 voronoi_3d(const in vec3 x, float _res ) {
vec3 p = floor(x);
vec3 f = fract(x);
float id = 0.0;
vec2 res = vec2( _res );
for (int k = -1; k <= 1; k++) {
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
vec3 b = vec3(float(i), float(j), float(k));
vec3 r = vec3(b) - f + voronoi_hash(p + b);
float d = dot(r, r);
float cond = max(sign(res.x - d), 0.0);
float nCond = 1.0 - cond;
float cond2 = nCond * max(sign(res.y - d), 0.0);
float nCond2 = 1.0 - cond2;
id = (dot(p + b, vec3(1.0, 57.0, 113.0)) * cond) + (id * nCond);
res = vec2(d, res.x) * cond + res * nCond;
res.y = cond2 * d + nCond2 * res.y;
}
}
}
return vec3(sqrt(res), abs(id));
}
vec3 voronoi2d( vec2 st, float scale, vec3 mod, float res, float time, float mode ) {
vec3 v = voronoi_3d( vec3((st+mod.xy) * scale, time), res );
vec3 fin;
if( mode == 0. ) fin = vec3(v.x);
if( mode == 1. ) fin = vec3(v.y);
if( mode == 2. ) fin = vec3(v.y - v.x);
return fin;
}
` ,
},
// adapted from https://thebookofshaders.com/edit.php#09/zigzag.frag
zigzag: {
name:'zigzag',
glsl2d:`
vec2 mirrorTile(vec2 _st, float _zoom){
_st *= _zoom;
if (fract(_st.y * 0.5) > 0.5){
_st.x = _st.x+0.5;
_st.y = 1.0-_st.y;
}
return fract(_st);
}
float fillY(vec2 _st, float _pct,float _antia){
return smoothstep( _pct-_antia, _pct, _st.y);
}
vec3 zigzag2d( vec2 st, float scale, vec3 mod, float time ) {
st = mirrorTile((st+mod.xy)*vec2(1.,2.),scale);
float x = st.x*2.;
float a = floor(1.+sin(x*3.14));
float b = floor(1.+sin((x+1.)*3.14));
float f = fract(x);
vec3 color = vec3( fillY(st,mix(a,b,f),0.01) );
return vec3(color);
}
` ,
parameters: [
{ name:'scale', type:'float', default:5 },
{ name:'uv', type:'vec3', default:[0,0,0] },
{ name:'time', type:'float', default:1 }
],
}
}
module.exports = textures