154 lines
3.8 KiB
JavaScript
154 lines
3.8 KiB
JavaScript
export default `#define MAX_STEPS 1280
|
|
#define MAX_DIST 128.
|
|
#define E 0.0001
|
|
#define PI 3.141592
|
|
|
|
vec3 rotX(vec3 v, float a)
|
|
{
|
|
return vec3(v.x, v.y * cos(a) - v.z * sin(a), v.y * sin(a) + v.z * cos(a));
|
|
}
|
|
|
|
vec3 rotY(vec3 v, float a)
|
|
{
|
|
return vec3(v.x * cos(a) + v.z * sin(a), v.y, v.z * cos(a) - v.x * sin(a));
|
|
}
|
|
|
|
vec3 rotZ(vec3 v, float a)
|
|
{
|
|
return vec3(v.x * cos(a) - v.y * sin(a), v.x * sin(a) + v.y * cos(a), v.z);
|
|
}
|
|
|
|
float sdfSphere(vec3 p, float r)
|
|
{
|
|
return length(p) - r;
|
|
}
|
|
|
|
float sdfPyramid( vec3 p, float h)
|
|
{
|
|
float m2 = h*h + 0.25;
|
|
p.xz = abs(p.xz);
|
|
p.xz = (p.z>p.x) ? p.zx : p.xz;
|
|
p.xz -= 0.5;
|
|
|
|
vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);
|
|
float s = max(-q.x,0.0);
|
|
float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );
|
|
float a = m2*(q.x+s)*(q.x+s) + q.y*q.y;
|
|
float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);
|
|
float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);
|
|
return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));
|
|
}
|
|
|
|
float sdfTriPrism( vec3 p, vec2 h )
|
|
{
|
|
vec3 q = abs(p);
|
|
return max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);
|
|
}
|
|
|
|
vec3 SDFmod( in vec3 p, in vec3 c)
|
|
{
|
|
return (mod(p+0.5*c,c)-0.5*c);
|
|
return (p);
|
|
}
|
|
|
|
// blackbody by aiekick : https://www.shadertoy.com/view/lttXDn
|
|
|
|
// -------------blackbody----------------- //
|
|
|
|
// return color from temperature
|
|
//http://www.physics.sfasu.edu/astro/color/blackbody.html
|
|
//http://www.vendian.org/mncharity/dir3/blackbody/
|
|
//http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
|
|
|
|
vec3 blackbody(float Temp)
|
|
{
|
|
vec3 col = vec3(255.);
|
|
col.x = 56100000. * pow(Temp,(-3. / 2.)) + 148.;
|
|
col.y = 100.04 * log(Temp) - 623.6;
|
|
if (Temp > 6500.) col.y = 35200000. * pow(Temp,(-3. / 2.)) + 184.;
|
|
col.z = 194.18 * log(Temp) - 1448.6;
|
|
col = clamp(col, 0., 255.)/255.;
|
|
if (Temp < 1000.) col *= Temp/1000.;
|
|
return col;
|
|
}
|
|
|
|
// -------------blackbody----------------- //
|
|
|
|
float length2( vec3 p ) { p=p*p; return sqrt( p.x+p.y+p.z); }
|
|
|
|
float length6( vec3 p ) { p=p*p*p; p=p*p; return pow(p.x+p.y+p.z,1.0/6.0); }
|
|
|
|
float length8( vec3 p ) { p=p*p; p=p*p; p=p*p; return pow(p.x+p.y+p.z,1.0/8.0); }
|
|
|
|
vec3 pos = vec3(0);
|
|
|
|
float scene(vec3 p)
|
|
{
|
|
int index = -1;
|
|
float d = 10000.;
|
|
float sd1 = sdfPyramid(SDFmod(rotX(rotY(p - pos, iTime / 10. + cos(iTime / 10.) * 50. * p.z / 100. + PI / 2.), iTime / 10. + 0. + sin(iTime / 10.) * 50. * p.x / 1000.),
|
|
vec3(20.)), 2.) * 0.15;
|
|
d = min(sd1, d);
|
|
pos = vec3(0);
|
|
return d;
|
|
}
|
|
|
|
vec3 march(vec3 ro, vec3 rd)
|
|
{
|
|
float dO = 0.;
|
|
float mind = 10000.;
|
|
float index;
|
|
int steps = 0;
|
|
for (int mysteps = 0; mysteps < MAX_STEPS; mysteps++)
|
|
{
|
|
steps = mysteps;
|
|
vec3 p = ro + rd * dO;
|
|
float dS = scene(p);
|
|
if (dS < mind)
|
|
mind = dS;
|
|
dO += dS;
|
|
if (dS < E || dO > MAX_DIST)
|
|
break;
|
|
steps++;
|
|
}
|
|
return vec3(dO, mind, steps);
|
|
}
|
|
|
|
vec3 normal(vec3 p)
|
|
{
|
|
float d = scene(p);
|
|
vec2 e = vec2(0.001, 0);
|
|
vec3 n = d - vec3(
|
|
scene(p - e.xyy),
|
|
scene(p - e.yxy),
|
|
scene(p - e.yyx));
|
|
return (normalize(n));
|
|
}
|
|
|
|
float light(vec3 p, vec3 n)
|
|
{
|
|
vec3 lightPos = vec3(2.5, 2.5, -10.);
|
|
vec3 l = normalize(lightPos - p);
|
|
float dif = clamp(dot(l, n), 0., 1.);
|
|
return (dif);
|
|
}
|
|
|
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
|
{
|
|
vec2 uv = ((fragCoord - .5 * iResolution.xy) / iResolution.y);
|
|
vec3 ro = vec3(2.5, 2.5, -10.);
|
|
vec3 rd = normalize(vec3(uv.x, uv.y, 1.));
|
|
vec3 col = vec3(0);
|
|
vec3 d = march(ro, rd);
|
|
|
|
vec3 p = ro + rd * d.x;
|
|
vec3 n = normal(p);
|
|
float dif = light(p, n);
|
|
if (d.x < MAX_DIST * 0.9)
|
|
col += vec3(dif * ((sin(iTime / 1.) + 1.) * 0.25 + 0.5));
|
|
else
|
|
col += blackbody(abs(d.y * sin(iTime / 3.) * 10000.));
|
|
col = pow(col, vec3(0.454545));
|
|
fragColor = vec4(col, 1.0);
|
|
}`;
|