mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-22 15:51:30 +11:00
741 lines
20 KiB
Plaintext
741 lines
20 KiB
Plaintext
#version 450
|
|
// Ocean Structure - dr2 - 2017-11-01
|
|
// https://www.shadertoy.com/view/ltBczc
|
|
|
|
// Abstract construction with fire, smoke, reflections and aurora.
|
|
// Look around using mouse; mouse to lower-right corner for daylight view.
|
|
|
|
// "Ocean Structure" by dr2 - 2017
|
|
// License: Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
|
|
|
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;
|
|
|
|
#define REAL_WAVE 0 // real (=1) or fake (=0, less work) water waves
|
|
#define N_REFL 3 // number of reflections (1-4, 0 = none)
|
|
|
|
float PrBoxDf (vec3 p, vec3 b);
|
|
float PrSphDf (vec3 p, float s);
|
|
float PrSphAnDf (vec3 p, float r, float w);
|
|
float PrCylDf (vec3 p, float r, float h);
|
|
float PrTorusDf (vec3 p, float ri, float rc);
|
|
float PrCapsDf (vec3 p, float r, float h);
|
|
float PrCapsAnDf (vec3 p, float r, float w, float h);
|
|
float PrFlatCylDf (vec3 p, float rhi, float rlo, float h);
|
|
float Noisefv2 (vec2 p);
|
|
float Noisefv3 (vec3 p);
|
|
float Fbm1 (float p);
|
|
float Fbm2 (vec2 p);
|
|
float Fbm3 (vec3 p);
|
|
vec3 VaryNf (vec3 p, vec3 n, float f);
|
|
vec3 HsvToRgb (vec3 c);
|
|
vec2 Rot2D (vec2 q, float a);
|
|
|
|
vec3 qHit, sunDir, smkPos;
|
|
float dstFar, tCur, smkRadEx, smkRadIn, smkPhs, smkHt, tWav;
|
|
int idObj;
|
|
bool isNite;
|
|
const int idBase = 1, idPlat = 2, isShel = 3, idFrm = 4, idDway = 5,
|
|
idTwr = 6, idBrg = 7, idBrCab = 8, idRdw = 9;
|
|
const float pi = 3.14159;
|
|
|
|
float BridgeDf (vec3 p, float dMin)
|
|
{
|
|
float cbRad = 0.06;
|
|
vec3 q, qq;
|
|
float d, cLen, wRd;
|
|
wRd = 1.;
|
|
q = p; q.x = abs (q.x) - wRd; q.y -= -0.3;
|
|
d = PrBoxDf (q, vec3 (0.15, 5., 0.15));
|
|
q = p; q.y -= 4.85;
|
|
d = min (d, PrBoxDf (q, vec3 (wRd + 0.15, 0.15, 0.15)));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idBrg; }
|
|
qq = p; qq.x = abs (qq.x) - wRd + 0.07; qq.z = abs (qq.z);
|
|
q = qq; q.y -= 4.92;
|
|
q.yz = Rot2D (q.yz, -0.1 * pi);
|
|
q.z -= 9.5;
|
|
d = PrCylDf (q, cbRad, 9.5);
|
|
q = qq; q.y -= 4.82;
|
|
q.yz = Rot2D (q.yz, -0.15 * pi);
|
|
q.z -= 6.4;
|
|
d = min (d, PrCylDf (q, cbRad, 6.4));
|
|
q = qq; q.y -= 4.77;
|
|
q.yz = Rot2D (q.yz, -0.26 * pi);
|
|
q.z -= 4.;
|
|
d = min (d, PrCylDf (q, cbRad, 4.));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idBrCab; }
|
|
return dMin;
|
|
}
|
|
|
|
float CentStrucDf (vec3 p, float dMin, float ar)
|
|
{
|
|
float cRad = 6., cLen = 8., ww = 0.03, wThk = 0.05,
|
|
doorHt = 1.6, doorWd = 1.4;
|
|
vec3 q;
|
|
vec2 qo;
|
|
float d, dd;
|
|
q = p; q.y -= -1.05;
|
|
d = PrCylDf (q.xzy, 8.5, 0.15);
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idPlat; }
|
|
d = PrTorusDf (vec3 (q.xz, abs (abs (q.y - 1.1) - 0.4) - 0.2), 0.03, 8.5);
|
|
q.xz = Rot2D (q.xz, 2. * pi * (floor (16. * ar) + 0.5) / 16.);
|
|
q.xy -= vec2 (-8.5, 0.9);
|
|
d = min (d, PrCylDf (q.xzy, 0.05, 0.82));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idBrCab; }
|
|
q = p;
|
|
qo = Rot2D (q.xz, 2. * pi * (floor (4. * ar) + 0.5) / 4.);
|
|
q.xz = qo; q.y -= cLen + 1.2 * doorHt - 9.;
|
|
dd = PrFlatCylDf (q.yzx, doorHt, doorWd, 0.);
|
|
q = p; q.y -= cLen - 9.;
|
|
d = max (max (max (PrCapsAnDf (q.xzy, cRad, wThk, cLen), - q.y), q.y - 1.635 * cLen), - dd);
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = isShel; }
|
|
q.xz = Rot2D (q.xz, 2. * pi * (floor (8. * ar) + 0.5) / 8.);
|
|
d = max (max (max (PrCapsAnDf (q.xzy, cRad, 0.2, cLen),
|
|
min (abs (mod (q.y, 2.) - 1.) - 0.1,
|
|
dot (vec2 (q.x, abs (q.z)), vec2 (sin (0.04 * 2. * pi / 16.), cos (0.04 * 2. * pi / 16.))))),
|
|
- q.y), - dd);
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idFrm; }
|
|
q = p; q.xz = qo; q.xy -= vec2 (-0.98 * cRad, cLen + 1.2 * doorHt - 9.);
|
|
d = max (max (max (PrFlatCylDf (q.yzx, doorHt, doorWd, 0.1 * cRad),
|
|
- PrFlatCylDf (q.yzx, doorHt - ww, doorWd - ww, 0.)),
|
|
- (q.y + 2. * doorHt - ww - wThk)), - (q.y + 1.2 * doorHt));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idDway; }
|
|
return dMin;
|
|
}
|
|
|
|
float CornStrucDf (vec3 p, float dMin)
|
|
{
|
|
vec3 q;
|
|
float d, a;
|
|
q = p; q.y -= -1.2;
|
|
d = PrCylDf (q.xzy, 3.2, 0.15);
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idPlat; }
|
|
q = p; q.y -= 1.;
|
|
d = max (PrCapsAnDf (q.xzy, 2.5, 0.1, 3.), -2.2 - q.y);
|
|
q = p; q.y -= 7.;
|
|
d = min (d, max (PrCapsDf (q.xzy, 0.7, 2.), -1. - q.y));
|
|
q = p;
|
|
a = (length (q.xz) > 0.) ? atan (q.z, - q.x) / (2. * pi) : 0.;
|
|
q.xz = Rot2D (q.xz, 2. * pi * (floor (4. * a + 0.5) / 4.));
|
|
d = max (d, - PrFlatCylDf (q.yzx, 1.5, 1., 0.));
|
|
q = p;
|
|
q.xz = Rot2D (q.xz, 2. * pi * (floor (16. * a) + 0.5) / 16.);
|
|
q.y -= 4.3;
|
|
d = max (d, - (length (max (abs (q.yz) - vec2 (0.6, 0.08), 0.)) - 0.2));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idTwr; }
|
|
return dMin;
|
|
}
|
|
|
|
float ObjDf (vec3 p)
|
|
{
|
|
vec3 q;
|
|
float d, dMin, hs, wRd, ar;
|
|
dMin = dstFar;
|
|
hs = 5.;
|
|
q = p; q.xz = abs (q.xz) - 4.;
|
|
d = max (PrSphAnDf (q, 4.85, 0.15), - min (3.9 - q.y, q.y));
|
|
q.y -= 0.5;
|
|
d = max (d, 2.2 - min (length (q.yz), length (q.xy)));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idBase; }
|
|
q = p; q.xz = abs (q.xz) - 20.;
|
|
d = max (PrSphAnDf (q, 4.85, 0.15), - min (3.9 - q.y, q.y));
|
|
q.y -= 0.5;
|
|
d = max (d, 2.2 - min (length (q.yz), length (q.xy)));
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idBase; }
|
|
wRd = 1.;
|
|
q = p; q.xz = abs (q.xz) - 20.7 + wRd;
|
|
d = max (max (length (max (q.xz - wRd, 0.)) - 0.3,
|
|
- (length (max (q.xz + wRd, 0.)) - 0.3)), abs (q.y - hs + 1.) - 0.1);
|
|
if (d < dMin) { dMin = d; qHit = q; idObj = idRdw; }
|
|
q = p;
|
|
ar = (length (p.xz) > 0.) ? atan (p.z, - p.x) / (2. * pi) : 0.;
|
|
q.y -= hs;
|
|
dMin = CentStrucDf (q, dMin, ar);
|
|
q = p; q.y -= hs; q.xz = abs (q.xz) - vec2 (20.);
|
|
dMin = CornStrucDf (q, dMin);
|
|
q = p; q.y -= hs;
|
|
q.xz = Rot2D (q.xz, 2. * pi * (floor (4. * ar + 0.5) / 4.));
|
|
q.x += 20.;
|
|
dMin = BridgeDf (q, dMin);
|
|
return dMin;
|
|
}
|
|
|
|
float ObjRay (vec3 ro, vec3 rd)
|
|
{
|
|
float dHit, d;
|
|
dHit = 0.;
|
|
for (int j = 0; j < 120; j ++) {
|
|
d = ObjDf (ro + dHit * rd);
|
|
dHit += d;
|
|
if (d < 0.001 || dHit > dstFar) break;
|
|
}
|
|
return dHit;
|
|
}
|
|
|
|
vec3 ObjNf (vec3 p)
|
|
{
|
|
vec4 v;
|
|
vec3 e = vec3 (0.001, -0.001, 0.);
|
|
v = vec4 (ObjDf (p + e.xxx), ObjDf (p + e.xyy), ObjDf (p + e.yxy), ObjDf (p + e.yyx));
|
|
return normalize (vec3 (v.x - v.y - v.z - v.w) + 2. * v.yzw);
|
|
}
|
|
|
|
float WaveHt (vec2 p)
|
|
{
|
|
mat2 qRot = mat2 (0.8, -0.6, 0.6, 0.8);
|
|
vec4 t4, v4;
|
|
vec2 t;
|
|
float wFreq, wAmp, ht;
|
|
wFreq = 1.;
|
|
wAmp = 1.;
|
|
ht = 0.;
|
|
for (int j = 0; j < 3; j ++) {
|
|
p *= qRot;
|
|
t = tWav * vec2 (1., -1.);
|
|
t4 = (p.xyxy + t.xxyy) * wFreq;
|
|
t = vec2 (Noisefv2 (t4.xy), Noisefv2 (t4.zw));
|
|
t4 += 2. * t.xxyy - 1.;
|
|
v4 = (1. - abs (sin (t4))) * (abs (sin (t4)) + abs (cos (t4)));
|
|
ht += wAmp * dot (pow (1. - sqrt (v4.xz * v4.yw), vec2 (8.)), vec2 (1.));
|
|
wFreq *= 2.;
|
|
wAmp *= 0.5;
|
|
}
|
|
return ht;
|
|
}
|
|
|
|
vec3 WaveNf (vec3 p, float d)
|
|
{
|
|
vec3 vn;
|
|
vec2 e;
|
|
e = vec2 (max (0.01, 0.005 * d * d), 0.);
|
|
p *= 0.3;
|
|
vn.xz = 0.4 * (WaveHt (p.xz) - vec2 (WaveHt (p.xz + e.xy), WaveHt (p.xz + e.yx)));
|
|
vn.y = e.x;
|
|
return normalize (vn);
|
|
}
|
|
|
|
#if REAL_WAVE
|
|
|
|
float WaveRay (vec3 ro, vec3 rd)
|
|
{
|
|
vec3 p;
|
|
float dHit, h, s, sLo, sHi, f1, f2;
|
|
dHit = dstFar;
|
|
f1 = 0.4;
|
|
f2 = 0.3;
|
|
s = max (- (ro.y - 1.2 * f1) / rd.y, 0.);
|
|
sLo = s;
|
|
for (int j = 0; j < 80; j ++) {
|
|
p = ro + s * rd;
|
|
h = p.y - f1 * WaveHt (f2 * p.xz);
|
|
if (h < 0.) break;
|
|
sLo = s;
|
|
s += max (0.3, h) + 0.005 * s;
|
|
if (s >= dstFar) break;
|
|
}
|
|
if (h < 0.) {
|
|
sHi = s;
|
|
for (int j = 0; j < 5; j ++) {
|
|
s = 0.5 * (sLo + sHi);
|
|
p = ro + s * rd;
|
|
h = step (0., p.y - f1 * WaveHt (f2 * p.xz));
|
|
sLo += h * (s - sLo);
|
|
sHi += (1. - h) * (s - sHi);
|
|
}
|
|
dHit = sHi;
|
|
}
|
|
return dHit;
|
|
}
|
|
|
|
#endif
|
|
|
|
float SmokeDens (vec3 p)
|
|
{
|
|
mat2 rMat;
|
|
vec3 q, u;
|
|
float f;
|
|
f = PrTorusDf (p.xzy, smkRadIn, smkRadEx);
|
|
if (f < 0.) {
|
|
q = p.xzy / smkRadEx;
|
|
u = normalize (vec3 (q.xy, 0.));
|
|
q -= u;
|
|
rMat = mat2 (vec2 (u.x, - u.y), u.yx);
|
|
q.xy = rMat * q.xy;
|
|
q.xz = Rot2D (q.xz, 2.5 * tCur);
|
|
q.xy = q.xy * rMat;
|
|
q += u;
|
|
q.xy = Rot2D (q.xy, 0.1 * tCur);
|
|
f = smoothstep (0., smkRadIn, - f) * Fbm3 (10. * q);
|
|
} else f = 0.;
|
|
return f;
|
|
}
|
|
|
|
vec4 SmokeCol (vec3 ro, vec3 rd, float dstObj)
|
|
{
|
|
vec4 col4;
|
|
vec3 q;
|
|
float densFac, dens, d, h, sh;
|
|
d = 0.;
|
|
for (int j = 0; j < 150; j ++) {
|
|
q = ro + d * rd;
|
|
q.xz = abs (q.xz);
|
|
q -= smkPos;
|
|
h = PrTorusDf (q.xzy, smkRadIn, smkRadEx);
|
|
d += h;
|
|
if (h < 0.001 || d > dstFar) break;
|
|
}
|
|
col4 = vec4 (0.);
|
|
if (d < min (dstObj, dstFar)) {
|
|
densFac = 1.45 * (1.08 - pow (smkPhs, 1.5));
|
|
for (int j = 0; j < 150; j ++) {
|
|
q = ro + d * rd;
|
|
q.xz = abs (q.xz);
|
|
q -= smkPos;
|
|
dens = SmokeDens (q);
|
|
sh = 0.3 + 0.7 * smoothstep (-0.3, 0.1, dens - SmokeDens (q + 0.1 * sunDir));
|
|
col4 += densFac * dens * (1. - col4.w) * vec4 (sh * vec3 (0.9) - col4.rgb, 0.3);
|
|
d += 2.2 * smkRadEx / 150.;
|
|
if (col4.w > 0.99 || d > dstFar) break;
|
|
}
|
|
}
|
|
if (isNite) col4.rgb *= vec3 (0.3, 0.4, 0.3);
|
|
return col4;
|
|
}
|
|
|
|
vec4 ObjCol (vec3 n)
|
|
{
|
|
vec4 col;
|
|
if (idObj == idBase) col = vec4 (0.3, 0.4, 0.1, 0.1);
|
|
else if (idObj == idPlat) col = vec4 (0.4, 0.4, 0.3, 0.1);
|
|
else if (idObj == isShel) col = vec4 (0.5, 0.5, 0.5, 0.3);
|
|
else if (idObj == idFrm) col = vec4 (0.8, 0.8, 0.9, 0.5);
|
|
else if (idObj == idDway) col = vec4 (0.7, 0.8, 0.7, 0.3);
|
|
else if (idObj == idTwr) col = vec4 (0.7, 0.7, 0.6, 0.3);
|
|
else if (idObj == idBrg) col = vec4 (1., 0.3, 0.3, 0.3);
|
|
else if (idObj == idBrCab) col = vec4 (0.9, 0.9, 1., 0.5);
|
|
else if (idObj == idRdw) col = vec4 (0.4, 0.3, 0.3, 0.1);
|
|
return col;
|
|
}
|
|
|
|
vec4 AurCol (vec3 ro, vec3 rd)
|
|
{
|
|
vec4 col, mCol;
|
|
vec3 p, dp;
|
|
float ar;
|
|
dp = rd / rd.y;
|
|
p = ro + (40. - ro.y) * dp;
|
|
col = vec4 (0.);
|
|
mCol = vec4 (0.);
|
|
tWav = 0.05 * tCur;
|
|
for (float ns = 0.; ns < 50.; ns ++) {
|
|
p += dp;
|
|
ar = 0.05 - clamp (0.06 * WaveHt (0.01 * p.xz), 0., 0.04);
|
|
mCol = mix (mCol, ar * vec4 (HsvToRgb (vec3 (0.34 + 0.007 * ns, 1., 1. - 0.02 * ns)), 1.), 0.5);
|
|
col += mCol;
|
|
}
|
|
return col;
|
|
}
|
|
|
|
vec3 NtSkyCol (vec3 rd)
|
|
{
|
|
vec3 rds;
|
|
rds = floor (2000. * rd);
|
|
rds = 0.00015 * rds + 0.1 * Noisefv3 (0.0005 * rds.yzx);
|
|
for (int j = 0; j < 19; j ++) rds = abs (rds) / dot (rds, rds) - 0.9;
|
|
return 0.3 * vec3 (1., 1., 0.9) * min (1., 0.5e-3 * pow (min (6., length (rds)), 5.));
|
|
}
|
|
|
|
vec3 BgCol (vec3 ro, vec3 rd)
|
|
{
|
|
vec3 col;
|
|
float f, a;
|
|
if (rd.y > 0.) {
|
|
a = atan (rd.x, - rd.z);
|
|
if (rd.y < 0.03 * Fbm1 (32. * a) + 0.005)
|
|
col = (isNite ? vec3 (0.07, 0.1, 0.07) : vec3 (0.4, 0.5, 0.7)) * (1. - 0.3 * Fbm2 (128. * vec2 (a, rd.y)));
|
|
else {
|
|
if (isNite) {
|
|
vec4 aCol = AurCol (ro, rd);
|
|
col = (1. - 0.5 * aCol.a) * NtSkyCol (rd) + 0.6 * aCol.rgb;
|
|
} else {
|
|
ro.xz += 2. * tCur;
|
|
col = vec3 (0.2, 0.3, 0.6) + 0.2 * (1. - max (rd.y, 0.)) +
|
|
0.1 * pow (max (dot (rd, sunDir), 0.), 16.);
|
|
f = Fbm2 (0.02 * (ro.xz + rd.xz * (100. - ro.y) / max (rd.y, 0.01)));
|
|
col = mix (col, vec3 (1.), 0.2 + 0.8 * f * rd.y);
|
|
}
|
|
}
|
|
} else {
|
|
col = vec3 (0.6, 0.5, 0.3);
|
|
if (- ro.y / rd.y < dstFar) {
|
|
ro += - (ro.y / rd.y) * rd;
|
|
col *= 1.1 - 0.2 * Noisefv2 (30. * ro.xz);
|
|
}
|
|
col = mix (col, 0.9 * (vec3 (0.4, 0.2, 0.1) + 0.2) + 0.1, pow (1. + rd.y, 5.));
|
|
}
|
|
return col;
|
|
}
|
|
|
|
vec4 GlowCol (vec3 ro, vec3 rd, float dstObj)
|
|
{
|
|
vec3 gloDir;
|
|
float gloDist, wGlow, s;
|
|
wGlow = 0.;
|
|
for (float j = 0.; j < 4.; j ++) {
|
|
gloDir = vec3 (20., 9.3, 20.) * (1. - 2. * vec3 (floor (j / 2.), 0., mod (j, 2.))) - ro;
|
|
gloDist = length (gloDir);
|
|
s = dot (rd, normalize (gloDir));
|
|
if (s > 0. && gloDist < dstObj) wGlow += 1. - smoothstep (1., 2., sqrt (1. - s * s) * gloDist);
|
|
}
|
|
gloDir = vec3 (0., 15.5, 0.) - ro;
|
|
gloDist = length (gloDir);
|
|
s = dot (rd, normalize (gloDir));
|
|
if (s > 0. && gloDist < dstObj) wGlow += 1. - smoothstep (2., 3., sqrt (1. - s * s) * gloDist);
|
|
return (0.6 + 0.4 * sin (0.3 * 2. * pi * tCur)) * clamp (wGlow, 0., 1.) * vec4 (1., 0.5, 0.3, 1.);
|
|
}
|
|
|
|
vec3 ShowScene (vec3 ro, vec3 rd)
|
|
{
|
|
vec4 objCol, smkCol, smkColR, smkColW, glwCol, glwColR, glwColW;
|
|
vec3 col, vn;
|
|
float dstObj, dstWat, reflCol;
|
|
bool wRefl;
|
|
col = vec3 (0.2, 0.2, 0.);
|
|
wRefl = false;
|
|
dstObj = ObjRay (ro, rd);
|
|
smkCol = SmokeCol (ro, rd, dstObj);
|
|
glwCol = GlowCol (ro, rd, dstObj);
|
|
glwColR = vec4 (0.);
|
|
glwColW = vec4 (0.);
|
|
smkColR = vec4 (0.);
|
|
smkColW = vec4 (0.);
|
|
tWav = 0.4 * tCur;
|
|
reflCol = 1.;
|
|
if (N_REFL >= 2 && dstObj < dstFar && idObj == isShel) {
|
|
if (length (qHit.xz) > 6. || qHit.y >= 8.8) {
|
|
ro += dstObj * rd;
|
|
vn = ObjNf (ro);
|
|
rd = reflect (rd, vn);
|
|
ro += 0.01 * rd;
|
|
dstObj = ObjRay (ro, rd);
|
|
smkColR = SmokeCol (ro, rd, dstObj);
|
|
glwColR = GlowCol (ro, rd, dstObj);
|
|
reflCol *= 0.9;
|
|
}
|
|
}
|
|
if (N_REFL >= 1 && rd.y < 0.) {
|
|
#if REAL_WAVE
|
|
dstWat = WaveRay (ro, rd);
|
|
#else
|
|
dstWat = - ro.y / rd.y;
|
|
#endif
|
|
if (dstWat < min (dstObj, dstFar)) {
|
|
wRefl = true;
|
|
ro += dstWat * rd;
|
|
vn = WaveNf (ro, dstWat);
|
|
rd = reflect (rd, vn);
|
|
ro += 0.01 * rd;
|
|
dstObj = ObjRay (ro, rd);
|
|
smkColW = SmokeCol (ro, rd, dstObj);
|
|
glwColW = GlowCol (ro, rd, dstObj);
|
|
if (N_REFL >= 3 && dstObj < dstFar && idObj == isShel) {
|
|
ro += dstObj * rd;
|
|
vn = ObjNf (ro);
|
|
rd = reflect (rd, vn);
|
|
if (N_REFL == 4) {
|
|
ro += 0.01 * rd;
|
|
dstObj = ObjRay (ro, rd);
|
|
} else {
|
|
dstObj = dstFar;
|
|
}
|
|
}
|
|
reflCol *= 0.7;
|
|
}
|
|
}
|
|
if (dstObj < dstFar) {
|
|
ro += dstObj * rd;
|
|
vn = ObjNf (ro);
|
|
if (idObj == idRdw) vn = VaryNf (5. * qHit, vn, 1.);
|
|
else if (idObj == idBase) vn = VaryNf (2. * floor (16. * qHit), vn, 2.);
|
|
objCol = ObjCol (vn);
|
|
if (isNite) col = objCol.rgb * vec3 (0.3, 0.35, 0.3) * (0.2 + 0.8 * max (0.,vn.y));
|
|
else col = objCol.rgb * (0.2 + 0.8 * max (0., max (dot (vn, sunDir), 0.))) +
|
|
objCol.a * pow (max (dot (normalize (sunDir - rd), vn), 0.), 64.);
|
|
} else if (rd.y > 0.) {
|
|
col = BgCol (ro, rd);
|
|
} else {
|
|
#if N_REFL == 0
|
|
dstWat = - ro.y / rd.y;
|
|
#endif
|
|
col = BgCol (ro + dstWat * rd, reflect (rd, vec3 (0., 1., 0.)));
|
|
reflCol = 0.7;
|
|
}
|
|
col = clamp (reflCol * col, 0., 1.);
|
|
col = mix (col, glwCol.rgb, glwCol.a);
|
|
col = mix (col, glwColR.rgb, glwColR.a);
|
|
col = mix (col, smkCol.rgb, smkCol.a);
|
|
col = mix (col, smkColR.rgb, smkColR.a);
|
|
if (wRefl) {
|
|
col = mix (col, reflCol * glwColW.rgb, glwColW.a);
|
|
col = mix (col, reflCol * smkColW.rgb, smkColW.a);
|
|
col = mix (mix (vec3 (0., 0.1, 0.), vec3 (0., 0.05, 0.05),
|
|
smoothstep (0.4, 0.6, Fbm2 (0.5 * ro.xz))), col, 1. - pow (abs (rd.y), 4.));
|
|
}
|
|
return clamp (col, 0., 1.);
|
|
}
|
|
|
|
void mainImage (out vec4 fragColor, in vec2 fragCoord)
|
|
{
|
|
mat3 vuMat;
|
|
#ifdef MOUSE
|
|
vec4 mPtr;
|
|
#endif
|
|
vec3 ro, rd;
|
|
vec2 uv, ori, ca, sa;
|
|
float el, az;
|
|
uv = 2. * fragCoord.xy / iResolution.xy - 1.;
|
|
uv.x *= iResolution.x / iResolution.y;
|
|
tCur = iGlobalTime;
|
|
#ifdef MOUSE
|
|
mPtr = iMouse;
|
|
mPtr.xy = mPtr.xy / iResolution.xy - 0.5;
|
|
#endif
|
|
smkPhs = mod (0.15 * tCur + 0.3, 1.);
|
|
smkPos = vec3 (20., 9. + 10. * smkPhs, 20.);
|
|
smkRadIn = 0.6 * (0.1 + 0.9 * smoothstep (0.01, 0.1, smkPhs));
|
|
smkRadEx = smkRadIn + 2.5;
|
|
dstFar = 140.;
|
|
isNite = true;
|
|
az = 0.33 * pi;
|
|
el = -0.016 * pi;
|
|
#ifdef MOUSE
|
|
if (mPtr.z > 0.) {
|
|
if (mPtr.x > 0.45 && mPtr.y < -0.45) isNite = false;
|
|
else {
|
|
az += pi * mPtr.x;
|
|
el += 0.05 * pi * mPtr.y;
|
|
}
|
|
} else {
|
|
az += 0.002 * pi * tCur;
|
|
el += 0.01 * pi * sin (0.01 * pi * tCur);
|
|
}
|
|
#else
|
|
az += 0.002 * pi * tCur;
|
|
el += 0.01 * pi * sin (0.01 * pi * tCur);
|
|
#endif
|
|
el = clamp (el, -0.4 * pi, -0.01 * pi);
|
|
ori = vec2 (el, az);
|
|
ca = cos (ori);
|
|
sa = sin (ori);
|
|
vuMat = mat3 (ca.y, 0., - sa.y, 0., 1., 0., sa.y, 0., ca.y) *
|
|
mat3 (1., 0., 0., 0., ca.x, - sa.x, 0., sa.x, ca.x);
|
|
ro = vuMat * vec3 (0., 10., -100.);
|
|
rd = vuMat * normalize (vec3 (uv, 4.2));
|
|
sunDir = vuMat * normalize (vec3 (1., 1., -1.));
|
|
fragColor = vec4 (ShowScene (ro, rd), 1.);
|
|
}
|
|
|
|
float PrBoxDf (vec3 p, vec3 b)
|
|
{
|
|
vec3 d;
|
|
d = abs (p) - b;
|
|
return min (max (d.x, max (d.y, d.z)), 0.) + length (max (d, 0.));
|
|
}
|
|
|
|
float PrSphDf (vec3 p, float s)
|
|
{
|
|
return length (p) - s;
|
|
}
|
|
|
|
float PrSphAnDf (vec3 p, float r, float w)
|
|
{
|
|
return abs (length (p) - r) - w;
|
|
}
|
|
|
|
float PrCylDf (vec3 p, float r, float h)
|
|
{
|
|
return max (length (p.xy) - r, abs (p.z) - h);
|
|
}
|
|
|
|
float PrCapsDf (vec3 p, float r, float h)
|
|
{
|
|
return length (p - vec3 (0., 0., h * clamp (p.z / h, -1., 1.))) - r;
|
|
}
|
|
|
|
float PrCapsAnDf (vec3 p, float r, float w, float h)
|
|
{
|
|
p.z = abs (p.z);
|
|
return max (length (p - vec3 (0., 0., min (p.z, h + w))) - r,
|
|
- length (p - vec3 (0., 0., min (p.z, h - w))) + r) - w;
|
|
}
|
|
|
|
float PrFlatCylDf (vec3 p, float rhi, float rlo, float h)
|
|
{
|
|
float d;
|
|
d = length (p.xy - vec2 (rhi * clamp (p.x / rhi, -1., 1.), 0.)) - rlo;
|
|
if (h > 0.) d = max (d, abs (p.z) - h);
|
|
return d;
|
|
}
|
|
|
|
float PrTorusDf (vec3 p, float ri, float rc)
|
|
{
|
|
return length (vec2 (length (p.xy) - rc, p.z)) - ri;
|
|
}
|
|
|
|
const float cHashM = 43758.54;
|
|
|
|
vec2 Hashv2f (float p)
|
|
{
|
|
return fract (sin (p + vec2 (0., 1.)) * cHashM);
|
|
}
|
|
|
|
vec2 Hashv2v2 (vec2 p)
|
|
{
|
|
vec2 cHashVA2 = vec2 (37., 39.);
|
|
return fract (sin (vec2 (dot (p, cHashVA2), dot (p + vec2 (1., 0.), cHashVA2))) * cHashM);
|
|
}
|
|
|
|
vec4 Hashv4v3 (vec3 p)
|
|
{
|
|
vec3 cHashVA3 = vec3 (37., 39., 41.);
|
|
vec2 e = vec2 (1., 0.);
|
|
return fract (sin (vec4 (dot (p + e.yyy, cHashVA3), dot (p + e.xyy, cHashVA3),
|
|
dot (p + e.yxy, cHashVA3), dot (p + e.xxy, cHashVA3))) * cHashM);
|
|
}
|
|
|
|
float Noiseff (float p)
|
|
{
|
|
vec2 t;
|
|
float ip, fp;
|
|
ip = floor (p);
|
|
fp = fract (p);
|
|
fp = fp * fp * (3. - 2. * fp);
|
|
t = Hashv2f (ip);
|
|
return mix (t.x, t.y, fp);
|
|
}
|
|
|
|
float Noisefv2 (vec2 p)
|
|
{
|
|
vec2 t, ip, fp;
|
|
ip = floor (p);
|
|
fp = fract (p);
|
|
fp = fp * fp * (3. - 2. * fp);
|
|
t = mix (Hashv2v2 (ip), Hashv2v2 (ip + vec2 (0., 1.)), fp.y);
|
|
return mix (t.x, t.y, fp.x);
|
|
}
|
|
|
|
float Noisefv3 (vec3 p)
|
|
{
|
|
vec4 t;
|
|
vec3 ip, fp;
|
|
ip = floor (p);
|
|
fp = fract (p);
|
|
fp *= fp * (3. - 2. * fp);
|
|
t = mix (Hashv4v3 (ip), Hashv4v3 (ip + vec3 (0., 0., 1.)), fp.z);
|
|
return mix (mix (t.x, t.y, fp.x), mix (t.z, t.w, fp.x), fp.y);
|
|
}
|
|
|
|
float Fbm1 (float p)
|
|
{
|
|
float f, a;
|
|
f = 0.;
|
|
a = 1.;
|
|
for (int i = 0; i < 5; i ++) {
|
|
f += a * Noiseff (p);
|
|
a *= 0.5;
|
|
p *= 2.;
|
|
}
|
|
return f * (1. / 1.9375);
|
|
}
|
|
|
|
float Fbm2 (vec2 p)
|
|
{
|
|
float f, a;
|
|
f = 0.;
|
|
a = 1.;
|
|
for (int i = 0; i < 5; i ++) {
|
|
f += a * Noisefv2 (p);
|
|
a *= 0.5;
|
|
p *= 2.;
|
|
}
|
|
return f * (1. / 1.9375);
|
|
}
|
|
|
|
float Fbm3 (vec3 p)
|
|
{
|
|
float f, a;
|
|
f = 0.;
|
|
a = 1.;
|
|
for (int i = 0; i < 5; i ++) {
|
|
f += a * Noisefv3 (p);
|
|
a *= 0.5;
|
|
p *= 2.;
|
|
}
|
|
return f * (1. / 1.9375);
|
|
}
|
|
|
|
float Fbmn (vec3 p, vec3 n)
|
|
{
|
|
vec3 s;
|
|
float a;
|
|
s = vec3 (0.);
|
|
a = 1.;
|
|
for (int i = 0; i < 5; i ++) {
|
|
s += a * vec3 (Noisefv2 (p.yz), Noisefv2 (p.zx), Noisefv2 (p.xy));
|
|
a *= 0.5;
|
|
p *= 2.;
|
|
}
|
|
return dot (s, abs (n));
|
|
}
|
|
|
|
vec3 VaryNf (vec3 p, vec3 n, float f)
|
|
{
|
|
vec3 g;
|
|
vec2 e = vec2 (0.1, 0.);
|
|
g = vec3 (Fbmn (p + e.xyy, n), Fbmn (p + e.yxy, n), Fbmn (p + e.yyx, n)) - Fbmn (p, n);
|
|
return normalize (n + f * (g - n * dot (n, g)));
|
|
}
|
|
|
|
vec3 HsvToRgb (vec3 c)
|
|
{
|
|
vec3 p;
|
|
p = abs (fract (c.xxx + vec3 (1., 2./3., 1./3.)) * 6. - 3.);
|
|
return c.z * mix (vec3 (1.), clamp (p - 1., 0., 1.), c.y);
|
|
}
|
|
|
|
vec2 Rot2D (vec2 q, float a)
|
|
{
|
|
return q * cos (a) + q.yx * sin (a) * vec2 (-1., 1.);
|
|
}
|
|
|
|
void main(void)
|
|
{
|
|
//just some shit to wrap shadertoy's stuff
|
|
vec2 FragmentCoord = vTexCoord.xy*global.OutputSize.xy;
|
|
FragmentCoord.y = -FragmentCoord.y;
|
|
mainImage(FragColor,FragmentCoord);
|
|
}
|