Created
November 18, 2013 20:56
-
-
Save anissen/7535140 to your computer and use it in GitHub Desktop.
Temp. fork of Fractal Cartoon on ShaderToy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// "Fractal Cartoon" - former "DE edge detection" by Kali | |
// Cartoon-like effect using eiffies's edge detection found here: | |
// https://www.shadertoy.com/view/4ss3WB | |
// I used my own method previously but was too complicated and not compiling everywhere. | |
// Thanks to the suggestion by WouterVanNifterick. | |
// There are no lights and no AO, only color by normals and dark edges. | |
//#define WAVES | |
#define RAY_STEPS 150 | |
#define BRIGHTNESS 1.2 | |
#define GAMMA 1.4 | |
#define SATURATION .65 | |
#define detail .001 | |
#define t iGlobalTime*.1 | |
const vec3 origin = vec3(-1.0,0.7,0.0); | |
float det = 0.0; | |
// 2D rotation function | |
mat2 rot(float a) { | |
return mat2(cos(a),sin(a),-sin(a),cos(a)); | |
} | |
// "Amazing Surface" fractal | |
vec4 formula(vec4 p) { | |
p.xz = abs(p.xz + 1.0) - abs(p.xz - 1.0) - p.xz; | |
p.y -= 0.35; | |
p.xy *= rot(radians(45.0+sin(iGlobalTime)*10.0)); | |
p = p * 2.0 / clamp(dot(p.xyz, p.xyz), 0.3, 0.9); | |
return p; | |
} | |
// Distance function | |
float de(vec3 pos) { | |
#ifdef WAVES | |
pos.y+=sin(pos.z-t*6.)*.15; //waves! | |
#endif | |
float hid=0.; | |
vec3 tpos=pos; | |
tpos.z=abs(3.-mod(tpos.z,6.)); | |
vec4 p=vec4(tpos,1.); | |
for (int i=0; i<4; i++) {p=formula(p);} | |
float fr=(length(max(vec2(0.),p.yz-1.5))-1.)/p.w; | |
float ro=max(abs(pos.x+1.)-.3,pos.y-.35); | |
ro=max(ro,-max(abs(pos.x+1.)-.1,pos.y-.5)); | |
pos.z=abs(.25-mod(pos.z,.5)); | |
ro=max(ro,-max(abs(pos.z)-.2,pos.y-.3)); | |
ro=max(ro,-max(abs(pos.z)-.01,-pos.y+.32)); | |
float d=min(fr,ro); | |
return d; | |
} | |
// Camera path | |
vec3 path(float ti) { | |
ti*=1.5; | |
vec3 p=vec3(sin(ti),(1.-sin(ti))*.5,-ti*5.)*.5; | |
return p; | |
} | |
// Calc normals, and here is edge detection, set to variable "edge" | |
float edge=0.0; | |
vec3 normal(vec3 p) { | |
vec3 e = vec3(0.0,det*5.,0.0); | |
float d1=de(p-e.yxx),d2=de(p+e.yxx); | |
float d3=de(p-e.xyx),d4=de(p+e.xyx); | |
float d5=de(p-e.xxy),d6=de(p+e.xxy); | |
float d=de(p); | |
edge=abs(d-0.5*(d2+d1))+abs(d-0.5*(d4+d3))+abs(d-0.5*(d6+d5));//edge finder | |
edge=min(1.,pow(edge,.5)*15.); | |
return normalize(vec3(d1-d2,d3-d4,d5-d6)); | |
} | |
// Raymarching and 2D graphics | |
vec3 raymarch(in vec3 from, in vec3 dir){ | |
edge=0.; | |
vec3 p, norm; | |
float d=100.; | |
float totdist=0.; | |
for (int i=0; i<RAY_STEPS; i++) { | |
if (d > det && totdist < 25.0) { | |
p = from + totdist * dir; | |
d = de(p); | |
det = detail*exp(.13*totdist); | |
totdist += d; | |
} | |
} | |
vec3 col=vec3(0.); | |
p-=(det-d)*dir; | |
norm=normal(p); | |
col=(1.-abs(norm))*max(0.,1.-edge*.8); // set normal as color with dark edges | |
totdist=clamp(totdist,0.,26.); | |
dir.y-=.02; | |
// set up background with sky and sun | |
vec3 backg=vec3(0.2,0.,0.4); | |
if (totdist>25.) col=backg; // hit background | |
col=pow(col,vec3(GAMMA))*BRIGHTNESS; | |
col=mix(vec3(length(col)),col,SATURATION); | |
col*=vec3(1.,.9,.85); | |
return col; | |
} | |
// get camera position | |
vec3 move(inout vec3 dir) { | |
vec3 go=path(t); | |
vec3 adv=path(t+.7); | |
float hd=de(adv); | |
vec3 advec=normalize(adv-go); | |
float an=adv.x-go.x; an*=min(1.,abs(adv.z-go.z))*sign(adv.z-go.z)*.7; | |
dir.xy*=mat2(cos(an),sin(an),-sin(an),cos(an)); | |
an=advec.y*1.7; | |
dir.yz*=mat2(cos(an),sin(an),-sin(an),cos(an)); | |
an=atan(advec.x,advec.z); | |
dir.xz*=mat2(cos(an),sin(an),-sin(an),cos(an)); | |
return go; | |
} | |
void main(void) { | |
vec2 uv = gl_FragCoord.xy / iResolution.xy*2.-1.; | |
vec2 oriuv=uv; | |
uv.y*=iResolution.y/iResolution.x; | |
vec2 mouse=(iMouse.xy/iResolution.xy-.5)*3.; | |
if (iMouse.z<1.) mouse=vec2(0.,-0.05); | |
float fov=.9-max(0.,.7-iGlobalTime*.3); | |
vec3 dir=normalize(vec3(uv*fov,1.)); | |
dir.yz*=rot(mouse.y); | |
dir.xz*=rot(mouse.x); | |
vec3 from=origin+move(dir); | |
vec3 color=raymarch(from,dir); | |
gl_FragColor = vec4(color,1.); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment