Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define MAX_STEPS 100
- #define MAX_DIST 100.
- #define SURF_DIST .001
- mat2 Rot(float a) {
- float s = sin(a);
- float c = cos(a);
- return mat2(c, -s, s, c);
- }
- float sdCylinder(vec3 p, vec3 a, vec3 b, float r) {
- vec3 ab = b-a;
- vec3 ap = p-a;
- float t = dot(ab, ap) / dot(ab, ab);
- vec3 c = a + t*ab;
- float x = length(p-c)-r;
- float y = (abs(t-.5)-.5)*length(ab);
- float e = length(max(vec2(x, y), 0.));
- float i = min(max(x, y), 0.);
- return e+i;
- }
- float sdTorus(vec3 p, vec2 r) {
- float x = length(p.xz)-r.x;
- return length(vec2(x, p.y))-r.y;
- }
- vec3 PlaneNormal(vec3 v0, vec3 v1, vec3 v2)
- {
- vec3 x = v0 - v1;
- vec3 y = v0 - v2;
- vec3 n = cross(x, y);
- return vec3((n.y < 0.)?-n:n);
- }
- float dot2( in vec3 v ) { return dot(v,v); }
- vec4 udTriangle( vec3 p, vec3 a, vec3 b, vec3 c )
- {
- vec3 ba = b - a; vec3 pa = p - a;
- vec3 cb = c - b; vec3 pb = p - b;
- vec3 ac = a - c; vec3 pc = p - c;
- vec3 nor = cross( ba, ac );
- return vec4(sqrt(
- (sign(dot(cross(ba,nor),pa)) +
- sign(dot(cross(cb,nor),pb)) +
- sign(dot(cross(ac,nor),pc))<2.0)
- ?
- min( min(
- dot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),
- dot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),
- dot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )
- :
- dot(nor,pa)*dot(nor,pa)/dot2(nor)), PlaneNormal(a, b, c));
- }
- vec4 min2( vec4 d1, vec4 d2 )
- {
- return (d1.x < d2.x) ? d1 : d2;
- }
- vec4 Planes(vec3 p)
- {
- vec4 p0, p1, p2, p3;
- vec3 a1 = vec3(-3, 1., -1);
- vec3 a2 = vec3(-3., 3., 0.);
- vec3 a3 = vec3(-2., 1., 1.);
- vec3 a4 = vec3(-6., 1., 1.);
- p0 = udTriangle(p, a1, a2, a3);
- p1 = udTriangle(p, a1, a2, a4);
- p2 = udTriangle(p, a2, a3, a4);
- p3 = udTriangle(p, a1, a3, a4);
- return min2(min2(min2(p0, p1), p2), p3);
- }
- float GetDist(vec3 p)
- {
- float planeDist = p.y;
- float td = sdTorus(p-vec3(0,.5,0), vec2(1.5, .4));
- float bd = Planes(p).x;
- float cyld = sdCylinder(p, vec3(0, .7, -3), vec3(3, .7, -1), .3);
- float d = min(td, planeDist);
- d = min(d, bd);
- d = min(d, cyld);
- return d;
- }
- float GetDist2(vec3 p) {
- vec4 s = vec4(0, 1, 6, 1);
- float td = sdTorus(p-vec3(0,.5,0), vec2(1.5, .4));
- float bd = Planes(p).x;
- float cyld = sdCylinder(p, vec3(0, .7, -3), vec3(3, .7, -1), .3);
- float d = min(td, bd);
- d = min(d, cyld);
- return d;
- }
- float RayMarch(vec3 ro, vec3 rd) {
- float dO=0.;
- for(int i=0; i<MAX_STEPS; i++) {
- vec3 p = ro + rd*dO;
- float dS = GetDist(p);
- dO += dS;
- if(dO>MAX_DIST || dS<SURF_DIST) break;
- }
- return dO;
- }
- float RayMarch2(vec3 ro, vec3 rd) {
- float dO=0.;
- for(int i=0; i<MAX_STEPS; i++) {
- vec3 p = ro + rd*dO;
- float dS = GetDist2(p);
- dO += dS;
- if(dO>MAX_DIST || dS<SURF_DIST) break;
- }
- return dO;
- }
- vec3 GetNormal(vec3 p) {
- float d = GetDist(p);
- vec2 e = vec2(.001, 0);
- vec3 n = d - vec3(
- GetDist(p-e.xyy),
- GetDist(p-e.yxy),
- GetDist(p-e.yyx));
- if(Planes(p).x <= .01 && Planes(p).x >= 0.)
- {
- return normalize(Planes(p).yzw);
- }
- return normalize(n);
- }
- float GetLight(vec3 p) {
- vec3 lightPos = vec3(0, 5, 6);
- lightPos.xz += vec2(sin(iTime), cos(iTime))*10.;
- vec3 l = normalize(lightPos-p);
- vec3 n = GetNormal(p);
- float dif = clamp(dot(n, l), 0., 1.);
- float d = RayMarch(p+n*SURF_DIST*2., l);
- if(d<length(lightPos-p)) dif *= .1;
- return dif;
- }
- vec3 Rot1(vec2 uv, vec3 p, vec3 l, float z) {
- vec3 f = normalize(l-p),
- r = normalize(cross(vec3(0,1,0), f)),
- u = cross(f,r),
- c = p+f*z,
- i = c + uv.x*r + uv.y*u,
- d = normalize(i-p);
- return d;
- }
- void mainImage( out vec4 fragColor, in vec2 fragCoord )
- {
- vec2 uv = (fragCoord-.5*iResolution.xy)/iResolution.y;
- vec3 col = vec3(0);
- vec3 ro = vec3(2, 2, -5);
- ro.yz *= Rot(.4);
- ro.xz *= Rot(iTime*.2);
- vec3 rd = Rot1(uv, ro, vec3(0,0,0), .7);
- float d = RayMarch(ro, rd);
- vec3 p = ro + rd * d;
- float dif = GetLight(p);
- col = vec3(dif);
- vec3 p_m = vec3(0.);
- if(p.y <= SURF_DIST)
- {
- rd = normalize(vec3(rd.x, -rd.y+(0.1*cos(iTime - (p.x + p.z)*9.3)), rd.z));
- d = RayMarch2(p, rd);
- p_m = p + rd * d;
- dif = GetLight(p_m);
- col = vec3(dif, dif, dif + 0.3);
- }
- fragColor = vec4(col,1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement