-//
-// is always the first argument and modified in place.
-//
-// Many of the operators partition space into cells. An identifier
-// or cell index is returned, if possible. This return value is
-// intended to be optionally used e.g. as a random seed to change
-// parameters of the distance functions inside the cells.
-//
-// Unless stated otherwise, for cell index 0, is unchanged and cells
-// are centered on the origin so objects don't have to be moved to fit.
-//
-//
-////////////////////////////////////////////////////////////////
-
-// Rotate around a coordinate axis (i.e. in a plane perpendicular to that axis) by angle .
-// Read like this: R(p.xz, a) rotates "x towards z".
-// This is fast if is a compile-time constant and slower (but still practical) if not.
-void pR(inout vec2 p, float a) {
- p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
-}
-
-// Shortcut for 45-degrees rotation
-void pR45(inout vec2 p) {
- p = (p + vec2(p.y, -p.x))*sqrt(0.5);
-}
-
-// Repeat space along one axis. Use like this to repeat along the x axis:
-// - using the return value is optional.
-float pMod1(inout float p, float size) {
- float halfsize = size*0.5;
- float c = floor((p + halfsize)/size);
- p = mod(p + halfsize, size) - halfsize;
- return c;
-}
-
-// Same, but mirror every second cell so they match at the boundaries
-float pModMirror1(inout float p, float size) {
- float halfsize = size*0.5;
- float c = floor((p + halfsize)/size);
- p = mod(p + halfsize,size) - halfsize;
- p *= mod(c, 2.0)*2. - 1.;
- return c;
-}
-
-// Repeat the domain only in positive direction. Everything in the negative half-space is unchanged.
-float pModSingle1(inout float p, float size) {
- float halfsize = size*0.5;
- float c = floor((p + halfsize)/size);
- if (p >= 0.)
- p = mod(p + halfsize, size) - halfsize;
- return c;
-}
-
-// Repeat only a few times: from indices to (similar to above, but more flexible)
-float pModInterval1(inout float p, float size, float start, float stop) {
- float halfsize = size*0.5;
- float c = floor((p + halfsize)/size);
- p = mod(p+halfsize, size) - halfsize;
- if (c > stop) { //yes, this might not be the best thing numerically.
- p += size*(c - stop);
- c = stop;
- }
- if (c = (repetitions/2.)) c = abs(c);
- return c;
-}
-
-// Repeat in two dimensions
-vec2 pMod2(inout vec2 p, vec2 size) {
- vec2 c = floor((p + size*0.5)/size);
- p = mod(p + size*0.5,size) - size*0.5;
- return c;
-}
-
-// Same, but mirror every second cell so all boundaries match
-vec2 pModMirror2(inout vec2 p, vec2 size) {
- vec2 halfsize = size*0.5;
- vec2 c = floor((p + halfsize)/size);
- p = mod(p + halfsize, size) - halfsize;
- p *= mod(c,vec2(2.))*2. - vec2(1);
- return c;
-}
-
-// Same, but mirror every second cell at the diagonal as well
-vec2 pModGrid2(inout vec2 p, vec2 size) {
- vec2 c = floor((p + size*0.5)/size);
- p = mod(p + size*0.5, size) - size*0.5;
- p *= mod(c,vec2(2.))*2. - vec2(1.);
- p -= size/2.;
- if (p.x > p.y) p.xy = p.yx;
- return floor(c/2.);
-}
-
-// Repeat in three dimensions
-vec3 pMod3(inout vec3 p, vec3 size) {
- vec3 c = floor((p + size*0.5)/size);
- p = mod(p + size*0.5, size) - size*0.5;
- return c;
-}
-
-// Mirror at an axis-aligned plane which is at a specified distance from the origin.
-float pMirror (inout float p, float dist) {
- float s = sgn(p);
- p = abs(p)-dist;
- return s;
-}
-
-// Mirror in both dimensions and at the diagonal, yielding one eighth of the space.
-// translate by dist before mirroring.
-vec2 pMirrorOctant (inout vec2 p, vec2 dist) {
- vec2 s = sgn(p);
- pMirror(p.x, dist.x);
- pMirror(p.y, dist.y);
- if (p.y > p.x)
- p.xy = p.yx;
- return s;
-}
-
-// Reflect space at a plane
-float pReflect(inout vec3 p, vec3 planeNormal, float offset) {
- float t = dot(p, planeNormal)+offset;
- if (t < 0.) {
- p = p - (2.*t)*planeNormal;
- }
- return sgn(t);
-}
-
-
-////////////////////////////////////////////////////////////////
-//
-// OBJECT COMBINATION OPERATORS
-//
-////////////////////////////////////////////////////////////////
-//
-// We usually need the following boolean operators to combine two objects:
-// Union: OR(a,b)
-// Intersection: AND(a,b)
-// Difference: AND(a,!b)
-// (a and b being the distances to the objects).
-//
-// The trivial implementations are min(a,b) for union, max(a,b) for intersection
-// and max(a,-b) for difference. To combine objects in more interesting ways to
-// produce rounded edges, chamfers, stairs, etc. instead of plain sharp edges we
-// can use combination operators. It is common to use some kind of "smooth minimum"
-// instead of min(), but we don't like that because it does not preserve Lipschitz
-// continuity in many cases.
-//
-// Naming convention: since they return a distance, they are called fOpSomething.
-// The different flavours usually implement all the boolean operators above
-// and are called fOpUnionRound, fOpIntersectionRound, etc.
-//
-// The basic idea: Assume the object surfaces intersect at a right angle. The two
-// distances and constitute a new local two-dimensional coordinate system
-// with the actual intersection as the origin. In this coordinate system, we can
-// evaluate any 2D distance function we want in order to shape the edge.
-//
-// The operators below are just those that we found useful or interesting and should
-// be seen as examples. There are infinitely more possible operators.
-//
-// They are designed to actually produce correct distances or distance bounds, unlike
-// popular "smooth minimum" operators, on the condition that the gradients of the two
-// SDFs are at right angles. When they are off by more than 30 degrees or so, the
-// Lipschitz condition will no longer hold (i.e. you might get artifacts). The worst
-// case is parallel surfaces that are close to each other.
-//
-// Most have a float argument to specify the radius of the feature they represent.
-// This should be much smaller than the object size.
-//
-// Some of them have checks like "if ((-a < r) && (-b < r))" that restrict
-// their influence (and computation cost) to a certain area. You might
-// want to lift that restriction or enforce it. We have left it as comments
-// in some cases.
-//
-// usage example:
-//
-// float fTwoBoxes(vec3 p) {
-// float box0 = fBox(p, vec3(1));
-// float box1 = fBox(p-vec3(1), vec3(1));
-// return fOpUnionChamfer(box0, box1, 0.2);
-// }
-//
-////////////////////////////////////////////////////////////////
-
-
-// The "Chamfer" flavour makes a 45-degree chamfered edge (the diagonal of a square of size ):
-float fOpUnionChamfer(float a, float b, float r) {
- return min(min(a, b), (a - r + b)*sqrt(0.5));
-}
-
-// Intersection has to deal with what is normally the inside of the resulting object
-// when using union, which we normally don't care about too much. Thus, intersection
-// implementations sometimes differ from union implementations.
-float fOpIntersectionChamfer(float a, float b, float r) {
- return max(max(a, b), (a + r + b)*sqrt(0.5));
-}
-
-// Difference can be built from Intersection or Union:
-float fOpDifferenceChamfer (float a, float b, float r) {
- return fOpIntersectionChamfer(a, -b, r);
-}
-
-// The "Round" variant uses a quarter-circle to join the two objects smoothly:
-float fOpUnionRound(float a, float b, float r) {
- vec2 u = max(vec2(r - a,r - b), vec2(0));
- return max(r, min (a, b)) - length(u);
-}
-
-float fOpIntersectionRound(float a, float b, float r) {
- vec2 u = max(vec2(r + a,r + b), vec2(0));
- return min(-r, max (a, b)) + length(u);
-}
-
-float fOpDifferenceRound (float a, float b, float r) {
- return fOpIntersectionRound(a, -b, r);
-}
-
-
-// The "Columns" flavour makes n-1 circular columns at a 45 degree angle:
-float fOpUnionColumns(float a, float b, float r, float n) {
- if ((a < r) && (b < r)) {
- vec2 p = vec2(a, b);
- float columnradius = r*sqrt(2.)/((n-1.)*2.+sqrt(2.));
- pR45(p);
- p.x -= sqrt(2.)/2.*r;
- p.x += columnradius*sqrt(2.);
- if (mod(n,2.) == 1.) {
- p.y += columnradius;
- }
- // At this point, we have turned 45 degrees and moved at a point on the
- // diagonal that we want to place the columns on.
- // Now, repeat the domain along this direction and place a circle.
- pMod1(p.y, columnradius*2.);
- float result = length(p) - columnradius;
- result = min(result, p.x);
- result = min(result, a);
- return min(result, b);
- } else {
- return min(a, b);
- }
-}
-
-float fOpDifferenceColumns(float a, float b, float r, float n) {
- a = -a;
- float m = min(a, b);
- //avoid the expensive computation where not needed (produces discontinuity though)
- if ((a < r) && (b < r)) {
- vec2 p = vec2(a, b);
- float columnradius = r*sqrt(2.)/n/2.0;
- columnradius = r*sqrt(2.)/((n-1.)*2.+sqrt(2.));
-
- pR45(p);
- p.y += columnradius;
- p.x -= sqrt(2.)/2.*r;
- p.x += -columnradius*sqrt(2.)/2.;
-
- if (mod(n,2.) == 1.) {
- p.y += columnradius;
- }
- pMod1(p.y,columnradius*2.);
-
- float result = -length(p) + columnradius;
- result = max(result, p.x);
- result = min(result, a);
- return -min(result, b);
- } else {
- return -m;
- }
-}
-
-float fOpIntersectionColumns(float a, float b, float r, float n) {
- return fOpDifferenceColumns(a,-b,r, n);
-}
-
-// The "Stairs" flavour produces n-1 steps of a staircase:
-// much less stupid version by paniq
-float fOpUnionStairs(float a, float b, float r, float n) {
- float s = r/n;
- float u = b-r;
- return min(min(a,b), 0.5 * (u + a + abs ((mod (u - a + s, 2. * s)) - s)));
-}
-
-// We can just call Union since stairs are symmetric.
-float fOpIntersectionStairs(float a, float b, float r, float n) {
- return -fOpUnionStairs(-a, -b, r, n);
-}
-
-float fOpDifferenceStairs(float a, float b, float r, float n) {
- return -fOpUnionStairs(-a, b, r, n);
-}
-
-
-// Similar to fOpUnionRound, but more lipschitz-y at acute angles
-// (and less so at 90 degrees). Useful when fudging around too much
-// by MediaMolecule, from Alex Evans' siggraph slides
-float fOpUnionSoft(float a, float b, float r) {
- float e = max(r - abs(a - b), 0.);
- return min(a, b) - e*e*0.25/r;
-}
-
-
-// produces a cylindical pipe that runs along the intersection.
-// No objects remain, only the pipe. This is not a boolean operator.
-float fOpPipe(float a, float b, float r) {
- return length(vec2(a, b)) - r;
-}
-
-// first object gets a v-shaped engraving where it intersect the second
-float fOpEngrave(float a, float b, float r) {
- return max(a, (a + r - abs(b))*sqrt(0.5));
-}
-
-// first object gets a capenter-style groove cut out
-float fOpGroove(float a, float b, float ra, float rb) {
- return max(a, min(a + ra, rb - abs(b)));
-}
-
-// first object gets a capenter-style tongue attached
-float fOpTongue(float a, float b, float ra, float rb) {
- return min(a, max(a - ra, abs(b) - rb));
-}
-
-//#endSection End of library
-
-// https://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl
-// golden_noise
-float noise(in vec2 xy, in float seed){
- return fract(tan(distance(xy*PHI, xy)*seed)*xy.x);
-}
-
-vec3 rnd23(vec2 p)
-{
- vec3 p3 = fract(p.xyx * vec3(.1031, .1030, .0973));
- p3 += dot(p3, p3.yxz+33.33);
- return fract((p3.xxy+p3.yzz)*p3.zyx);
-}
-
-mat2 Rot(float a) {
- float s=sin(a), c=cos(a);
+// Rotate
+mat2 rot2D(float angle) {
+ float s = sin(angle);
+ float c = cos(angle);
return mat2(c, -s, s, c);
}
-float opExtrusion( in vec3 p, in float sdf, in float h )
+// Exponential smoothing
+float smin( float a, float b, float k )
{
- vec2 w = vec2( sdf, abs(p.z) - h);
- return min(max(w.x,w.y),0.0) + length(max(w,0.0));
+ k *= 1.0;
+ float r = exp2(-a/k) + exp2(-b/k);
+ return -k*log2(r);
}
-float sdCog2d(vec2 pos) {
- float r = length(pos)*2.;
- float a = atan(pos.y,pos.x);
- float f = 1. - smoothstep(-0.2, .8, sin(a * 12.))*0.14;
- f = smoothstep(f,f + 2.,r);
- return f;
-}
-
-float sdCog(vec3 pos, float angle) {
- pos.xy *= Rot(angle);
- float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.05);
- float d2 = fCapsule(pos, vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2);
- return 0.8 * fOpDifferenceRound(d1,d2,0.05)-0.003;
-}
-
-float sdText(vec3 pos, float angle) {
- //pos.xy *= Rot(angle);
- vec3 color = texture2D(texts, getUV(vec2( 0.,0.))).rgb;
-
- //gl_FragColor = vec4(vec3(color), 1.);
-
- //float d1 = opExtrusion(pos, , 0.1);
- return 0.;
-// return d1;
+float smax( float a, float b, float k )
+{
+ float h = max(k-abs(a-b),0.0);
+ return max(a, b) + h*h*0.25/k;
}
-float sdHex(vec3 pos, float i, float angle) {
- vec3 po = pos;
+/////////////////
+// GEOMETRY //
+/////////////////
+
+float sdBox( in vec2 p, in vec2 r )
+{
+ return length( max(abs(p)-r,0.0) );
+}
+
+float sdBox2(vec3 p, vec3 b) {
+ vec3 q = abs(p) - b;
+ return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
+}
+
+float sdSphere(vec3 p, float r){
+ return length(p) -r;
+}
+
+float sdTriPrism( vec3 p, vec2 h, float rot )
+{
+ p.xy *= rot2D(rot);
+ const float k = sqrt(3.0);
+ h.x *= 0.5*k;
+ p.xy /= h.x;
+ p.x = abs(p.x) - 1.0;
+ p.y = p.y + 1.0/k;
+ if( p.x+k*p.y>0.0 ) p.xy=vec2(p.x-k*p.y,-k*p.x-p.y)/2.0;
+ p.x -= clamp( p.x, -2.0, 0.0 );
+ float d1 = length(p.xy)*sign(-p.y)*h.x;
+ float d2 = abs(p.z)-h.y;
+
+ return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
+}
+
+
+//////////////////
+// ANIMATION //
+//////////////////
+
+// Rotate ring with duration d and startTime s
+float ringRotateFunc(float d, float s, float timeFact) {
+ const float TWOPI = 6.28318530718;
+ float maxCycles = d;
+ float startTime = s;
+ float phase = ((u_time * timeFact) - startTime) / TWOPI;
+ phase = min(phase, maxCycles);
+return TWOPI * phase;
+}
+
+// Animate ring movements
+vec3 ringAnim( in vec3 p) {
+
+const float STARTDELAY = 2.0;
+
+float factor = 9.0+9.0*clamp(sin(ringRotateFunc(2.0, 0.0, 1.0) * 0.05), -0.9, 0.9);
+
+// delay start
+if( u_time >= STARTDELAY ) {
+factor = 9.0+9.0*clamp(sin(ringRotateFunc(2.0, 0.0, 1.0) * 0.05), -0.9, 0.9);
+p.xy = rot2D(factor) * p.xy;
+}
+
+if(u_time >= 14.0) {
+factor = 9.0+9.0*clamp(sin(ringRotateFunc(2.0, 14.0, 1.0) * 0.05), -0.9, 0.9);
+p.xy = rot2D(factor * -1.0) * p.xy;
+}
+
+return p;
+}
+
+// Animate prism movements
+float prismAnim(in float x, in float delay) {
+
+
+if(u_time >= delay) {
+x += (0.045*clamp(sin((ringRotateFunc(2.4, delay*10.0, 10.0) * 0.4)),-0.9, 0.9));
+}
+
+return x;
+}
+
+
+//////////////
+// SCENE //
+//////////////
+
+vec2 map( in vec3 p)
+{
+ // Stargate
+
+ // Ring boxes
+ const float an = 6.283185/24.0;
+ float sector = round(atan(p.y,p.x)/an);
+ float angrot = sector*an;
+ vec3 q = p;
+ q.xy = mat2(cos(angrot),-sin(angrot),
+ sin(angrot), cos(angrot))*q.xy;
+ float d = sdBox( q.xy - vec2(1.8,0.0), vec2(0.24,0.14) ) - 0.02;
+
+ // Main ring
+ float d2 = abs(length(p.xy) - 1.8) - 0.2;
+ d = min(d,d2);
+
+ // Inner ring
+ float d3 = abs(length(p.xy) - 1.75) - 0.08;
+ d3 = smax( d3, abs(p.z - 0.1)-0.04, 0.005 );
+ d = max(-d3,d);
+
+ // Depth slice rings
+ d = smax( d, abs(p.z)-0.1, 0.02 );
+
+ // Prisms
+ float index = 1.0;
+ for(int i=0; i<8; i++ ) {
- po.xz *= Rot(angle);
- po.yz *= Rot(angle);
- pR(po.yz, PI/2.);
+ //vec3 p2 = prismAnim(p);
+
+ float secDist = 6.283185 / 8.0; // sector distance
+ float angle = ((24.67 / 6.283185 )); // sector size
+ vec3 q = p;
+ float rotationIncrement = angle + (index * secDist);
- float d1 = fHexagonCircumcircle(po, vec2(0.5+i, .1));
- float d2 = fHexagonCircumcircle(po, vec2(0.2+i, .1));
- return fOpDifferenceRound(d1,d2,0.1);
-
-}
-
-// Scene
-vec2 mapScene(in vec3 p) {
- float mat = 0.;
- float d = 1e10;
-
- //float dGround = p.y + 2.5;
- //d = min(d, dGround);
-
- vec3 po = p;
- //po.y += sin(u_time);
- // pMod3(po, vec3(3.));
- po.xy *= scale(vec2(1.3, 1.3));
-
- const float num = 6.;
- for (float i = 1.; i <= num; i++) {
- // pos.z += i*.1;
- float a = sdHex(po,i*0.35, u_time + abs( 2. + 0.4 * sin(u_time)) * i*3.1415/num);
- d = min(d,a);
- if (d == a) mat = 1. + mod(i,3.);
- }
-
-
- //float c2 = sdText(p, u_time);
- //d = min(d, c2);
- //if ( d == c2) mat = 4.;
-
- // float c3 = fBox(p+vec3(0.5, .87, 0.), vec3(1., 1.,1.));
- // d = min(d, c3);
-
-
-
- // if ( d == c1) mat = 1.;
-
- //if ( d == c3) mat = 3.;
-
- return vec2(d, mat);
-}
-
-vec3 castRay(vec3 ro, vec3 rd, inout vec3 pos) {
- float t = 0.0;
- float mat = 0.;
- float hit = 0.;
- for(int i=0; i < 150; i++) {
- pos = ro + rd * t;
- vec2 res = mapScene(pos);
- t += res.x;
- mat = res.y;
- if (t > 80.) break;
- if (res.x < abs(0.001*t) ) {
- hit = 1.;
- break;
- }
- }
- if (t > 80.) t = -1.0;
- return vec3(t, mat, hit);
-}
-
-
-vec3 castReflectedRay(vec3 ro, vec3 rd, vec3 pos) {
- float t = 0.0;
- float mat = 0.;
- float hit = 0.;
- for(int i=0; i < 50; i++) {
- pos = ro + rd * t;
- vec2 res = mapScene(pos);
- t += res.x;
- mat = res.y;
- if (t > 40.) break;
- if (res.x < abs(0.001*t) ) {
- hit = 1.;
- break;
+ // Nudge first and the last prism out of the ground
+ if (i == 1) {
+ rotationIncrement = rotationIncrement + 0.2;
}
+ if (i == 7) {
+ rotationIncrement = rotationIncrement - 0.2;
+ }
+
+ float prismSector = round(atan(p.y,p.x)/(rotationIncrement));
+ q.xy = rot2D(rotationIncrement) * q.xy;
+
+ // We can now call each prism by it's index
+ // draw all except the middle bottom prism
+ if (i > 0) {
+ q.x = q.x - 1.95;
+
+ if(i == 1) {
+ q.x = prismAnim(q.x, 13.0);
+ }
+
+ if(i == 2) {
+ q.x = prismAnim(q.x, 26.0);
+ }
+
+ float d4 = sdTriPrism(vec3(q.x, q.y - 0.0 , q.z - 0.0), vec2(0.2,0.2), 0.5) - 0.02;
+ d = min(d, d4);
+ }
+
+ index += 1.0;
}
- if (t > 40.) t = -1.0;
- return vec3(t, mat, hit);
+
+ //Rotating glyphs
+ vec3 p2 = ringAnim(p);
+ float an2 = (6.283185/32.0);
+ float sector2 = round((atan(p2.y,p2.x)/an2) );
+ float angrot2 = sector2*an2;
+ vec3 q2 = p2;
+ q2.xy = rot2D(angrot2)*q2.xy;
+ float d5 = sdBox2( q2.xyz - vec3(1.75,0.0,0.0), vec3(0.04, 0.14, 0.05) ) - 0.02;
+ d = min(d, d5);
+
+
+ // Gate Base
+ const float stepHeight = 0.1;
+ float stepDist = 1.5;
+ const float stepWidth = 2.0;
+
+ for(int i = 0; i < 4; i++) {
+ float step = sdBox2(vec3(p.x,p.y+stepDist,p.z), vec3(stepWidth,stepHeight,stepDist)) - 0.05;
+ d = min(d, step);
+ stepDist += stepHeight * 2.0;
+ }
+
+ return vec2( d );
}
-float softshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float w )
-{
- float res = 1.0;
- float t = mint;
- for( int i=0; i<40; i++ )
- {
- if (t > maxt) break;
- float h = mapScene(ro + t*rd).x;
- res = min( res, h/(w*t) );
- t += clamp(h, 0.005, 0.50);
- if( res < -1.0 || t>maxt ) break;
+////////////////
+// DRAWING //
+////////////////
+float rayMarch(vec3 ro, vec3 rd) {
+
+ float t = 0.; // total distance travelled
+ float d;
+ // Raymarching
+ for (int i = 0; i < 80; i++) {
+ vec3 p = ro + rd * t; // "cast" rays
+
+ d = map(p).x; // Get distance to objects
+
+
+ t += d; // "march" the ray
+
+ if (d< .001 || t>100.) break;
}
- res = max(res,-1.0);
- return 0.25*(1.0+res)*(1.0+res)*(2.0-res);
+ return t;
}
+vec3 getNormal(vec3 p) {
+ float d = map(p).x;
+ vec2 e = vec2(.01, 0);
-float castShadow(vec3 ro, vec3 rd) {
- float res = 1.0;
- float t = 0.001;
- for(int i = 0; i < 40; i++) {
- float h = mapScene(ro + t* rd).x;
- res = min(res, 10.0*h/t);
- if (abs(h) < (0.001*t) ) break;
- t += h;
- if (t > 20.) break;
- }
- return clamp(res,0., 1.);
-}
-
-vec3 calcNormal(vec3 pos) {
- vec2 e = vec2(.001, 0.);
- vec3 n = vec3( mapScene(pos+e.xyy).x - mapScene(pos-e.xyy).x,
- mapScene(pos+e.yxy).x - mapScene(pos-e.yxy).x,
- mapScene(pos+e.yyx).x - mapScene(pos-e.yyx).x
- );
+ vec3 n = d - vec3(
+ map(p-e.xyy).x,
+ map(p-e.yxy).x,
+ map(p-e.yyx).x);
return normalize(n);
}
-vec3 fresnel( vec3 F0, vec3 h, vec3 l ) {
- return F0 + ( 1.0 - F0 ) * pow( clamp( 1.0 - dot( h, l ), 0.0, 1.0 ), 5.0 );
+float getLight(vec3 p, vec3 lightPos, float intensity, float shadow) {
+ vec3 l = normalize(lightPos - p);
+ vec3 n = getNormal(p);
+
+ float dif = clamp(dot(n, l), 0., intensity);
+
+ // Shadows
+ float d = rayMarch(p+n*.0025, l);
+ if(d 0.) {
- vec3 nor = calcNormal(hitPos);
- col = shading(hitPos, nor, rayDir , t.y);
- float fogAmount = 0.04;
- col = col*exp(-t.x*fogAmount) + applyFog(col, t.x, rd, vec3(0., .3, -1.), fogAmount) * (1.0-exp(-t.x*fogAmount));
-
- rayDir = normalize(reflect(rayDir, nor));
- vec3 rayOrigin = hitPos + (rayDir * 0.01);
- vec3 t2 = castReflectedRay(rayOrigin, rayDir, hitPos);
-
- if (t2.z > 0.) {
- hitPos = rayOrigin + rayDir * t2.x;
- nor = calcNormal(hitPos);
- col += 0.1 * shading(hitPos, nor, rayDir , t2.y);
-
- /* rayDir = normalize(reflect(rayDir, nor));
- rayOrigin = hitPos + (rayDir * 0.01);
- vec3 t3 = castReflectedRay(rayOrigin, rayDir, hitPos);
-
- if (t3.z > 0.) {
- hitPos = rayOrigin + rayDir * t3.x;
- nor = calcNormal(hitPos);
- col += 0.025 * shading(hitPos, nor, rayDir , t3.y);
- } */
- }
- }
- // pixelColor*exp(-distance*b) + fogColor*(1.0-exp(-distance*b));
-
- return col;
-}
-
-
-void main()
+void main( )
{
-
- vec3 finalColor = vec3(0.);
- const float AA_SIZE = 1.;
- float count = 0.0;
-/*
- for (float aaY = 0.0; aaY < AA_SIZE; aaY++) {
- for (float aaX = 0.0; aaX < AA_SIZE; aaX++) {
- finalColor += render(getUV(vec2( aaX, aaY)));
- count += 1.0;
+ // Initialization
+ vec2 uv = (gl_FragCoord.xy * 2. - u_resolution.xy) / u_resolution.y;
+ //vec2 m = iMouse.xy/u_resolution.xy;
+
+ vec3 ro = vec3(0, 2, 3);
+ //ro.yz *= rot2D(-m.y*3.14+1.);
+ //ro.xz *= rot2D(-m.x*6.2831);
+
+ //vec3 ro = vec3(0,0,-3); // ray origin
+
+ vec3 rd = GetRayDir(uv, ro, vec3(0, 0., 0.), 1.); // ray direction
+ vec3 col = vec3(0); // color
+
+ float d = rayMarch(ro, rd);
+
+ if (d < 1000.)
+ {
+ // Lighting
+ vec3 p = ro + rd * d;
+
+ float mat = map(p).y;
+ // Light 1
+ // Light 1 Position
+ vec3 lightPos1 = vec3( 3, 5, 4);
+ // Light 1 Arguments
+ // 1: Ray starting point
+ // 2: Light position
+ // 3: Light intensity
+ // 4: Shadow intensity
+ float dif = getLight(p, lightPos1, 0.75, 0.2);
+ // Color for light 1
+ col = vec3(dif * vec3(1));
+
+ // Light 2
+ vec3 lightPos2 = vec3( -3, 5, -4);
+ dif = getLight(p, lightPos2, 0.75, 0.1);
+ // Color for light 2
+ col += vec3(dif * vec3(0.5,0.2,0.1));
+
+ if(mat==0.){
+ col *= vec3(0,0,1);
}
- }
- finalColor /= count; */
- finalColor += render(getUV(vec2( 0.,0.)));
-
- finalColor = postProcess(finalColor);
+ else if(mat==1.){
+ col *= vec3(0,1,0);
+ }
+ else if(mat==2.){
+ col *= vec3(1,0,0);
+ }
+ }
- gl_FragColor = vec4(finalColor, 1.);
-
-}
\ No newline at end of file
+ gl_FragColor = vec4(col, 1);
+}
diff --git a/shader_minified.h b/shader_minified.h
index b1e807c..0230763 100644
--- a/shader_minified.h
+++ b/shader_minified.h
@@ -1,228 +1,167 @@
// Generated with Shader Minifier 1.3.6 (https://github.com/laurentlb/Shader_Minifier/)
#ifndef SHADER_MINIFIED_H_
# define SHADER_MINIFIED_H_
-# define VAR_texts "k"
-# define VAR_texture_sampler "m"
-# define VAR_u_resolution "v"
-# define VAR_u_time "f"
+# define VAR_texts "f"
+# define VAR_texture_sampler "x"
+# define VAR_u_resolution "y"
+# define VAR_u_time "v"
const char *__temp_cleaned_shader_glsl =
- "uniform vec2 v;"
- "uniform float f;"
- "uniform sampler2D m,k;struct Ray{vec3 rd;vec3 dir;};"
- "vec2 s()"
+ "uniform vec2 y;"
+ "uniform float v;"
+ "uniform sampler2D x,f;"
+ "mat2 n(float v)"
"{"
- "vec2 r=2.*((gl_FragCoord.xy+vec2(0)*.5)/v.xy-.5);"
- "r.x*=v.x/v.y;"
- "return r;"
+ "float x=sin(v),y=cos(v);"
+ "return mat2(y,-x,x,y);"
"}"
- "mat2 n()"
+ "float n(float v,float x,float y)"
"{"
- "vec2 v=vec2(1.3);"
- "return mat2(1./v.x,0.,0.,1./v.y);"
+ "float m=max(y-abs(v-x),0.);"
+ "return max(v,x)+m*m*.25/y;"
"}"
- "const float i=2.*acos(-1.),c=sqrt(5.)*.5+.5;"
- "float n(vec3 v,vec2 x)"
+ "float n(vec3 v,vec3 y)"
"{"
- "vec3 f=abs(v);"
- "return max(f.y-x.y,max(f.x*sqrt(3.)*.5+f.z*.5,f.z)-x.x);"
+ "vec3 x=abs(v)-y;"
+ "return length(max(x,0.))+min(max(x.x,max(x.y,x.z)),0.);"
"}"
- "void n(inout vec2 v)"
+ "float s(vec3 v)"
"{"
- "float f=acos(-1.)/2.;"
- "v=cos(f)*v+sin(f)*vec2(v.y,-v.x);"
+ "vec2 f=vec2(.2);"
+ "v.xy*=n(.5);"
+ "const float y=sqrt(3.);"
+ "f.x*=.5*y;"
+ "v.xy/=f.x;"
+ "v.x=abs(v.x)-1.;"
+ "v.y=v.y+1./y;"
+ "if(v.x+y*v.y>0.)"
+ "v.xy=vec2(v.x-y*v.y,-y*v.x-v.y)/2.;"
+ "v.x-=clamp(v.x,-2.,0.);"
+ "float x=length(v.xy)*sign(-v.y)*f.x,a=abs(v.z)-f.y;"
+ "return length(max(vec2(x,a),0.))+min(max(x,a),0.);"
"}"
- "float s(float v,float f)"
+ "float s(float x,float y,float m)"
"{"
- "return min(-.1,max(v,f))+length(max(vec2(.1+v,.1+f),vec2(0)));"
+ "float f=(v*m-y)/(2.*acos(-1.));"
+ "f=min(f,x);"
+ "return 2.*acos(-1.)*f;"
"}"
- "float t(vec2 v,float f)"
+ "vec3 m(vec3 y)"
"{"
- "return fract(tan(distance(v*c,v)*f)*v.x);"
+ "float x=9.+9.*clamp(sin(s(2.,0.,1.)*.05),-.9,.9);"
+ "if(v>=2.)"
+ "x=9.+9.*clamp(sin(s(2.,0.,1.)*.05),-.9,.9),y.xy=n(x)*y.xy;"
+ "if(v>=14.)"
+ "x=9.+9.*clamp(sin(s(2.,14.,1.)*.05),-.9,.9),y.xy=n(x*-1.)*y.xy;"
+ "return y;"
"}"
- "mat2 s(float v)"
+ "float m(float x,float y)"
"{"
- "float f=sin(v),x=cos(v);"
- "return mat2(x,-f,f,x);"
+ "if(v>=y)"
+ "x+=.045*clamp(sin(s(2.4,y*10.,10.)*.4),-.9,.9);"
+ "return x;"
"}"
- "float n(vec3 v,float f,float x)"
+ "vec2 a(vec3 v)"
"{"
- "vec3 r=v;"
- "r.xz*=s(x);"
- "r.yz*=s(x);"
- "n(r.yz);"
- "float i=n(r,vec2(.5+f,.1)),y=n(r,vec2(.2+f,.1));"
- "return s(i,-y);"
- "}"
- "vec2 t(vec3 v)"
- "{"
- "float x=0.,r=1e10;"
- "vec3 i=v;"
- "i.xy*=n();"
- "for(float m=1.;m<=6.;m++)"
+ "float x=round(atan(v.y,v.x)/.261799375)*.261799375;"
+ "vec3 f=v;"
+ "f.xy=mat2(cos(x),-sin(x),sin(x),cos(x))*f.xy;"
+ "float y=length(max(abs(f.xy-vec2(1.8,0))-vec2(.24,.14),0.))-.02;"
+ "y=min(y,abs(length(v.xy)-1.8)-.2);"
+ "float i=abs(length(v.xy)-1.75)-.08;"
+ "i=n(i,abs(v.z-.1)-.04,.005);"
+ "y=max(-i,y);"
+ "y=n(y,abs(v.z)-.1,.02);"
+ "float r=1.;"
+ "for(int a=0;a<8;a++)"
"{"
- "float y=n(i,m*.35,f+abs(2.+.4*sin(f))*m*3.1415/6.);"
- "r=min(r,y);"
- "if(r==y)"
- "x=1.+mod(m,3.);"
- "}"
- "return vec2(r,x);"
- "}"
- "vec3 s(vec3 v,vec3 f,inout vec3 x)"
- "{"
- "float r=0.,i=0.,y=0.;"
- "for(int m=0;m<150;m++)"
- "{"
- "x=v+f*r;"
- "vec2 n=t(x);"
- "r+=n.x;"
- "i=n.y;"
- "if(r>80.)"
- "break;"
- "if(n.x0)"
"{"
- "y=1.;"
- "break;"
+ "c.x=c.x-1.95;"
+ "if(a==1)"
+ "c.x=m(c.x,13.);"
+ "if(a==2)"
+ "c.x=m(c.x,26.);"
+ "float l=s(vec3(c))-.02;"
+ "y=min(y,l);"
"}"
+ "r+=1.;"
"}"
- "if(r>80.)"
- "r=-1.;"
- "return vec3(r,i,y);"
- "}"
- "vec3 t(vec3 v,vec3 f,vec3 x)"
- "{"
- "float r=0.,i=0.,y=0.;"
- "for(int m=0;m<50;m++)"
+ "vec3 a=m(v);"
+ "float c=6.283185/32.;"
+ "vec3 l=a;"
+ "l.xy=n(round(atan(a.y,a.x)/c)*c)*l.xy;"
+ "float z=n(l.xyz-vec3(1.75,0,0),vec3(.04,.14,.05))-.02;"
+ "y=min(y,z);"
+ "float e=1.5;"
+ "for(int u=0;u<4;u++)"
"{"
- "x=v+f*r;"
- "vec2 n=t(x);"
- "r+=n.x;"
- "i=n.y;"
- "if(r>40.)"
- "break;"
- "if(n.x40.)"
- "r=-1.;"
- "return vec3(r,i,y);"
+ "return vec2(y);"
"}"
- "float x(vec3 v,vec3 x)"
+ "float a(vec3 x,vec3 y)"
"{"
- "float r=1.,f=.01;"
- "for(int i=0;i<40;i++)"
+ "float f=0.,v;"
+ "for(int i=0;i<80;i++)"
"{"
- "if(f>30.)"
- "break;"
- "float m=t(v+f*x).x;"
- "r=min(r,m/(18.*f));"
- "f+=clamp(m,.005,.5);"
- "if(r<-1.||f>30.)"
+ "vec3 m=x+y*f;"
+ "v=a(m).x;"
+ "f+=v;"
+ "if(v<.001||f>1e2)"
"break;"
"}"
- "r=max(r,-1.);"
- "return.25*(1.+r)*(1.+r)*(2.-r);"
+ "return f;"
"}"
- "vec3 x(vec3 v)"
+ "vec3 h(vec3 v)"
"{"
- "vec2 f=vec2(.001,0);"
- "vec3 r=vec3(t(v+f.xyy).x-t(v-f.xyy).x,t(v+f.yxy).x-t(v-f.yxy).x,t(v+f.yyx).x-t(v-f.yyx).x);"
- "return normalize(r);"
+ "float y=a(v).x;"
+ "vec2 x=vec2(.01,0);"
+ "vec3 f=y-vec3(a(v-x.xyy).x,a(v-x.yxy).x,a(v-x.yyx));"
+ "return normalize(f);"
"}"
- "vec3 e(vec3 v,vec3 f)"
+ "float a(vec3 v,vec3 x,float y)"
"{"
- "vec3 x=vec3(.5454);"
- "return x+(1.-x)*pow(clamp(1.-dot(v,f),0.,1.),5.);"
+ "vec3 f=normalize(x-v),m=h(v);"
+ "float i=clamp(dot(m,f),0.,.75),c=a(v+m*.0025,f);"
+ "if(c0.)"
- "{"
- "vec3 k=x(n);"
- "m=e(n,k,i,d.y);"
- "m=m*exp(-d.x*.04)+mix(m,mix(vec3(.3686,.2431,.4392),vec3(.4,.7294,.9216),pow(max(dot(c,vec3(0,.3,-1)),0.),8.)),1.-exp(-d.x*.04))*(1.-exp(-d.x*.04));"
- "i=normalize(reflect(i,k));"
- "vec3 g=n+i*.01,a=t(g,i,n);"
- "if(a.z>0.)"
- "n=g+i*a.x,k=x(n),m+=.1*e(n,k,i,a.y);"
- "}"
- "return m;"
+ "vec3 x=normalize(vec3(0)-y),f=normalize(cross(vec3(0,1,0),x));"
+ "return normalize(x+v.x*f+v.y*cross(x,f));"
"}"
"void main()"
"{"
- "vec3 v=vec3(0);"
- "v+=p(s());"
- "v=e(v);"
- "gl_FragColor=vec4(v,1);"
+ "vec2 x=(gl_FragCoord.xy*2.-y.xy)/y.y;"
+ "vec3 v=vec3(0,2,3),f=h(x,v),i=vec3(0);"
+ "float c=a(v,f);"
+ "if(c<1e3)"
+ "{"
+ "vec3 m=v+f*c;"
+ "float l=a(m).y,r=a(m,vec3(3,5,4),.2);"
+ "i=vec3(r*vec3(1));"
+ "r=a(m,vec3(-3,5,-4),.1);"
+ "i+=vec3(r*vec3(.5,.2,.1));"
+ "if(l==0.)"
+ "i*=vec3(0,0,1);"
+ "else if(l==1.)"
+ "i*=vec3(0,1,0);"
+ "else if(l==2.)"
+ "i*=vec3(1,0,0);"
+ "}"
+ "gl_FragColor=vec4(i,1);"
"}";
#endif // SHADER_MINIFIED_H_