Add spherical-polyhedra.glsl

This commit is contained in:
polyfloyd 2018-05-19 16:58:26 +02:00
parent b91c483b61
commit 07d6d1dee5

254
spherical-polyhedra.glsl Normal file
View file

@ -0,0 +1,254 @@
//Spherical polyhedra by nimitz (twitter: @stormoid)
/*
Follow up to my "Sphere mappings" shader (https://www.shadertoy.com/view/4sjXW1)
I was thinking about a cheap way to do icosahedral mapping and realized
I could just project on an axis and rotate the sphere for each projected
"facet".
Here I am showing only tilings of the regular polyhedra but this technique can
be used for any tilings of the sphere, regular or not. (or even arbitrary projections)
I omitted the tetraedron since the small number of projections
results in heavy deformation.
Perhaps there is a way to make that process cheaper? Let me know.
*/
#define time iTime
mat2 mm2(in float a){float c = cos(a), s = sin(a);return mat2(c,-s,s,c);}
vec3 rotx(vec3 p, float a){ float s = sin(a), c = cos(a);
return vec3(p.x, c*p.y - s*p.z, s*p.y + c*p.z); }
vec3 roty(vec3 p, float a){ float s = sin(a), c = cos(a);
return vec3(c*p.x + s*p.z, p.y, -s*p.x + c*p.z); }
vec3 rotz(vec3 p, float a){ float s = sin(a), c = cos(a);
return vec3(c*p.x - s*p.y, s*p.x + c*p.y, p.z); }
//---------------------------Textures--------------------------------
//-------------------------------------------------------------------
vec3 texpent(in vec2 p, in float idx)
{
float siz = iResolution.x *.007;
vec2 q = abs(p);
float rz = sin(clamp(max(max(q.x*1.176-p.y*0.385, q.x*0.727+p.y),
-p.y*1.237)*33.,0.,25.))*siz+siz;
vec3 col = (sin(vec3(1,1.5,5)*idx)+2.)*(rz+0.25);
col -= sin(dot(p,p)*10.+time*5.)*0.4;
return col;
}
vec3 textri2(in vec2 p, in float idx)
{
float siz = iResolution.x *.007;
vec2 q = abs(p);
float rz = sin(clamp(max(q.x*1.73205+p.y, -p.y*2.)*32.,0.,25.))*siz+siz;
vec3 col = (sin(vec3(1,1.7,5)*idx)+2.)*(rz+0.25);
col -= sin(p.x*20.+time*5.)*0.2;
return col;
}
vec3 texcub(in vec2 p, in float idx)
{
float siz = iResolution.x *.007;
float rz = sin(clamp(max(abs(p.x),abs(p.y))*24.,0.,25.))*siz+siz;
vec3 col = (sin(vec3(4,3.,5)*idx*.9)+2.)*(rz+0.25);
float a= atan(p.y,p.x);
col -= sin(a*15.+time*11.)*0.15-0.15;
return col;
}
vec3 textri(in vec2 p, in float idx)
{
float siz = iResolution.x *.001;
p*=1.31;
vec2 bp = p;
p.x *= 1.732;
vec2 f = fract(p)-0.5;
float d = abs(f.x-f.y);
d = min(abs(f.x+f.y),d);
float f1 = fract((p.y-0.25)*2.);
d = min(d,abs(f1-0.5));
d = 1.-smoothstep(0.,.1/(siz+.7),d);
vec2 q = abs(bp);
p = bp;
d -= smoothstep(1.,1.3,(max(q.x*1.73205+p.y, -p.y*2.)));
vec3 col = (sin(vec3(1.,1.5,5)*idx)+2.)*((1.-d)+0.25);
col -= sin(p.x*10.+time*8.)*0.15-0.1;
return col;
}
//----------------------------------------------------------------------------
//----------------------------------Sphere Tilings----------------------------
//----------------------------------------------------------------------------
//All the rotation matrices can be precomputed for better performance.
//5 mirrored pentagons for the dodecahedron
vec3 dod(in vec3 p)
{
vec3 col = vec3(1);
vec2 uv = vec2(0);
for (float i = 0.;i<=4.;i++)
{
p = roty(p,0.81);
p = rotx(p,0.759);
p = rotz(p,0.3915);
uv = vec2(p.z,p.y)/((p.x));
col = min(texpent(uv,i+1.),col);
}
p = roty(p,0.577);
p = rotx(p,-0.266);
p = rotz(p,-0.848);
uv = vec2(p.z,-p.y)/((p.x));
col = min(texpent(uv,6.),col);
return 1.-col;
}
//10 mirrored triangles for the icosahedron
vec3 ico(in vec3 p)
{
vec3 col = vec3(1);
vec2 uv = vec2(0);
//center band
const float n1 = .7297;
const float n2 = 1.0472;
for (float i = 0.;i<5.;i++)
{
if(mod(i,2.)==0.)
{
p = rotz(p,n1);
p = rotx(p,n2);
}
else
{
p = rotz(p,n1);
p = rotx(p,-n2);
}
uv = vec2(p.z,p.y)/((p.x));
col = min(textri(uv,i+1.),col);
}
p = roty(p,1.048);
p = rotz(p,.8416);
p = rotx(p,.7772);
//top caps
for (float i = 0.;i<5.;i++)
{
p = rotz(p,n1);
p = rotx(p,n2);
uv = vec2(p.z,p.y)/((p.x));
col = min(textri(uv,i+6.),col);
}
return 1.-col;
}
//4 mirrored triangles for octahedron
vec3 octa(in vec3 p)
{
vec3 col = vec3(1);
vec2 uv = vec2(0);
const float n1 = 1.231;
const float n2 = 1.047;
for (float i = 0.;i<4.;i++)
{
p = rotz(p,n1);
p = rotx(p,n2);
uv = vec2(p.z,p.y)/((p.x));
col = min(textri2(uv*.54,i+1.),col);
}
return 1.-col;
}
//cube using the same technique for completeness
vec3 cub(in vec3 p)
{
vec3 col = vec3(1);
vec2 uv = vec2(p.z,p.y)/((p.x));
col = min(texcub(uv*1.01,15.),col);
p = rotz(p,1.5708);
uv = vec2(p.z,p.y)/((p.x));
col = min(texcub(uv*1.01,4.),col);
p = roty(p,1.5708);
uv = vec2(p.z,p.y)/((p.x));
col = min(texcub(uv*1.01,5.),col);
return 1.-col;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
vec2 iSphere2(in vec3 ro, in vec3 rd)
{
vec3 oc = ro;
float b = dot(oc, rd);
float c = dot(oc,oc) - 1.;
float h = b*b - c;
if(h <0.0) return vec2(-1.);
else return vec2((-b - sqrt(h)), (-b + sqrt(h)));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = (fragCoord.xy - iResolution.xy * 0.5) / max(iResolution.x, iResolution.y);
vec2 bp = uv+0.5;
vec2 um = iResolution.xy / max(iResolution.x, iResolution.y);
//camera
vec3 ro = vec3(0.,0.,3.5);
vec3 rd = normalize(vec3(uv,-0.8));
mat2 mx = mm2(time*0.25+um.x*6.);
mat2 my = mm2(time*0.27+um.y*6.);
ro.xz *= mx;rd.xz *= mx;
ro.xy *= my;rd.xy *= my;
float sel = mod(floor((time+10.)*0.2),4.);
//sel=0.;
vec2 t = iSphere2(ro,rd);
vec3 col = vec3(0.);
float bg = clamp(dot(-rd,vec3(0.577))*0.3+.6,0.,1.);
if (sel == 0.) col = dod(rd)*1.2;
else if (sel == 1.) col = ico(rd)*1.2;
else if (sel == 2.) col = cub(rd)*1.2;
else if (sel == 3.) col = octa(rd)*1.2;
if (t.x > 0.)
{
vec3 pos = ro+rd*t.x;
vec3 pos2 = ro+rd*t.y;
vec3 rf = reflect(rd,pos);
if (sel == 0.)
{
vec3 col2 = max(dod(pos)*2.,dod(pos2)*.6);
col = mix(max(col,col2),col2,0.6);
}
else if (sel == 1.)
{
vec3 col2 = max(ico(pos2)*0.6,ico(pos)*2.);
col = mix(max(col,col2),col2,0.6);
}
else if (sel == 2.)
{
vec3 col2 = max(cub(pos2)*0.6,cub(pos)*2.);
col = mix(max(col,col2),col2,0.6);
}
else if (sel == 3.)
{
vec3 col2 = max(octa(pos2)*0.6,octa(pos)*2.);
col = mix(max(col,col2),col2,0.6);
}
}
fragColor = vec4(col, 1.0);
}
// https://www.shadertoy.com/view/4dBXWD