#define GLSLIFY 1
uniform float time;
uniform float seed;
uniform vec2 resolution;
float noise3D(vec3 p){
return fract(sin(dot(p,vec3(12.9898,78.233,128.852)))*43758.5453)*2.-1.;
}
float simplex3D(vec3 p){
float f3=1./3.;
float s=(p.x+p.y+p.z)*f3;
int i=int(floor(p.x+s));
int j=int(floor(p.y+s));
int k=int(floor(p.z+s));
float g3=1./6.;
float t=float((i+j+k))*g3;
float x0=float(i)-t;
float y0=float(j)-t;
float z0=float(k)-t;
x0=p.x-x0;
y0=p.y-y0;
z0=p.z-z0;
int i1,j1,k1;
int i2,j2,k2;
if(x0>=y0)
{
if(y0>=z0){i1=1;j1=0;k1=0;i2=1;j2=1;k2=0;}
else if(x0>=z0){i1=1;j1=0;k1=0;i2=1;j2=0;k2=1;}
else{i1=0;j1=0;k1=1;i2=1;j2=0;k2=1;}
}
else
{
if(y0<z0){i1=0;j1=0;k1=1;i2=0;j2=1;k2=1;}
else if(x0<z0){i1=0;j1=1;k1=0;i2=0;j2=1;k2=1;}
else{i1=0;j1=1;k1=0;i2=1;j2=1;k2=0;}
}
float x1=x0-float(i1)+g3;
float y1=y0-float(j1)+g3;
float z1=z0-float(k1)+g3;
float x2=x0-float(i2)+2.*g3;
float y2=y0-float(j2)+2.*g3;
float z2=z0-float(k2)+2.*g3;
float x3=x0-1.+3.*g3;
float y3=y0-1.+3.*g3;
float z3=z0-1.+3.*g3;
vec3 ijk0=vec3(i,j,k);
vec3 ijk1=vec3(i+i1,j+j1,k+k1);
vec3 ijk2=vec3(i+i2,j+j2,k+k2);
vec3 ijk3=vec3(i+1,j+1,k+1);
vec3 gr0=normalize(vec3(noise3D(ijk0),noise3D(ijk0*2.01),noise3D(ijk0*2.02)));
vec3 gr1=normalize(vec3(noise3D(ijk1),noise3D(ijk1*2.01),noise3D(ijk1*2.02)));
vec3 gr2=normalize(vec3(noise3D(ijk2),noise3D(ijk2*2.01),noise3D(ijk2*2.02)));
vec3 gr3=normalize(vec3(noise3D(ijk3),noise3D(ijk3*2.01),noise3D(ijk3*2.02)));
float n0=0.;
float n1=0.;
float n2=0.;
float n3=0.;
float t0=.5-x0*x0-y0*y0-z0*z0;
if(t0>=0.)
{
t0*=t0;
n0=t0*t0*dot(gr0,vec3(x0,y0,z0));
}
float t1=.5-x1*x1-y1*y1-z1*z1;
if(t1>=0.)
{
t1*=t1;
n1=t1*t1*dot(gr1,vec3(x1,y1,z1));
}
float t2=.5-x2*x2-y2*y2-z2*z2;
if(t2>=0.)
{
t2*=t2;
n2=t2*t2*dot(gr2,vec3(x2,y2,z2));
}
float t3=.5-x3*x3-y3*y3-z3*z3;
if(t3>=0.)
{
t3*=t3;
n3=t3*t3*dot(gr3,vec3(x3,y3,z3));
}
return 96.*(n0+n1+n2+n3);
}
float sdSphere(vec3 p,float s)
{
return length(p)-s;
}
float opSmoothUnion(float d1,float d2,float k)
{
float h=clamp(.5+.5*(d2-d1)/k,0.,1.);
return mix(d2,d1,h)-k*h*(1.-h);
}
#define MAX_DIST 3.
#define CLOSE_ENOUGH.001
#define K.2
const vec3 liquidColor=vec3(.1,0.,.17);
const vec3 hotColor=vec3(1.,1.,0.);
const vec3 waxColor=vec3(1.,0.,0);
const float blobRate=.2;
const float blobFreq=3.;
const float blobAmp=.02;
const int blobCount=5;
const float blobScaleVariance=.05;
const float moveRate=.1;
struct ray{
vec3 o;
vec3 d;
};
struct hit{
float sdf;
float heat;
vec3 col;
};
struct light{
vec3 d;
float i;
};
float sdBlob(vec3 p,float s,float u){
p+=simplex3D(vec3(p.x*blobFreq+time*blobRate*.237128+u*.24184,p.y*blobFreq+time*blobRate*.214717+u*-.124918,p.z*blobFreq+time*blobRate*.187461+u*.125817))*blobAmp;
return sdSphere(p,s);
}
float sdScene(vec3 p){
float d=float(MAX_DIST);
float bd=0.,bm=float(blobCount-1);
float ix,is,fi;
vec3 nx=vec3(sin(time*moveRate*.01489198)+seed*24.1581),
ny=vec3(sin(time*moveRate*.01612878)-seed*15.15918),
nz=vec3(sin(time*moveRate*.011232245)+seed*51.1491),
ns=vec3(sin(time*moveRate*.0070712)-seed*14.187),
center;
vec3 id;
for(int i=0;i<blobCount;++i){
fi=float(i);
id=vec3(i*16,i*32,i*25);
ix=(fi/bm)-.5;
center=vec3(
simplex3D(nx+id*13.1384)*.35+sin(id.x*11.418+time*moveRate)*.15,
simplex3D(ny+id*10.11424)*.16+sin(id.y*4.127-fi*14.19+time*moveRate)*.28,
1.+simplex3D(nz+id*12.35172)*.02+sin(id.z*1.1487+time*moveRate)*.02
);
bd=sdBlob(
center-p,
.1+simplex3D(ns+id)*blobScaleVariance,
fi*5.13816
);
d=opSmoothUnion(bd,d,K);
}
return d;
}
hit scene(vec3 p){
float sd=sdScene(p);
float heat=pow(max(-sd,0.),.2);
vec3 col=mix(waxColor,hotColor,heat);
return hit(sd,heat,col);
}
vec3 calcNormal(in vec3 p){
const vec2 k=vec2(1,-1);
return normalize(k.xyy*sdScene(p+k.xyy*CLOSE_ENOUGH)+
k.yyx*sdScene(p+k.yyx*CLOSE_ENOUGH)+
k.yxy*sdScene(p+k.yxy*CLOSE_ENOUGH)+
k.xxx*sdScene(p+k.xxx*CLOSE_ENOUGH));
}
void main(){
vec2 uv=gl_FragCoord.xy/resolution.xy;
uv-=vec2(.5);
uv*=min(vec2(resolution.x/resolution.y,1.),vec2(1.,resolution.y/resolution.x));
light l=light(normalize(vec3(1.,1.,1.)),1.);
ray r=ray(vec3(uv,0.),normalize(vec3(uv,4.)));
float d=0.;
float b=0.;
vec3 n=vec3(0.);
hit h;
float minSdf=100.;
while(d<MAX_DIST){
vec3 rp=r.o+r.d*d;
h=scene(rp);
minSdf=min(minSdf,h.sdf);
if(h.sdf<CLOSE_ENOUGH){
n=calcNormal(rp);
break;
}
d+=max(rp.z,CLOSE_ENOUGH);
}
vec3 color=vec3(0.);
if(d>MAX_DIST){
float radiantHeat=max(1.-pow(minSdf,.2),0.);
color=liquidColor;
color=mix(color,waxColor,-uv.y*.3-pow(abs(uv.x),4.));
color=mix(color,waxColor,pow(radiantHeat,1.4));
}else{
color=h.col;
}
gl_FragColor=vec4(color,1.);
}