|
|
|
@ -1,5 +1,7 @@ |
|
|
|
# version 330 |
|
|
|
|
|
|
|
#define ZERO 0 |
|
|
|
|
|
|
|
// Input vertex attributes (from vertex shader) |
|
|
|
in vec2 fragTexCoord; |
|
|
|
in vec4 fragColor; |
|
|
|
@ -13,10 +15,12 @@ uniform vec3 camPos; |
|
|
|
uniform vec3 camDir; |
|
|
|
uniform vec2 screenCenter; |
|
|
|
|
|
|
|
#define ZERO 0 |
|
|
|
// Output fragment color |
|
|
|
out vec4 finalColor; |
|
|
|
|
|
|
|
// https://learnopengl.com/Advanced-OpenGL/Depth-testing |
|
|
|
float CalcDepth(in vec3 rd, in float Idist){ |
|
|
|
float CalcDepth(in vec3 rd, in float Idist) |
|
|
|
{ |
|
|
|
float local_z = dot(normalize(camDir),rd)*Idist; |
|
|
|
return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01); |
|
|
|
} |
|
|
|
@ -26,15 +30,13 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w) |
|
|
|
{ |
|
|
|
p.x = abs(p.x); |
|
|
|
float l = length(p.xy); |
|
|
|
p.xy = mat2(-c.x, c.y, |
|
|
|
c.y, c.x)*p.xy; |
|
|
|
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
|
|
|
(p.x>0.0)?p.y:l); |
|
|
|
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
|
|
|
p.xy = mat2(-c.x, c.y, c.y, c.x)*p.xy; |
|
|
|
p.xy = vec2(((p.y > 0.0) || (p.x > 0.0))? p.x : l*sign(-c.x), (p.x>0.0)? p.y : l); |
|
|
|
p.xy = vec2(p.x, abs(p.y - r)) - vec2(le, 0.0); |
|
|
|
|
|
|
|
vec2 q = vec2(length(max(p.xy,0.0)) k">+ min(0.0err">,max(p.x,p.y)),p.z); |
|
|
|
vec2 q = vec2(length(max(p.xy, 0.0)) + min(0.0, max(p.x, p.y)), p.z); |
|
|
|
vec2 d = abs(q) - w; |
|
|
|
return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
|
|
|
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)); |
|
|
|
} |
|
|
|
|
|
|
|
// r = sphere's radius |
|
|
|
@ -44,17 +46,16 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t) |
|
|
|
{ |
|
|
|
// Six way symetry Transformation |
|
|
|
vec3 ap = abs(p); |
|
|
|
if (ap.x < max(ap.y, ap.z)){ |
|
|
|
if (ap.x < max(ap.y, ap.z)) |
|
|
|
{ |
|
|
|
if (ap.y < ap.z) ap.xz = ap.zx; |
|
|
|
else ap.xy = ap.yx; |
|
|
|
} |
|
|
|
|
|
|
|
vec2 q = vec2(length(ap.yz), ap.x); |
|
|
|
|
|
|
|
float w = sqrt(r*r-h*h); |
|
|
|
|
|
|
|
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : |
|
|
|
abs(length(q)-r)) - t; |
|
|
|
return ((h*q.x < w*q.y)? length(q - vec2(w, h)) : abs(length(q) - r)) - t; |
|
|
|
} |
|
|
|
|
|
|
|
// https://iquilezles.org/articles/boxfunctions |
|
|
|
@ -65,44 +66,47 @@ vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) |
|
|
|
vec3 k = abs(m)*rad; |
|
|
|
vec3 t1 = -n - k; |
|
|
|
vec3 t2 = -n + k; |
|
|
|
return vec2(max(max(t1.x, t1.y), t1.z), |
|
|
|
min(min(t2.x, t2.y), t2.z)); |
|
|
|
|
|
|
|
return vec2(max(max(t1.x, t1.y), t1.z), min(min(t2.x, t2.y), t2.z)); |
|
|
|
} |
|
|
|
|
|
|
|
vec2 opU(vec2 d1, vec2 d2) |
|
|
|
{ |
|
|
|
return (d1.x<d2.x) ? d1 : d2; |
|
|
|
return (d1.x < d2.x)? d1 : d2; |
|
|
|
} |
|
|
|
|
|
|
|
vec2 map(in vec3 pos){ |
|
|
|
vec2 res = vec2(sdHorseshoe( pos-vec3(-1.0,0.08, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5) ; |
|
|
|
res = opU(res, vec2(sdSixWayCutHollowSphere( pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5)) ; |
|
|
|
vec2 map(in vec3 pos) |
|
|
|
{ |
|
|
|
vec2 res = vec2(sdHorseshoe(pos - vec3(-1.0, 0.08, 1.0), vec2(cos(1.3), sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5); |
|
|
|
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5)); |
|
|
|
|
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
// https://www.shadertoy.com/view/Xds3zN |
|
|
|
vec2 raycast(in vec3 ro, in vec3 rd){ |
|
|
|
vec2 res = vec2(-1.0,-1.0); |
|
|
|
vec2 raycast(in vec3 ro, in vec3 rd) |
|
|
|
{ |
|
|
|
vec2 res = vec2(-1.0, -1.0); |
|
|
|
|
|
|
|
float tmin = 1.0; |
|
|
|
float tmax = 20.0; |
|
|
|
|
|
|
|
// raytrace floor plane |
|
|
|
float tp1 = (-ro.y)/rd.y; |
|
|
|
if err">(tp1>0.0) |
|
|
|
if nf">(tp1 > 0.0) |
|
|
|
{ |
|
|
|
tmax = min(tmax, tp1); |
|
|
|
res = vec2(tp1, 1.0); |
|
|
|
} |
|
|
|
|
|
|
|
float t = tmin; |
|
|
|
for (int nf">i=0; i<70 ; i++) |
|
|
|
for (int k">i = 0; i < 70 ; i++) |
|
|
|
{ |
|
|
|
if (t>tmax) break; |
|
|
|
vec2 h = err">map(ro+rd*t); |
|
|
|
if err">(abs(h.x)<(0.0001*t)) |
|
|
|
if (t > tmax) break; |
|
|
|
vec2 h = nf">map(ro + rd*t); |
|
|
|
if nf">(abs(h.x )< (0.0001*t)) |
|
|
|
{ |
|
|
|
res = vec2(t,h.y); |
|
|
|
res = vec2(t, h.y); |
|
|
|
break; |
|
|
|
} |
|
|
|
t += h.x; |
|
|
|
@ -111,28 +115,28 @@ vec2 raycast(in vec3 ro, in vec3 rd){ |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// https://iquilezles.org/articles/rmshadows |
|
|
|
float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax) |
|
|
|
{ |
|
|
|
// bounding volume |
|
|
|
float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp); |
|
|
|
float tp = (0.8 - ro.y)/rd.y; if (tp > 0.0) tmax = min(tmax, tp); |
|
|
|
|
|
|
|
float res = 1.0; |
|
|
|
float t = mint; |
|
|
|
for (int nf">i=ZERO; i<24; i++) |
|
|
|
for (int k">i = ZERO; i < 24; i++) |
|
|
|
{ |
|
|
|
float h = map(ro + rd*t).x; |
|
|
|
float s = err">clamp(8.0*h/t,0.0,1.0); |
|
|
|
float s = nf">clamp(8.0*h/t, 0.0, 1.0); |
|
|
|
res = min(res, s); |
|
|
|
t += clamp(h, 0.01, 0.2); |
|
|
|
if (res<0.004 || t>tmax) break; |
|
|
|
if ((res < 0.004) || (t > tmax)) break; |
|
|
|
} |
|
|
|
|
|
|
|
res = clamp(res, 0.0, 1.0); |
|
|
|
|
|
|
|
return res*res*(3.0-2.0*res); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// https://iquilezles.org/articles/normalsSDF |
|
|
|
vec3 calcNormal(in vec3 pos) |
|
|
|
{ |
|
|
|
@ -148,7 +152,7 @@ float calcAO(in vec3 pos, in vec3 nor) |
|
|
|
{ |
|
|
|
float occ = 0.0; |
|
|
|
float sca = 1.0; |
|
|
|
for (int nf">i=ZERO; i<5; i++) |
|
|
|
for (int k">i = ZERO; i < 5; i++) |
|
|
|
{ |
|
|
|
float h = 0.01 + 0.12*float(i)/4.0; |
|
|
|
float d = map(pos + h*nor).x; |
|
|
|
@ -156,6 +160,7 @@ float calcAO(in vec3 pos, in vec3 nor) |
|
|
|
sca *= 0.95; |
|
|
|
if (occ>0.35) break; |
|
|
|
} |
|
|
|
|
|
|
|
return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y); |
|
|
|
} |
|
|
|
|
|
|
|
@ -165,9 +170,9 @@ float checkersGradBox(in vec2 p) |
|
|
|
// filter kernel |
|
|
|
vec2 w = fwidth(p) + 0.001; |
|
|
|
// analytical integral (box filter) |
|
|
|
vec2 i = 2.0err">*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; |
|
|
|
vec2 i = 2.0nf">*(abs(fract((p - 0.5*w)*0.5)-0.5) - abs(fract((p + 0.5*w)*0.5) - 0.5))/w; |
|
|
|
// xor pattern |
|
|
|
return mi">0.5 - 0.5*i.x*i.y; |
|
|
|
return nf">(0.5 - 0.5*i.x*i.y); |
|
|
|
} |
|
|
|
|
|
|
|
// https://www.shadertoy.com/view/tdS3DG |
|
|
|
@ -180,7 +185,7 @@ vec4 render(in vec3 ro, in vec3 rd) |
|
|
|
vec2 res = raycast(ro,rd); |
|
|
|
float t = res.x; |
|
|
|
float m = res.y; |
|
|
|
if err">(m>-0.5) |
|
|
|
if nf">(m > -0.5) |
|
|
|
{ |
|
|
|
vec3 pos = ro + t*rd; |
|
|
|
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos); |
|
|
|
@ -190,7 +195,7 @@ vec4 render(in vec3 ro, in vec3 rd) |
|
|
|
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0)); |
|
|
|
float ks = 1.0; |
|
|
|
|
|
|
|
if err">(m<1.5) |
|
|
|
if nf">(m < 1.5) |
|
|
|
{ |
|
|
|
float f = checkersGradBox(3.0*pos.xz); |
|
|
|
col = 0.15 + f*vec3(0.05); |
|
|
|
@ -207,14 +212,14 @@ vec4 render(in vec3 ro, in vec3 rd) |
|
|
|
vec3 lig = normalize(vec3(-0.5, 0.4, -0.6)); |
|
|
|
vec3 hal = normalize(lig-rd); |
|
|
|
float dif = clamp(dot(nor, lig), 0.0, 1.0); |
|
|
|
//if (dif>0.0001) |
|
|
|
//if (dif>0.0001) |
|
|
|
dif *= calcSoftshadow(pos, lig, 0.02, 2.5); |
|
|
|
float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0); |
|
|
|
spe *= dif; |
|
|
|
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
|
|
|
//spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0); |
|
|
|
lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
|
|
|
lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
|
|
|
lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
|
|
|
} |
|
|
|
// sky |
|
|
|
{ |
|
|
|
@ -249,7 +254,8 @@ vec4 render(in vec3 ro, in vec3 rd) |
|
|
|
return vec4(vec3(clamp(col,0.0,1.0)),t); |
|
|
|
} |
|
|
|
|
|
|
|
vec3 CalcRayDir(vec2 nCoord){ |
|
|
|
vec3 CalcRayDir(vec2 nCoord) |
|
|
|
{ |
|
|
|
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0))); |
|
|
|
vec3 vertical = normalize(cross(horizontal,camDir)); |
|
|
|
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y); |
|
|
|
@ -279,6 +285,7 @@ void main() |
|
|
|
color = res.xyz; |
|
|
|
depth = CalcDepth(rd,res.w); |
|
|
|
} |
|
|
|
gl_FragColor = vec4(color , 1.0); |
|
|
|
|
|
|
|
finalColor = vec4(color , 1.0); |
|
|
|
gl_FragDepth = depth; |
|
|
|
} |