mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-23 00:01:31 +11:00
287 lines
6.4 KiB
Plaintext
287 lines
6.4 KiB
Plaintext
#version 450
|
|
//kirby jump
|
|
// fizzer 2018-01-31
|
|
// https://www.shadertoy.com/view/lt2fD3
|
|
|
|
layout(std140, set = 0, binding = 0) uniform UBO
|
|
{
|
|
mat4 MVP;
|
|
vec4 OutputSize;
|
|
vec4 OriginalSize;
|
|
vec4 SourceSize;
|
|
uint FrameCount;
|
|
} global;
|
|
|
|
#pragma stage vertex
|
|
layout(location = 0) in vec4 Position;
|
|
layout(location = 1) in vec2 TexCoord;
|
|
layout(location = 0) out vec2 vTexCoord;
|
|
const vec2 madd = vec2(0.5, 0.5);
|
|
void main()
|
|
{
|
|
gl_Position = global.MVP * Position;
|
|
vTexCoord = gl_Position.xy;
|
|
}
|
|
|
|
#pragma stage fragment
|
|
layout(location = 0) in vec2 vTexCoord;
|
|
layout(location = 0) out vec4 FragColor;
|
|
float iGlobalTime = float(global.FrameCount)*0.025;
|
|
vec2 iResolution = global.OutputSize.xy;
|
|
|
|
// polynomial smooth min (from IQ)
|
|
float smin( float a, float b, float k )
|
|
{
|
|
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
|
|
return mix( b, a, h ) - k*h*(1.0-h);
|
|
}
|
|
|
|
|
|
float smax(float a,float b, float k)
|
|
{
|
|
return -smin(-a,-b,k);
|
|
}
|
|
|
|
mat2 rotmat(float a)
|
|
{
|
|
return mat2(cos(a),sin(a),-sin(a),cos(a));
|
|
}
|
|
|
|
float shoesDist(vec3 p)
|
|
{
|
|
vec3 op=p;
|
|
float d=1e4;
|
|
|
|
p.y-=1.5;
|
|
|
|
// right shoe
|
|
op=p;
|
|
p-=vec3(-.5,-.6,-.9);
|
|
p.yz=rotmat(-.7)*p.yz;
|
|
p.xz=rotmat(0.1)*p.xz;
|
|
d=min(d,-smin(p.y,-(length(p*vec3(1.6,1,1))-.64),.2));
|
|
p=op;
|
|
|
|
// left shoe
|
|
op=p;
|
|
p-=vec3(.55,-.8,0.4);
|
|
p.x=-p.x;
|
|
p.yz=rotmat(1.4)*p.yz;
|
|
d=min(d,-smin(p.y,-(length(p*vec3(1.6,1,1))-.73),.2));
|
|
p=op;
|
|
return d;
|
|
}
|
|
|
|
float sceneDist(vec3 p)
|
|
{
|
|
vec3 op=p;
|
|
float d=shoesDist(p);
|
|
|
|
d=min(d,p.y);
|
|
p.y-=1.5;
|
|
|
|
// torso
|
|
d=min(d,length(p)-1.);
|
|
|
|
|
|
// left arm
|
|
op=p;
|
|
p-=vec3(.66,.7,0);
|
|
p.xz=rotmat(-0.1)*p.xz;
|
|
d=smin(d,(length(p*vec3(1.8,1,1))-.58),.07);
|
|
p=op;
|
|
|
|
// right arm
|
|
op=p;
|
|
p-=vec3(-.75,0.2,0);
|
|
d=smin(d,(length(p*vec3(1,1.5,1))-.54),.03);
|
|
p=op;
|
|
|
|
// mouth
|
|
p.y-=.11;
|
|
float md=smax(p.z+.84,smax(smax(p.x-.2,p.y-.075,.2),dot(p,vec3(.7071,-.7071,0))-.1,.08),.04);
|
|
p.x=-p.x;
|
|
md=smax(md,smax(p.z+.84,smax(smax(p.x-.2,p.y-.075,.2),dot(p,vec3(.7071,-.7071,0))-.1,.08),.01),.13);
|
|
d=smax(d,-md,.012);
|
|
|
|
// tongue
|
|
p=op;
|
|
d=smin(d,length((p-vec3(0,.03,-.75))*vec3(1,1,1))-.16,.01);
|
|
|
|
return min(d,10.);
|
|
}
|
|
|
|
|
|
|
|
vec3 sceneNorm(vec3 p)
|
|
{
|
|
vec3 e=vec3(1e-3,0,0);
|
|
float d = sceneDist(p);
|
|
return normalize(vec3(sceneDist(p + e.xyy) - sceneDist(p - e.xyy), sceneDist(p + e.yxy) - sceneDist(p - e.yxy),
|
|
sceneDist(p + e.yyx) - sceneDist(p - e.yyx)));
|
|
}
|
|
|
|
|
|
// from simon green and others
|
|
float ambientOcclusion(vec3 p, vec3 n)
|
|
{
|
|
const int steps = 4;
|
|
const float delta = 0.15;
|
|
|
|
float a = 0.0;
|
|
float weight = 4.;
|
|
for(int i=1; i<=steps; i++) {
|
|
float d = (float(i) / float(steps)) * delta;
|
|
a += weight*(d - sceneDist(p + n*d));
|
|
weight *= 0.5;
|
|
}
|
|
return clamp(1.0 - a, 0.0, 1.0);
|
|
}
|
|
|
|
// a re-shaped cosine, to make the peaks more pointy
|
|
float cos2(float x){return cos(x-sin(x)/3.);}
|
|
|
|
float starShape(vec2 p)
|
|
{
|
|
float a=atan(p.y,p.x)+iGlobalTime/3.;
|
|
float l=pow(length(p),.8);
|
|
float star=1.-smoothstep(0.,(3.-cos2(a*5.*2.))*.02,l-.5+cos2(a*5.)*.1);
|
|
return star;
|
|
}
|
|
|
|
|
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
|
{
|
|
// Normalized pixel coordinates (from 0 to 1)
|
|
vec2 uv = fragCoord/iResolution.xy;
|
|
|
|
float an=cos(iGlobalTime)*.1;
|
|
|
|
vec2 ot=uv*2.-1.;
|
|
ot.y*=iResolution.y/iResolution.x;
|
|
vec3 ro=vec3(0.,1.4,4.);
|
|
vec3 rd=normalize(vec3(ot.xy,-1.3));
|
|
|
|
rd.xz=mat2(cos(an),sin(an),sin(an),-cos(an))*rd.xz;
|
|
ro.xz=mat2(cos(an),sin(an),sin(an),-cos(an))*ro.xz;
|
|
|
|
float s=20.;
|
|
|
|
// primary ray
|
|
float t=0.,d=0.;
|
|
for(int i=0;i<80;++i)
|
|
{
|
|
d=sceneDist(ro+rd*t);
|
|
if(d<1e-4)
|
|
break;
|
|
if(t>10.)
|
|
break;
|
|
t+=d*.9;
|
|
}
|
|
|
|
t=min(t,10.0);
|
|
|
|
// shadow ray
|
|
vec3 rp=ro+rd*t;
|
|
vec3 n=sceneNorm(rp);
|
|
float st=5e-3;
|
|
vec3 ld=normalize(vec3(2,4,-4));
|
|
for(int i=0;i<20;++i)
|
|
{
|
|
d=sceneDist(rp+ld*st);
|
|
if(d<1e-5)
|
|
break;
|
|
if(st>5.)
|
|
break;
|
|
st+=d*2.;
|
|
}
|
|
|
|
// ambient occlusion and shadowing
|
|
vec3 ao=vec3(ambientOcclusion(rp, n));
|
|
float shad=mix(.85,1.,step(5.,st));
|
|
|
|
ao*=mix(.3,1.,.5+.5*n.y);
|
|
|
|
// soft floor shadow
|
|
if(rp.y<1e-3)
|
|
ao*=mix(mix(vec3(1,.5,.7),vec3(1),.4)*.6,vec3(1),smoothstep(0.,1.6,length(rp.xz)));
|
|
|
|
|
|
|
|
vec3 diff=vec3(1);
|
|
vec3 emit=vec3(0);
|
|
|
|
// skin
|
|
diff*=vec3(1.15,.3,.41)*1.4;
|
|
diff+=.4*mix(1.,0.,smoothstep(0.,1.,length(rp.xy-vec2(0.,1.9))));
|
|
diff+=.5*mix(1.,0.,smoothstep(0.,.5,length(rp.xy-vec2(.7,2.5))));
|
|
diff+=.36*mix(1.,0.,smoothstep(0.,.5,length(rp.xy-vec2(-1.1,1.8))));
|
|
|
|
if(rp.y<1e-3)
|
|
diff=vec3(.6,1,.6);
|
|
|
|
// mouth
|
|
diff*=mix(vec3(1,.3,.2),vec3(1),smoothstep(.97,.99,length(rp-vec3(0,1.5,0))));
|
|
|
|
// shoes
|
|
diff=mix(vec3(1.,.05,.1),diff,smoothstep(0.,0.01,shoesDist(rp)));
|
|
diff+=.2*mix(1.,0.,smoothstep(0.,.2,length(rp.xy-vec2(-0.5,1.4))));
|
|
diff+=.12*mix(1.,0.,smoothstep(0.,.25,length(rp.xy-vec2(0.57,.3))));
|
|
|
|
// bounce light from the floor
|
|
diff+=vec3(.25,1.,.25)*smoothstep(-.3,1.7,-rp.y+1.)*max(0.,-n.y)*.7;
|
|
|
|
vec3 orp=rp;
|
|
rp.y-=1.5;
|
|
rp.x=abs(rp.x);
|
|
|
|
// blushes
|
|
diff*=mix(vec3(1,.5,.5),vec3(1),smoothstep(.1,.15,length((rp.xy-vec2(.4,.2))*vec2(1,1.65))));
|
|
|
|
rp.xy-=vec2(.16,.45);
|
|
rp.xy*=.9;
|
|
orp=rp;
|
|
rp.y=pow(abs(rp.y),1.4)*sign(rp.y);
|
|
|
|
// eye outline
|
|
diff*=smoothstep(.058,.067,length((rp.xy)*vec2(.9,.52)));
|
|
|
|
rp=orp;
|
|
rp.y+=.08;
|
|
rp.y-=pow(abs(rp.x),2.)*16.;
|
|
|
|
// eye reflections
|
|
emit+=vec3(.1,.5,1.)*(1.-smoothstep(.03,.036,length((rp.xy)*vec2(.7,.3))))*max(0.,-rp.y)*10.;
|
|
|
|
rp=orp;
|
|
rp.y-=.12;
|
|
|
|
// eye highlights
|
|
emit+=vec3(1)*(1.-smoothstep(.03,.04,length((rp.xy)*vec2(1.,.48))));
|
|
|
|
// fresnel
|
|
diff+=pow(clamp(1.-dot(-rd,n),0.,.9),4.)*.5;
|
|
|
|
// background and floor fade
|
|
vec3 backg=vec3(1.15,.3,.41)*.9;
|
|
ot.x+=.6+iGlobalTime/50.;
|
|
ot.y+=cos(floor(ot.x*2.)*3.)*.1+.2;
|
|
ot.x=mod(ot.x,.5)-.25;
|
|
backg=mix(backg,vec3(1.,1.,.5),.1*starShape((ot-vec2(0.,.6))*8.)*smoothstep(9.,10.,t));
|
|
diff=mix(diff,backg,smoothstep(.9,10.,t));
|
|
|
|
fragColor.rgb=mix(vec3(.15,0,0),vec3(1),ao)*shad*diff*1.1;
|
|
fragColor.rgb+=emit;
|
|
fragColor.a = 1.0f;
|
|
|
|
fragColor.rgb=pow(fragColor.rgb,vec3(1./2.4));
|
|
}
|
|
|
|
void main(void)
|
|
{
|
|
//just some shit to wrap shadertoy's stuff
|
|
vec2 FragCoord = vTexCoord.xy*global.OutputSize.xy;
|
|
FragCoord.y = -FragCoord.y;
|
|
mainImage(FragColor,FragCoord);
|
|
}
|