diff --git a/shaders/_common/passthrough.vert.msl b/shaders/_common/passthrough.vert.msl index f596d75..8b9d90b 100644 --- a/shaders/_common/passthrough.vert.msl +++ b/shaders/_common/passthrough.vert.msl @@ -14,6 +14,6 @@ vertex PassthroughVOut passthrough_vs(uint vid [[vertex_id]]) { PassthroughVOut out; float2 pos = positions[vid]; out.uv = pos * 0.5 + 0.5; - out.pos = float4(pos.x, -pos.y, 0.0, 1.0); + out.pos = float4(pos, 0.0, 1.0); return out; } diff --git a/shaders/_common/passthrough.vert.spv b/shaders/_common/passthrough.vert.spv index 6c18908..2998023 100644 Binary files a/shaders/_common/passthrough.vert.spv and b/shaders/_common/passthrough.vert.spv differ diff --git a/shaders/_common/passthrough.vk.glsl b/shaders/_common/passthrough.vk.glsl index cf192c2..2b07bf3 100644 --- a/shaders/_common/passthrough.vk.glsl +++ b/shaders/_common/passthrough.vk.glsl @@ -2,7 +2,6 @@ // Shared fullscreen-triangle vertex shader for the SDL3 GPU backend. // Emits vUV in Shadertoy convention: (0,0) bottom-left, (1,1) top-right. -// Y flipped in NDC because Vulkan/Metal point Y down by default. layout(location = 0) out vec2 vUV; @@ -14,5 +13,5 @@ void main() { ); vec2 pos = positions[gl_VertexIndex]; vUV = pos * 0.5 + 0.5; - gl_Position = vec4(pos.x, -pos.y, 0.0, 1.0); + gl_Position = vec4(pos, 0.0, 1.0); } diff --git a/shaders/cineshader_lava/cineshader_lava.frag.msl b/shaders/cineshader_lava/cineshader_lava.frag.msl new file mode 100644 index 0000000..4f48672 --- /dev/null +++ b/shaders/cineshader_lava/cineshader_lava.frag.msl @@ -0,0 +1,75 @@ +#include +using namespace metal; + +// Cineshader Lava — edankwan +// MSL port of cineshader_lava.vk.glsl. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +static float opSmoothUnion(float d1, float d2, float k) { + float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0); + return mix(d2, d1, h) - k * h * (1.0 - h); +} + +static float sdSphere(float3 p, float s) { + return length(p) - s; +} + +static float map(float3 p, float iTime) { + float d = 2.0; + for (int i = 0; i < 16; i++) { + float fi = float(i); + float time = iTime * (fract(fi * 412.531 + 0.513) - 0.5) * 2.0; + d = opSmoothUnion( + sdSphere(p + sin(time + fi * float3(52.5126, 64.62744, 632.25)) * float3(2.0, 2.0, 0.8), + mix(0.5, 1.0, fract(fi * 412.531 + 0.5124))), + d, + 0.4 + ); + } + return d; +} + +static float3 calcNormal(float3 p, float iTime) { + const float h = 1e-5; + const float2 k = float2(1, -1); + return normalize(k.xyy * map(p + k.xyy * h, iTime) + + k.yyx * map(p + k.yyx * h, iTime) + + k.yxy * map(p + k.yxy * h, iTime) + + k.xxx * map(p + k.xxx * h, iTime)); +} + +fragment float4 cineshader_lava_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 uv = fragCoord / U.iResolution; + + float3 rayOri = float3((uv - 0.5) * float2(U.iResolution.x / U.iResolution.y, 1.0) * 6.0, 3.0); + float3 rayDir = float3(0.0, 0.0, -1.0); + + float depth = 0.0; + float3 p = float3(0.0); + + for (int i = 0; i < 64; i++) { + p = rayOri + rayDir * depth; + float dist = map(p, U.iTime); + depth += dist; + if (dist < 1e-6) { break; } + } + + depth = min(6.0, depth); + float3 n = calcNormal(p, U.iTime); + float b = max(0.0, dot(n, float3(0.577))); + float3 col = (0.5 + 0.5 * cos((b + U.iTime * 3.0) + uv.xyx * 2.0 + float3(0, 2, 4))) * (0.85 + b * 0.35); + col *= exp(-depth * 0.15); + + return float4(col, 1.0 - (depth - 0.5) / 2.0); +} diff --git a/shaders/cineshader_lava/cineshader_lava.frag.spv b/shaders/cineshader_lava/cineshader_lava.frag.spv new file mode 100644 index 0000000..27b6561 Binary files /dev/null and b/shaders/cineshader_lava/cineshader_lava.frag.spv differ diff --git a/shaders/cineshader_lava/cineshader_lava.vk.glsl b/shaders/cineshader_lava/cineshader_lava.vk.glsl new file mode 100644 index 0000000..ab19fba --- /dev/null +++ b/shaders/cineshader_lava/cineshader_lava.vk.glsl @@ -0,0 +1,77 @@ +#version 450 + +// Name: Cineshader Lava +// Author: edankwan +// URL: https://www.shadertoy.com/view/3sySRK + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +float opSmoothUnion(float d1, float d2, float k) { + float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0); + return mix(d2, d1, h) - k * h * (1.0 - h); +} + +float sdSphere(vec3 p, float s) { + return length(p) - s; +} + +float map(vec3 p) { + float d = 2.0; + for (int i = 0; i < 16; i++) { + float fi = float(i); + float time = iTime * (fract(fi * 412.531 + 0.513) - 0.5) * 2.0; + d = opSmoothUnion( + sdSphere(p + sin(time + fi * vec3(52.5126, 64.62744, 632.25)) * vec3(2.0, 2.0, 0.8), mix(0.5, 1.0, fract(fi * 412.531 + 0.5124))), + d, + 0.4 + ); + } + return d; +} + +vec3 calcNormal(in vec3 p) { + const float h = 1e-5; + const vec2 k = vec2(1, -1); + return normalize(k.xyy * map(p + k.xyy * h) + + k.yyx * map(p + k.yyx * h) + + k.yxy * map(p + k.yxy * h) + + k.xxx * map(p + k.xxx * h)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = fragCoord / iResolution.xy; + + vec3 rayOri = vec3((uv - 0.5) * vec2(iResolution.x / iResolution.y, 1.0) * 6.0, 3.0); + vec3 rayDir = vec3(0.0, 0.0, -1.0); + + float depth = 0.0; + vec3 p; + + for (int i = 0; i < 64; i++) { + p = rayOri + rayDir * depth; + float dist = map(p); + depth += dist; + if (dist < 1e-6) { break; } + } + + depth = min(6.0, depth); + vec3 n = calcNormal(p); + float b = max(0.0, dot(n, vec3(0.577))); + vec3 col = (0.5 + 0.5 * cos((b + iTime * 3.0) + uv.xyx * 2.0 + vec3(0, 2, 4))) * (0.85 + b * 0.35); + col *= exp(-depth * 0.15); + + fragColor = vec4(col, 1.0 - (depth - 0.5) / 2.0); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/creation/creation.frag.msl b/shaders/creation/creation.frag.msl new file mode 100644 index 0000000..feed021 --- /dev/null +++ b/shaders/creation/creation.frag.msl @@ -0,0 +1,42 @@ +#include +using namespace metal; + +// Creation by Silexars — Danguafer +// MSL port of creation.vk.glsl. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +fragment float4 creation_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float t = U.iTime; + float2 r = U.iResolution; + + float3 c = float3(0.0); + float l = 0.0; + float z = t; + for (int i = 0; i < 3; i++) { + float2 p = fragCoord / r; + float2 uv = p; + p -= 0.5; + p.x *= r.x / r.y; + z += 0.07; + l = length(p); + float invl = (l > 0.0) ? (1.0 / l) : 0.0; + uv += p * invl * (sin(z) + 1.0) * abs(sin(l * 9.0 - z - z)); + float2 m = fract(uv) - 0.5; + float denom = length(m); + if (denom < 1e-6) denom = 1e-6; + c[i] = 0.01 / denom; + } + float L = (l > 0.0) ? l : 1.0; + return float4(c / L, t); +} diff --git a/shaders/creation/creation.frag.spv b/shaders/creation/creation.frag.spv new file mode 100644 index 0000000..fcd4cfe Binary files /dev/null and b/shaders/creation/creation.frag.spv differ diff --git a/shaders/creation/creation.vk.glsl b/shaders/creation/creation.vk.glsl new file mode 100644 index 0000000..97083c2 --- /dev/null +++ b/shaders/creation/creation.vk.glsl @@ -0,0 +1,45 @@ +#version 450 + +// Name: Creation by Silexars +// Author: Danguafer +// URL: https://www.shadertoy.com/view/XsXXDn + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +#define t iTime +#define r iResolution.xy + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec3 c = vec3(0.0); + float l; + float z = t; + for (int i = 0; i < 3; i++) { + vec2 uv, p = fragCoord.xy / r; + uv = p; + p -= 0.5; + p.x *= r.x / r.y; + z += 0.07; + l = length(p); + float invl = (l > 0.0) ? (1.0 / l) : 0.0; + uv += p * invl * (sin(z) + 1.0) * abs(sin(l * 9.0 - z - z)); + vec2 m = mod(uv, 1.0) - 0.5; + float denom = length(m); + if (denom < 1e-6) denom = 1e-6; + c[i] = 0.01 / denom; + } + float L = (l > 0.0) ? l : 1.0; + fragColor = vec4(c / L, t); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/cube_lines/cube_lines.frag.msl b/shaders/cube_lines/cube_lines.frag.msl new file mode 100644 index 0000000..1b63517 --- /dev/null +++ b/shaders/cube_lines/cube_lines.frag.msl @@ -0,0 +1,452 @@ +#include +using namespace metal; + +// Cube lines — Danil +// MSL port of cube_lines.vk.glsl. The original Shadertoy is ~780 lines and +// uses every GLSL trick (mat3 chains, arrays, fwidth-based AA, swap macros). +// +// Notes on compromises in this port: +// - fcos() in the GLSL uses fwidth() with a fallback that depends on +// iResolution.y. To avoid threading iResolution through ~10 helpers, this +// port uses the simpler `fcos = cos` path (equivalent to defining AA_ALL +// in the original). Edges may be slightly less smooth than the Vulkan/GL +// versions; cosmetic only. +// - Optional Shadertoy defines (ANIM_SHAPE, ANIM_COLOR, ROTATION_SPEED, +// CAMERA_*, USE_COLOR, AA_*, ONLY_BOX, etc.) are left at their defaults +// just like the .vk.glsl ships them. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +constant float ROTATION_SPEED = 0.8999; +constant float tshift = 53.0; +constant float FDIST = 0.7; +constant float PI = 3.1415926; +constant float3 BOXDIMS = float3(0.75, 0.75, 1.25); +constant float IOR = 1.33; + +static float3x3 rotx(float a) { + float s = sin(a), c = cos(a); + return float3x3(float3(1.0, 0.0, 0.0), float3(0.0, c, s), float3(0.0, -s, c)); +} +static float3x3 roty(float a) { + float s = sin(a), c = cos(a); + return float3x3(float3(c, 0.0, s), float3(0.0, 1.0, 0.0), float3(-s, 0.0, c)); +} +static float3x3 rotz(float a) { + float s = sin(a), c = cos(a); + return float3x3(float3(c, s, 0.0), float3(-s, c, 0.0), float3(0.0, 0.0, 1.0)); +} + +static float3 fcos(float3 x) { return cos(x); } + +static float3 getColor(float3 p) { + p = abs(p); + p *= 1.25; + p = 0.5 * p / dot(p, p); + + float t = 0.13 * length(p); + float3 col = float3(0.3, 0.4, 0.5); + col += 0.12 * fcos(6.28318 * t * 1.0 + float3(0.0, 0.8, 1.1)); + col += 0.11 * fcos(6.28318 * t * 3.1 + float3(0.3, 0.4, 0.1)); + col += 0.10 * fcos(6.28318 * t * 5.1 + float3(0.1, 0.7, 1.1)); + col += 0.10 * fcos(6.28318 * t * 17.1 + float3(0.2, 0.6, 0.7)); + col += 0.10 * fcos(6.28318 * t * 31.1 + float3(0.1, 0.6, 0.7)); + col += 0.10 * fcos(6.28318 * t * 65.1 + float3(0.0, 0.5, 0.8)); + col += 0.10 * fcos(6.28318 * t * 115.1 + float3(0.1, 0.4, 0.7)); + col += 0.10 * fcos(6.28318 * t * 265.1 + float3(1.1, 1.4, 2.7)); + col = clamp(col, 0.0, 1.0); + return col; +} + +static void calcColor(float3 ro, float3 rd, float3 nor, float d, float len, int idx, + bool si, float td, + thread float4& colx, thread float4& colsi) { + float3 pos = ro + rd * d; + float a = 1.0 - smoothstep(len - 0.15 * 0.5, len + 0.00001, length(pos)); + float3 col = getColor(pos); + colx = float4(col, a); + if (si) { + pos = ro + rd * td; + float ta = 1.0 - smoothstep(len - 0.15 * 0.5, len + 0.00001, length(pos)); + col = getColor(pos); + colsi = float4(col, ta); + } +} + +static bool iBilinearPatch(float3 ro, float3 rd, float4 ps, float4 ph, float sz, + thread float& t, thread float3& norm, + thread bool& si, thread float& tsi, thread float3& normsi, + thread float& fade, thread float& fadesi) { + float3 va = float3(0.0, 0.0, ph.x + ph.w - ph.y - ph.z); + float3 vb = float3(0.0, ps.w - ps.y, ph.z - ph.x); + float3 vc = float3(ps.z - ps.x, 0.0, ph.y - ph.x); + float3 vd = float3(ps.xy, ph.x); + t = -1.0; + tsi = -1.0; + si = false; + fade = 1.0; + fadesi = 1.0; + norm = float3(0.0, 1.0, 0.0); + normsi = float3(0.0, 1.0, 0.0); + + float tmp = 1.0 / (vb.y * vc.x); + float a = 0.0, b = 0.0, c = 0.0; + float d = va.z * tmp; + float e = 0.0, f = 0.0; + float g = (vc.z * vb.y - vd.y * va.z) * tmp; + float h = (vb.z * vc.x - va.z * vd.x) * tmp; + float i = -1.0; + float j = (vd.x * vd.y * va.z + vd.z * vb.y * vc.x) * tmp - (vd.y * vb.z * vc.x + vd.x * vc.z * vb.y) * tmp; + + float p = dot(float3(a, b, c), rd.xzy * rd.xzy) + dot(float3(d, e, f), rd.xzy * rd.zyx); + float q = dot(float3(2.0, 2.0, 2.0) * ro.xzy * rd.xyz, float3(a, b, c)) + dot(ro.xzz * rd.zxy, float3(d, d, e)) + + dot(ro.yyx * rd.zxy, float3(e, f, f)) + dot(float3(g, h, i), rd.xzy); + float r = dot(float3(a, b, c), ro.xzy * ro.xzy) + dot(float3(d, e, f), ro.xzy * ro.zyx) + dot(float3(g, h, i), ro.xzy) + j; + + if (abs(p) < 0.000001) { + float tt = -r / q; + if (tt <= 0.0) return false; + t = tt; + float3 pos = ro + t * rd; + if (length(pos) > sz) return false; + float3 grad = float3(2.0) * pos.xzy * float3(a, b, c) + pos.zxz * float3(d, d, e) + pos.yyx * float3(f, e, f) + float3(g, h, i); + norm = -normalize(grad); + return true; + } else { + float sq = q * q - 4.0 * p * r; + if (sq < 0.0) return false; + float s = sqrt(sq); + float t0 = (-q + s) / (2.0 * p); + float t1 = (-q - s) / (2.0 * p); + float tt1 = min(t0 < 0.0 ? t1 : t0, t1 < 0.0 ? t0 : t1); + float tt2 = max(t0 > 0.0 ? t1 : t0, t1 > 0.0 ? t0 : t1); + float tt0 = tt1; + if (tt0 <= 0.0) return false; + float3 pos = ro + tt0 * rd; + bool ru = step(sz, length(pos)) > 0.5; + if (ru) { + tt0 = tt2; + pos = ro + tt0 * rd; + } + if (tt0 <= 0.0) return false; + bool ru2 = step(sz, length(pos)) > 0.5; + if (ru2) return false; + + if ((tt2 > 0.0) && (!ru) && !(step(sz, length(ro + tt2 * rd)) > 0.5)) { + si = true; + fadesi = s; + tsi = tt2; + float3 tpos = ro + tsi * rd; + float3 tgrad = float3(2.0) * tpos.xzy * float3(a, b, c) + tpos.zxz * float3(d, d, e) + + tpos.yyx * float3(f, e, f) + float3(g, h, i); + normsi = -normalize(tgrad); + } + + fade = s; + t = tt0; + float3 grad = float3(2.0) * pos.xzy * float3(a, b, c) + pos.zxz * float3(d, d, e) + pos.yyx * float3(f, e, f) + float3(g, h, i); + norm = -normalize(grad); + return true; + } +} + +static float dot2(float3 v) { return dot(v, v); } + +static float segShadow(float3 ro, float3 rd, float3 pa, float sh) { + float dm = dot(rd.yz, rd.yz); + float k1 = (ro.x - pa.x) * dm; + float k2 = (ro.x + pa.x) * dm; + float2 k5 = (ro.yz + pa.yz) * dm; + float k3 = dot(ro.yz + pa.yz, rd.yz); + float2 k4 = (pa.yz + pa.yz) * rd.yz; + float2 k6 = (pa.yz + pa.yz) * dm; + + for (int i = 0; i < 4; i++) { + float2 s = float2(i & 1, i >> 1); + float t = dot(s, k4) - k3; + if (t > 0.0) { + sh = min(sh, dot2(float3(clamp(-rd.x * t, k1, k2), k5 - k6 * s) + rd * t) / (t * t)); + } + } + return sh; +} + +static float boxSoftShadow(float3 ro, float3 rd, float3 rad, float sk) { + rd += 0.0001 * (1.0 - abs(sign(rd))); + float3 rdd = rd; + float3 roo = ro; + + float3 m = 1.0 / rdd; + float3 n = m * roo; + float3 k = abs(m) * rad; + + float3 t1 = -n - k; + float3 t2 = -n + k; + + float tN = max(max(t1.x, t1.y), t1.z); + float tF = min(min(t2.x, t2.y), t2.z); + + if (tN < tF && tF > 0.0) return 0.0; + + float sh = 1.0; + sh = segShadow(roo.xyz, rdd.xyz, rad.xyz, sh); + sh = segShadow(roo.yzx, rdd.yzx, rad.yzx, sh); + sh = segShadow(roo.zxy, rdd.zxy, rad.zxy, sh); + sh = clamp(sk * sqrt(sh), 0.0, 1.0); + return sh * sh * (3.0 - 2.0 * sh); +} + +static float boxRay(float3 ro, float3 rd, float3 r, thread float3& nn, bool entering) { + rd += 0.0001 * (1.0 - abs(sign(rd))); + float3 dr = 1.0 / rd; + float3 n = ro * dr; + float3 k = r * abs(dr); + + float3 pin = -k - n; + float3 pout = k - n; + float tin = max(pin.x, max(pin.y, pin.z)); + float tout = min(pout.x, min(pout.y, pout.z)); + if (tin > tout) return -1.0; + if (entering) { + nn = -sign(rd) * step(pin.zxy, pin.xyz) * step(pin.yzx, pin.xyz); + } else { + nn = sign(rd) * step(pout.xyz, pout.zxy) * step(pout.xyz, pout.yzx); + } + return entering ? tin : tout; +} + +static float3 bgcol(float3 rd) { + return mix(float3(0.01), float3(0.336, 0.458, 0.668), 1.0 - pow(abs(rd.z + 0.25), 1.3)); +} + +static float3 background(float3 ro, float3 rd, float3 l_dir, thread float& alpha) { + float t = (-BOXDIMS.z - ro.z) / rd.z; + alpha = 0.0; + float3 bgc = bgcol(rd); + if (t < 0.0) return bgc; + float2 uv = ro.xy + t * rd.xy; + float shad = boxSoftShadow((ro + t * rd), normalize(l_dir + float3(0.0, 0.0, 1.0)) * rotz(PI * 0.65), BOXDIMS, 1.5); + float aofac = smoothstep(-0.95, 0.75, length(abs(uv) - min(abs(uv), float2(0.45)))); + aofac = min(aofac, smoothstep(-0.65, 1.0, shad)); + float lght = max(dot(normalize(ro + t * rd + float3(0.0, -0.0, -5.0)), normalize(l_dir - float3(0.0, 0.0, 1.0)) * rotz(PI * 0.65)), 0.0); + float3 col = mix(float3(0.4), float3(0.71, 0.772, 0.895), lght * lght * aofac + 0.05) * aofac; + alpha = 1.0 - smoothstep(7.0, 10.0, length(uv)); + return mix(col * length(col) * 0.8, bgc, smoothstep(7.0, 10.0, length(uv))); +} + +static float4 insides(float3 ro, float3 rd, float3 nor_c, float3 l_dir, thread float& tout) { + tout = -1.0; + + float pi = 3.1415926; + + if (abs(nor_c.x) > 0.5) { + rd = rd.xzy * nor_c.x; + ro = ro.xzy * nor_c.x; + } else if (abs(nor_c.z) > 0.5) { + l_dir = l_dir * roty(pi); + rd = rd.yxz * nor_c.z; + ro = ro.yxz * nor_c.z; + } else if (abs(nor_c.y) > 0.5) { + l_dir = l_dir * rotz(-pi * 0.5); + rd = rd * nor_c.y; + ro = ro * nor_c.y; + } + + const float curvature = 0.5; + float bil_size = 1.0; + float4 ps = float4(-bil_size, -bil_size, bil_size, bil_size) * curvature; + float4 ph = float4(-bil_size, bil_size, bil_size, -bil_size) * curvature; + + float4 colx[3] = { float4(0.0), float4(0.0), float4(0.0) }; + float3 dx[3] = { float3(-1.0), float3(-1.0), float3(-1.0) }; + float4 colxsi[3] = { float4(0.0), float4(0.0), float4(0.0) }; + int order[3] = { 0, 1, 2 }; + + for (int i = 0; i < 3; i++) { + if (abs(nor_c.x) > 0.5) { + ro = ro * rotz(-pi * (1.0 / 3.0)); + rd = rd * rotz(-pi * (1.0 / 3.0)); + } else if (abs(nor_c.z) > 0.5) { + ro = ro * rotz(pi * (1.0 / 3.0)); + rd = rd * rotz(pi * (1.0 / 3.0)); + } else if (abs(nor_c.y) > 0.5) { + ro = ro * rotx(pi * (1.0 / 3.0)); + rd = rd * rotx(pi * (1.0 / 3.0)); + } + float3 normnew; + float tnew; + bool si; + float tsi; + float3 normsi; + float fade; + float fadesi; + + if (iBilinearPatch(ro, rd, ps, ph, bil_size, tnew, normnew, si, tsi, normsi, fade, fadesi)) { + if (tnew > 0.0) { + float4 tcol, tcolsi; + calcColor(ro, rd, normnew, tnew, bil_size, i, si, tsi, tcol, tcolsi); + if (tcol.a > 0.0) { + dx[i] = float3(tnew, float(si), tsi); + + float dif = clamp(dot(normnew, l_dir), 0.0, 1.0); + float amb = clamp(0.5 + 0.5 * dot(normnew, l_dir), 0.0, 1.0); + + { + float3 shad = float3(0.32, 0.43, 0.54) * amb + float3(1.0, 0.9, 0.7) * dif; + const float3 tcr = float3(1.0, 0.21, 0.11); + float ta = clamp(length(tcol.rgb), 0.0, 1.0); + tcol = clamp(tcol * tcol * 2.0, 0.0, 1.0); + float4 tvalx = float4(tcol.rgb * shad * 1.4 + 3.0 * (tcr * tcol.rgb) * clamp(1.0 - (amb + dif), 0.0, 1.0), min(tcol.a, ta)); + tvalx.rgb = clamp(2.0 * tvalx.rgb * tvalx.rgb, 0.0, 1.0); + tvalx *= min(fade * 5.0, 1.0); + colx[i] = tvalx; + } + if (si) { + dif = clamp(dot(normsi, l_dir), 0.0, 1.0); + amb = clamp(0.5 + 0.5 * dot(normsi, l_dir), 0.0, 1.0); + float3 shad = float3(0.32, 0.43, 0.54) * amb + float3(1.0, 0.9, 0.7) * dif; + const float3 tcr = float3(1.0, 0.21, 0.11); + float ta = clamp(length(tcolsi.rgb), 0.0, 1.0); + tcolsi = clamp(tcolsi * tcolsi * 2.0, 0.0, 1.0); + float4 tvalx = float4(tcolsi.rgb * shad + 3.0 * (tcr * tcolsi.rgb) * clamp(1.0 - (amb + dif), 0.0, 1.0), min(tcolsi.a, ta)); + tvalx.rgb = clamp(2.0 * tvalx.rgb * tvalx.rgb, 0.0, 1.0); + tvalx.rgb *= min(fadesi * 5.0, 1.0); + colxsi[i] = tvalx; + } + } + } + } + } + + // sort by dx[*].x descending (3 passes of bubble sort like the GLSL) + if (dx[0].x < dx[1].x) { float3 tv = dx[0]; dx[0] = dx[1]; dx[1] = tv; int ti = order[0]; order[0] = order[1]; order[1] = ti; } + if (dx[1].x < dx[2].x) { float3 tv = dx[1]; dx[1] = dx[2]; dx[2] = tv; int ti = order[1]; order[1] = order[2]; order[2] = ti; } + if (dx[0].x < dx[1].x) { float3 tv = dx[0]; dx[0] = dx[1]; dx[1] = tv; int ti = order[0]; order[0] = order[1]; order[1] = ti; } + + tout = max(max(dx[0].x, dx[1].x), dx[2].x); + + float a = 1.0; + if (dx[0].y < 0.5) { + a = colx[order[0]].a; + } + + bool rul[3] = { + ((dx[0].y > 0.5) && (dx[1].x <= 0.0)), + ((dx[1].y > 0.5) && (dx[0].x > dx[1].z)), + ((dx[2].y > 0.5) && (dx[1].x > dx[2].z)) + }; + for (int k = 0; k < 3; k++) { + if (rul[k]) { + float4 tcolxsi = colxsi[order[k]]; + float4 tcolx = colx[order[k]]; + float4 tvalx = mix(tcolxsi, tcolx, tcolx.a); + float4 tvalx2 = mix(float4(0.0), tvalx, max(tcolx.a, tcolxsi.a)); + colx[order[k]] = tvalx2; + } + } + + float a1 = (dx[1].y < 0.5) ? colx[order[1]].a : ((dx[1].z > dx[0].x) ? colx[order[1]].a : 1.0); + float a2 = (dx[2].y < 0.5) ? colx[order[2]].a : ((dx[2].z > dx[1].x) ? colx[order[2]].a : 1.0); + float3 col = mix(mix(colx[order[0]].rgb, colx[order[1]].rgb, a1), colx[order[2]].rgb, a2); + a = max(max(a, a1), a2); + return float4(col, a); +} + +fragment float4 cube_lines_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float iTime = U.iTime; + + float3 l_dir = normalize(float3(0.0, 1.0, 0.0)); + l_dir = l_dir * rotz(0.5); + float mouseY = PI * 0.49 - smoothstep(0.0, 8.5, fmod((iTime + tshift) * 0.33, 25.0)) + * (1.0 - smoothstep(14.0, 24.0, fmod((iTime + tshift) * 0.33, 25.0))) * 0.55 * PI; + float mouseX = -2.0 * PI - 0.25 * (iTime * ROTATION_SPEED + tshift); + + float3 eye = 4.0 * float3(cos(mouseX) * cos(mouseY), sin(mouseX) * cos(mouseY), sin(mouseY)); + float3 w = normalize(-eye); + float3 up = float3(0.0, 0.0, 1.0); + float3 u = normalize(cross(w, up)); + float3 v = cross(u, w); + + float4 tot = float4(0.0); + float2 uv = (fragCoord - 0.5 * U.iResolution) / U.iResolution.x; + float3 rd = normalize(w * FDIST + uv.x * u + uv.y * v); + + float3 ni; + float t = boxRay(eye, rd, BOXDIMS, ni, true); + float3 ro = eye + t * rd; + float2 coords = ro.xy * ni.z / BOXDIMS.xy + ro.yz * ni.x / BOXDIMS.yz + ro.zx * ni.y / BOXDIMS.zx; + float fadeborders = (1.0 - smoothstep(0.915, 1.05, abs(coords.x))) * (1.0 - smoothstep(0.915, 1.05, abs(coords.y))); + + if (t > 0.0) { + float3 col = float3(0.0); + float R0 = (IOR - 1.0) / (IOR + 1.0); + R0 *= R0; + + float2 theta = float2(0.0); + float3 n = float3(cos(theta.x) * sin(theta.y), sin(theta.x) * sin(theta.y), cos(theta.y)); + + float3 nr = n.zxy * ni.x + n.yzx * ni.y + n.xyz * ni.z; + float3 rdr = reflect(rd, nr); + float talpha; + float3 reflcol = background(ro, rdr, l_dir, talpha); + + float3 rd2 = refract(rd, nr, 1.0 / IOR); + + float accum = 1.0; + float3 no2 = ni; + float3 ro_refr = ro; + + float4 colo[2] = { float4(0.0), float4(0.0) }; + + for (int j = 0; j < 2; j++) { + float tb; + float2 coords2 = ro_refr.xy * no2.z + ro_refr.yz * no2.x + ro_refr.zx * no2.y; + float3 eye2 = float3(coords2, -1.0); + float3 rd2trans = rd2.yzx * no2.x + rd2.zxy * no2.y + rd2.xyz * no2.z; + + rd2trans.z = -rd2trans.z; + float4 internalcol = insides(eye2, rd2trans, no2, l_dir, tb); + if (tb > 0.0) { + internalcol.rgb *= accum; + colo[j] = internalcol; + } + + if ((tb <= 0.0) || (internalcol.a < 1.0)) { + float tout = boxRay(ro_refr, rd2, BOXDIMS, no2, false); + no2 = n.zyx * no2.x + n.xzy * no2.y + n.yxz * no2.z; + float3 rout = ro_refr + tout * rd2; + float3 rdout = refract(rd2, -no2, IOR); + float fresnel2 = R0 + (1.0 - R0) * pow(1.0 - dot(rdout, no2), 1.3); + rd2 = reflect(rd2, -no2); + + ro_refr = rout; + ro_refr.z = max(ro_refr.z, -0.999); + + accum *= fresnel2; + } + } + float fresnel = R0 + (1.0 - R0) * pow(1.0 - dot(-rd, nr), 5.0); + col = mix(mix(colo[1].rgb * colo[1].a, colo[0].rgb, colo[0].a) * fadeborders, reflcol, pow(fresnel, 1.5)); + col = clamp(col, 0.0, 1.0); + + float cineshader_alpha = clamp(0.15 * dot(eye, ro), 0.0, 1.0); + tot += float4(col, cineshader_alpha); + } else { + float alpha; + tot += float4(background(eye, rd, l_dir, alpha), 0.15); + } + + float4 outColor = tot; + outColor.rgb = clamp(outColor.rgb, 0.0, 1.0); + return outColor; +} diff --git a/shaders/cube_lines/cube_lines.frag.spv b/shaders/cube_lines/cube_lines.frag.spv new file mode 100644 index 0000000..14aa383 Binary files /dev/null and b/shaders/cube_lines/cube_lines.frag.spv differ diff --git a/shaders/cube_lines/cube_lines.vk.glsl b/shaders/cube_lines/cube_lines.vk.glsl new file mode 100644 index 0000000..55aaddf --- /dev/null +++ b/shaders/cube_lines/cube_lines.vk.glsl @@ -0,0 +1,782 @@ +#version 450 + +// Name: Cube lines +// Author: Danil +// URL: https://www.shadertoy.com/view/NslGRN + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + + +// Note: Original shader uses iChannel0 for background blending (optional feature) +// Since we don't support texture channels, that line is commented out +// The shader works perfectly without it in default mode + +// Created by Danil (2021+) https://cohost.org/arugl +// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. +// self https://www.shadertoy.com/view/NslGRN + + +// --defines for "DESKTOP WALLPAPERS" that use this shader-- +// comment or uncomment every define to make it work (add or remove "//" before #define) + + +// this shadertoy use ALPHA, NO_ALPHA set alpha to 1, BG_ALPHA set background as alpha +// iChannel0 used as background if alpha ignored by wallpaper-app +//#define NO_ALPHA +//#define BG_ALPHA +//#define SHADOW_ALPHA +//#define ONLY_BOX + + +// save PERFORMANCE by disabling shadow +//#define NO_SHADOW + + +// static CAMERA position, 0.49 on top, 0.001 horizontal +//#define CAMERA_POS 0.049 + + +// speed of ROTATION +#define ROTATION_SPEED 0.8999 + + +// static SHAPE form, default 0.5 +//#define STATIC_SHAPE 0.15 + + +// static SCALE far/close to camera, 2.0 is default, exampe 0.5 or 10.0 +//#define CAMERA_FAR 0.1 + + +// ANIMATION shape change +//#define ANIM_SHAPE + + +// ANIMATION color change +//#define ANIM_COLOR + + +// custom COLOR, and change those const values +//#define USE_COLOR +const vec3 color_blue=vec3(0.5,0.65,0.8); +const vec3 color_red=vec3(0.99,0.2,0.1); + + +// use 4xAA for cube only (set 2-4-etc level of AA) +//#define AA_CUBE 4 + +// use 4xAA for everything - derivative filtering will not be used, look fcos2 +// this is very slow - DO NOT USE +//#define AA_ALL 4 + + + +// --shader code-- + +// Layers sorted and support transparency and self-intersection-transparency +// Antialiasing is only dFd. (with some dFd fixes around edges) + +// using iq's intersectors: https://iquilezles.org/articles/intersectors +// using https://www.shadertoy.com/view/ltKBzG +// using https://www.shadertoy.com/view/tsVXzh +// using https://www.shadertoy.com/view/WlffDn +// using https://www.shadertoy.com/view/WslGz4 + +#define tshift 53. + +// reflect back side +//#define backside_refl + +// Camera with mouse +// #define MOUSE_control (disabled - no iMouse support) + +// min(iFrame,0) does not speedup compilation in ANGLE +#define ANGLE_loops 0 + + +// this shader discover Nvidia bug with arrays https://www.shadertoy.com/view/NslGR4 +// use DEBUG with BUG, BUG trigger that bug and one layer will be white on Nvidia in OpenGL +//#define DEBUG +//#define BUG + +#define FDIST 0.7 +#define PI 3.1415926 +#define GROUNDSPACING 0.5 +#define GROUNDGRID 0.05 +#define BOXDIMS vec3(0.75, 0.75, 1.25) + +#define IOR 1.33 + +mat3 rotx(float a){float s = sin(a);float c = cos(a);return mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, c, s), vec3(0.0, -s, c)); } +mat3 roty(float a){float s = sin(a);float c = cos(a);return mat3(vec3(c, 0.0, s), vec3(0.0, 1.0, 0.0), vec3(-s, 0.0, c));} +mat3 rotz(float a){float s = sin(a);float c = cos(a);return mat3(vec3(c, s, 0.0), vec3(-s, c, 0.0), vec3(0.0, 0.0, 1.0 ));} + +vec3 fcos1(vec3 x) { + vec3 w = fwidth(x); + //if((length(w)==0.))return vec3(0.); // dFd fix2 + //w*=0.; //test + float lw=length(w); + if((lw==0.)||isnan(lw)||isinf(lw)){vec3 tc=vec3(0.); for(int i=0;i<8;i++)tc+=cos(x+x*float(i-4)*(0.01*400./iResolution.y));return tc/8.;} + + return cos(x) * smoothstep(3.14 * 2.0, 0.0, w); +} + +vec3 fcos2( vec3 x){return cos(x);} +vec3 fcos( vec3 x){ +#ifdef AA_ALL + return fcos2(x); +#else + return fcos1(x); +#endif +} + +vec3 getColor(vec3 p) +{ + // dFd fix, dFd broken on borders, but it fix only top level dFd, self intersection has border + //if (length(p) > 0.99)return vec3(0.); + p = abs(p); + + p *= 01.25; + p = 0.5 * p / dot(p, p); +#ifdef ANIM_COLOR + p+=0.072*iTime; +#endif + + float t = (0.13) * length(p); + vec3 col = vec3(0.3, 0.4, 0.5); + col += 0.12 * fcos(6.28318 * t * 1.0 + vec3(0.0, 0.8, 1.1)); + col += 0.11 * fcos(6.28318 * t * 3.1 + vec3(0.3, 0.4, 0.1)); + col += 0.10 * fcos(6.28318 * t * 5.1 + vec3(0.1, 0.7, 1.1)); + col += 0.10 * fcos(6.28318 * t * 17.1 + vec3(0.2, 0.6, 0.7)); + col += 0.10 * fcos(6.28318 * t * 31.1 + vec3(0.1, 0.6, 0.7)); + col += 0.10 * fcos(6.28318 * t * 65.1 + vec3(0.0, 0.5, 0.8)); + col += 0.10 * fcos(6.28318 * t * 115.1 + vec3(0.1, 0.4, 0.7)); + col += 0.10 * fcos(6.28318 * t * 265.1 + vec3(1.1, 1.4, 2.7)); + col = clamp(col, 0., 1.); + + return col; +} + +void calcColor(vec3 ro, vec3 rd, vec3 nor, float d, float len, int idx, bool si, float td, out vec4 colx, + out vec4 colsi) +{ + + vec3 pos = (ro + rd * d); +#ifdef DEBUG + float a = 1. - smoothstep(len - 0.15, len + 0.00001, length(pos)); + if (idx == 0)colx = vec4(1., 0., 0., a); + if (idx == 1)colx = vec4(0., 1., 0., a); + if (idx == 2)colx = vec4(0., 0., 1., a); + if (si) + { + pos = (ro + rd * td); + float ta = 1. - smoothstep(len - 0.15, len + 0.00001, length(pos)); + if (idx == 0)colsi = vec4(1., 0., 0., ta); + if (idx == 1)colsi = vec4(0., 1., 0., ta); + if (idx == 2)colsi = vec4(0., 0., 1., ta); + } +#else + float a = 1. - smoothstep(len - 0.15*0.5, len + 0.00001, length(pos)); + //a=1.; + vec3 col = getColor(pos); + colx = vec4(col, a); + if (si) + { + pos = (ro + rd * td); + float ta = 1. - smoothstep(len - 0.15*0.5, len + 0.00001, length(pos)); + //ta=1.; + col = getColor(pos); + colsi = vec4(col, ta); + } +#endif +} + +// xSI is self intersect data, fade to fix dFd on edges +bool iBilinearPatch(in vec3 ro, in vec3 rd, in vec4 ps, in vec4 ph, in float sz, out float t, out vec3 norm, + out bool si, out float tsi, out vec3 normsi, out float fade, out float fadesi) +{ + vec3 va = vec3(0.0, 0.0, ph.x + ph.w - ph.y - ph.z); + vec3 vb = vec3(0.0, ps.w - ps.y, ph.z - ph.x); + vec3 vc = vec3(ps.z - ps.x, 0.0, ph.y - ph.x); + vec3 vd = vec3(ps.xy, ph.x); + t = -1.; + tsi = -1.; + si = false; + fade = 1.; + fadesi = 1.; + norm=vec3(0.,1.,0.);normsi=vec3(0.,1.,0.); + + float tmp = 1.0 / (vb.y * vc.x); + float a = 0.0; + float b = 0.0; + float c = 0.0; + float d = va.z * tmp; + float e = 0.0; + float f = 0.0; + float g = (vc.z * vb.y - vd.y * va.z) * tmp; + float h = (vb.z * vc.x - va.z * vd.x) * tmp; + float i = -1.0; + float j = (vd.x * vd.y * va.z + vd.z * vb.y * vc.x) * tmp - (vd.y * vb.z * vc.x + vd.x * vc.z * vb.y) * tmp; + + float p = dot(vec3(a, b, c), rd.xzy * rd.xzy) + dot(vec3(d, e, f), rd.xzy * rd.zyx); + float q = dot(vec3(2.0, 2.0, 2.0) * ro.xzy * rd.xyz, vec3(a, b, c)) + dot(ro.xzz * rd.zxy, vec3(d, d, e)) + + dot(ro.yyx * rd.zxy, vec3(e, f, f)) + dot(vec3(g, h, i), rd.xzy); + float r = + dot(vec3(a, b, c), ro.xzy * ro.xzy) + dot(vec3(d, e, f), ro.xzy * ro.zyx) + dot(vec3(g, h, i), ro.xzy) + j; + + if (abs(p) < 0.000001) + { + float tt = -r / q; + if (tt <= 0.) + return false; + t = tt; + // normal + + vec3 pos = ro + t * rd; + if(length(pos)>sz)return false; + vec3 grad = + vec3(2.0) * pos.xzy * vec3(a, b, c) + pos.zxz * vec3(d, d, e) + pos.yyx * vec3(f, e, f) + vec3(g, h, i); + norm = -normalize(grad); + return true; + } + else + { + float sq = q * q - 4.0 * p * r; + if (sq < 0.0) + { + return false; + } + else + { + float s = sqrt(sq); + float t0 = (-q + s) / (2.0 * p); + float t1 = (-q - s) / (2.0 * p); + float tt1 = min(t0 < 0.0 ? t1 : t0, t1 < 0.0 ? t0 : t1); + float tt2 = max(t0 > 0.0 ? t1 : t0, t1 > 0.0 ? t0 : t1); + float tt0 = tt1; + if (tt0 <= 0.) + return false; + vec3 pos = ro + tt0 * rd; + // black border on end of circle and self intersection with alpha come because dFd + // uncomment this to see or rename fcos2 to fcos + //sz+=0.3; + bool ru = step(sz, length(pos)) > 0.5; + if (ru) + { + tt0 = tt2; + pos = ro + tt0 * rd; + } + if (tt0 <= 0.) + return false; + bool ru2 = step(sz, length(pos)) > 0.5; + if (ru2) + return false; + + // self intersect + if ((tt2 > 0.) && ((!ru)) && !(step(sz, length(ro + tt2 * rd)) > 0.5)) + { + si = true; + fadesi=s; + tsi = tt2; + vec3 tpos = ro + tsi * rd; + // normal + vec3 tgrad = vec3(2.0) * tpos.xzy * vec3(a, b, c) + tpos.zxz * vec3(d, d, e) + + tpos.yyx * vec3(f, e, f) + vec3(g, h, i); + normsi = -normalize(tgrad); + } + + fade=s; + t = tt0; + // normal + vec3 grad = + vec3(2.0) * pos.xzy * vec3(a, b, c) + pos.zxz * vec3(d, d, e) + pos.yyx * vec3(f, e, f) + vec3(g, h, i); + norm = -normalize(grad); + + return true; + } + } +} + +float dot2( in vec3 v ) { return dot(v,v); } + +float segShadow( in vec3 ro, in vec3 rd, in vec3 pa, float sh ) +{ + float dm = dot(rd.yz,rd.yz); + float k1 = (ro.x-pa.x)*dm; + float k2 = (ro.x+pa.x)*dm; + vec2 k5 = (ro.yz+pa.yz)*dm; + float k3 = dot(ro.yz+pa.yz,rd.yz); + vec2 k4 = (pa.yz+pa.yz)*rd.yz; + vec2 k6 = (pa.yz+pa.yz)*dm; + + for( int i=0; i<4 + ANGLE_loops; i++ ) + { + vec2 s = vec2(i&1,i>>1); + float t = dot(s,k4) - k3; + + if( t>0.0 ) + sh = min(sh,dot2(vec3(clamp(-rd.x*t,k1,k2),k5-k6*s)+rd*t)/(t*t)); + } + return sh; +} + +float boxSoftShadow( in vec3 ro, in vec3 rd, in vec3 rad, in float sk ) +{ + rd += 0.0001 * (1.0 - abs(sign(rd))); + vec3 rdd = rd; + vec3 roo = ro; + + vec3 m = 1.0/rdd; + vec3 n = m*roo; + vec3 k = abs(m)*rad; + + vec3 t1 = -n - k; + vec3 t2 = -n + k; + + float tN = max( max( t1.x, t1.y ), t1.z ); + float tF = min( min( t2.x, t2.y ), t2.z ); + + if( tN0.0) return 0.0; + + float sh = 1.0; + sh = segShadow( roo.xyz, rdd.xyz, rad.xyz, sh ); + sh = segShadow( roo.yzx, rdd.yzx, rad.yzx, sh ); + sh = segShadow( roo.zxy, rdd.zxy, rad.zxy, sh ); + sh = clamp(sk*sqrt(sh),0.0,1.0); + return sh*sh*(3.0-2.0*sh); +} + +float box(in vec3 ro, in vec3 rd, in vec3 r, out vec3 nn, bool entering) +{ + rd += 0.0001 * (1.0 - abs(sign(rd))); + vec3 dr = 1.0 / rd; + vec3 n = ro * dr; + vec3 k = r * abs(dr); + + vec3 pin = -k - n; + vec3 pout = k - n; + float tin = max(pin.x, max(pin.y, pin.z)); + float tout = min(pout.x, min(pout.y, pout.z)); + if (tin > tout) + return -1.; + if (entering) + { + nn = -sign(rd) * step(pin.zxy, pin.xyz) * step(pin.yzx, pin.xyz); + } + else + { + nn = sign(rd) * step(pout.xyz, pout.zxy) * step(pout.xyz, pout.yzx); + } + return entering ? tin : tout; +} + +vec3 bgcol(in vec3 rd) +{ + return mix(vec3(0.01), vec3(0.336, 0.458, .668), 1. - pow(abs(rd.z+0.25), 1.3)); +} + +vec3 background(in vec3 ro, in vec3 rd , vec3 l_dir, out float alpha) +{ +#ifdef ONLY_BOX +alpha=0.; +return vec3(0.01); +#endif + float t = (-BOXDIMS.z - ro.z) / rd.z; + alpha=0.; + vec3 bgc = bgcol(rd); + if (t < 0.) + return bgc; + vec2 uv = ro.xy + t * rd.xy; +#ifdef NO_SHADOW + float shad=1.; +#else + float shad = boxSoftShadow((ro + t * rd), normalize(l_dir+vec3(0.,0.,1.))*rotz(PI*0.65) , BOXDIMS, 1.5); +#endif + float aofac = smoothstep(-0.95, .75, length(abs(uv) - min(abs(uv), vec2(0.45)))); + aofac = min(aofac,smoothstep(-0.65, 1., shad)); + float lght=max(dot(normalize(ro + t * rd+vec3(0.,-0.,-5.)), normalize(l_dir-vec3(0.,0.,1.))*rotz(PI*0.65)), 0.0); + vec3 col = mix(vec3(0.4), vec3(.71,.772,0.895), lght*lght* aofac+ 0.05) * aofac; + alpha=1.-smoothstep(7.,10.,length(uv)); +#ifdef SHADOW_ALPHA + //alpha=clamp(alpha*max(lght*lght*0.95,(1.-aofac)*1.25),0.,1.); + alpha=clamp(alpha*(1.-aofac)*1.25,0.,1.); +#endif + return mix(col*length(col)*0.8,bgc,smoothstep(7.,10.,length(uv))); +} + +#define swap(a,b) tv=a;a=b;b=tv + +vec4 insides(vec3 ro, vec3 rd, vec3 nor_c, vec3 l_dir, out float tout) +{ + tout = -1.; + vec3 trd=rd; + + vec3 col = vec3(0.); + + float pi = 3.1415926; + + if (abs(nor_c.x) > 0.5) + { + rd = rd.xzy * nor_c.x; + ro = ro.xzy * nor_c.x; + } + else if (abs(nor_c.z) > 0.5) + { + l_dir *= roty(pi); + rd = rd.yxz * nor_c.z; + ro = ro.yxz * nor_c.z; + } + else if (abs(nor_c.y) > 0.5) + { + l_dir *= rotz(-pi * 0.5); + rd = rd * nor_c.y; + ro = ro * nor_c.y; + } + +#ifdef ANIM_SHAPE + float curvature = (0.001+1.5-1.5*smoothstep(0.,8.5,mod((iTime+tshift)*0.44,20.))*(1.-smoothstep(10.,18.5,mod((iTime+tshift)*0.44,20.)))); + // curvature(to not const above) make compilation on Angle 15+ sec +#else +#ifdef STATIC_SHAPE + const float curvature = STATIC_SHAPE; +#else + const float curvature = .5; +#endif +#endif + float bil_size = 1.; + vec4 ps = vec4(-bil_size, -bil_size, bil_size, bil_size) * curvature; + vec4 ph = vec4(-bil_size, bil_size, bil_size, -bil_size) * curvature; + + vec4 [3]colx=vec4[3](vec4(0.),vec4(0.),vec4(0.)); + vec3 [3]dx=vec3[3](vec3(-1.),vec3(-1.),vec3(-1.)); + vec4 [3]colxsi=vec4[3](vec4(0.),vec4(0.),vec4(0.)); + int [3]order=int[3](0,1,2); + + for (int i = 0; i < 3 + ANGLE_loops; i++) + { + if (abs(nor_c.x) > 0.5) + { + ro *= rotz(-pi * (1. / float(3))); + rd *= rotz(-pi * (1. / float(3))); + } + else if (abs(nor_c.z) > 0.5) + { + ro *= rotz(pi * (1. / float(3))); + rd *= rotz(pi * (1. / float(3))); + } + else if (abs(nor_c.y) > 0.5) + { + ro *= rotx(pi * (1. / float(3))); + rd *= rotx(pi * (1. / float(3))); + } + vec3 normnew; + float tnew; + bool si; + float tsi; + vec3 normsi; + float fade; + float fadesi; + + if (iBilinearPatch(ro, rd, ps, ph, bil_size, tnew, normnew, si, tsi, normsi, fade, fadesi)) + { + if (tnew > 0.) + { + vec4 tcol, tcolsi; + calcColor(ro, rd, normnew, tnew, bil_size, i, si, tsi, tcol, tcolsi); + if (tcol.a > 0.0) + { + { + vec3 tvalx = vec3(tnew, float(si), tsi); + dx[i]=tvalx; + } +#ifdef DEBUG + colx[i]=tcol; + if (si)colxsi[i]=tcolsi; +#else + + float dif = clamp(dot(normnew, l_dir), 0.0, 1.0); + float amb = clamp(0.5 + 0.5 * dot(normnew, l_dir), 0.0, 1.0); + + { +#ifdef USE_COLOR + vec3 shad = 0.57 * color_blue * amb + 1.5*color_blue.bgr * dif; + const vec3 tcr = color_red; +#else + vec3 shad = vec3(0.32, 0.43, 0.54) * amb + vec3(1.0, 0.9, 0.7) * dif; + const vec3 tcr = vec3(1.,0.21,0.11); +#endif + float ta = clamp(length(tcol.rgb),0.,1.); + tcol=clamp(tcol*tcol*2.,0.,1.); + vec4 tvalx = + vec4((tcol.rgb*shad*1.4 + 3.*(tcr*tcol.rgb)*clamp(1.-(amb+dif),0.,1.)), min(tcol.a,ta)); + tvalx.rgb=clamp(2.*tvalx.rgb*tvalx.rgb,0.,1.); + tvalx*=(min(fade*5.,1.)); + colx[i]=tvalx; + } + if (si) + { + dif = clamp(dot(normsi, l_dir), 0.0, 1.0); + amb = clamp(0.5 + 0.5 * dot(normsi, l_dir), 0.0, 1.0); + { +#ifdef USE_COLOR + vec3 shad = 0.57 * color_blue * amb + 1.5*color_blue.bgr * dif; + const vec3 tcr = color_red; +#else + vec3 shad = vec3(0.32, 0.43, 0.54) * amb + vec3(1.0, 0.9, 0.7) * dif; + const vec3 tcr = vec3(1.,0.21,0.11); +#endif + float ta = clamp(length(tcolsi.rgb),0.,1.); + tcolsi=clamp(tcolsi*tcolsi*2.,0.,1.); + vec4 tvalx = + vec4(tcolsi.rgb * shad + 3.*(tcr*tcolsi.rgb)*clamp(1.-(amb+dif),0.,1.), min(tcolsi.a,ta)); + tvalx.rgb=clamp(2.*tvalx.rgb*tvalx.rgb,0.,1.); + tvalx.rgb*=(min(fadesi*5.,1.)); + colxsi[i]=tvalx; + } + } +#endif + } + } + } + } + // transparency logic and layers sorting + float a = 1.; + if (dx[0].x < dx[1].x){{vec3 swap(dx[0], dx[1]);}{int swap(order[0], order[1]);}} + if (dx[1].x < dx[2].x){{vec3 swap(dx[1], dx[2]);}{int swap(order[1], order[2]);}} + if (dx[0].x < dx[1].x){{vec3 swap(dx[0], dx[1]);}{int swap(order[0], order[1]);}} + + tout = max(max(dx[0].x, dx[1].x), dx[2].x); + + if (dx[0].y < 0.5) + { + a=colx[order[0]].a; + } + +#if !(defined(DEBUG)&&defined(BUG)) + + // self intersection + bool [3] rul= bool[3]( + ((dx[0].y > 0.5) && (dx[1].x <= 0.)), + ((dx[1].y > 0.5) && (dx[0].x > dx[1].z)), + ((dx[2].y > 0.5) && (dx[1].x > dx[2].z)) + ); + for(int k=0;k<3;k++){ + if(rul[k]){ + vec4 tcolxsi = vec4(0.); + tcolxsi=colxsi[order[k]]; + vec4 tcolx = vec4(0.); + tcolx=colx[order[k]]; + + vec4 tvalx = mix(tcolxsi, tcolx, tcolx.a); + colx[order[k]]=tvalx; + + vec4 tvalx2 = mix(vec4(0.), tvalx, max(tcolx.a, tcolxsi.a)); + colx[order[k]]=tvalx2; + } + } + +#endif + + float a1 = (dx[1].y < 0.5) ? colx[order[1]].a : ((dx[1].z > dx[0].x) ? colx[order[1]].a : 1.); + float a2 = (dx[2].y < 0.5) ? colx[order[2]].a : ((dx[2].z > dx[1].x) ? colx[order[2]].a : 1.); + col = mix(mix(colx[order[0]].rgb, colx[order[1]].rgb, a1), colx[order[2]].rgb, a2); + a = max(max(a, a1), a2); + return vec4(col, a); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) +{ + float osc = 0.5; + vec3 l_dir = normalize(vec3(0., 1., 0.)); + l_dir *= rotz(0.5); + float mouseY = 1.0 * 0.5 * PI; + // Note: MOUSE_control disabled (no iMouse support) + // #ifdef MOUSE_control + // mouseY = (1.0 - 1.15 * iMouse.y / iResolution.y) * 0.5 * PI; + // if(iMouse.y < 1.) + // #endif +#ifdef CAMERA_POS + mouseY = PI*CAMERA_POS; +#else + mouseY = PI*0.49 - smoothstep(0.,8.5,mod((iTime+tshift)*0.33,25.))*(1.-smoothstep(14.,24.0,mod((iTime+tshift)*0.33,25.))) * 0.55 * PI; +#endif +#ifdef ROTATION_SPEED + float mouseX = -2.*PI-0.25*(iTime*ROTATION_SPEED+tshift); +#else + float mouseX = -2.*PI-0.25*(iTime+tshift); +#endif + // Note: MOUSE_control disabled (no iMouse support) + // #ifdef MOUSE_control + // mouseX+=-(iMouse.x / iResolution.x) * 2. * PI; + // #endif + +#ifdef CAMERA_FAR + vec3 eye = (2. + CAMERA_FAR) * vec3(cos(mouseX) * cos(mouseY), sin(mouseX) * cos(mouseY), sin(mouseY)); +#else + vec3 eye = 4. * vec3(cos(mouseX) * cos(mouseY), sin(mouseX) * cos(mouseY), sin(mouseY)); +#endif + vec3 w = normalize(-eye); + vec3 up = vec3(0., 0., 1.); + vec3 u = normalize(cross(w, up)); + vec3 v = cross(u, w); + + vec4 tot=vec4(0.); +#if defined(AA_CUBE)||defined(AA_ALL) +#ifdef AA_CUBE + const int AA = AA_CUBE; +#else + const int AA = AA_ALL; +#endif + vec3 incol_once=vec3(0.); + bool in_once=false; + vec4 incolbg_once=vec4(0.); + bool bg_in_once=false; + vec4 outcolbg_once=vec4(0.); + bool bg_out_once=false; + for( int mx=0; mx 0.) + { + float ang = -iTime * 0.33; + vec3 col = vec3(0.); +#ifdef AA_CUBE + if(in_once)col=incol_once; + else{ + in_once=true; +#endif + float R0 = (IOR - 1.) / (IOR + 1.); + R0 *= R0; + + vec2 theta = vec2(0.); + vec3 n = vec3(cos(theta.x) * sin(theta.y), sin(theta.x) * sin(theta.y), cos(theta.y)); + + vec3 nr = n.zxy * ni.x + n.yzx * ni.y + n.xyz * ni.z; + vec3 rdr = reflect(rd, nr); + float talpha; + vec3 reflcol = background(ro, rdr, l_dir,talpha); + + vec3 rd2 = refract(rd, nr, 1. / IOR); + + float accum = 1.; + vec3 no2 = ni; + vec3 ro_refr = ro; + + vec4 [2] colo = vec4[2](vec4(0.),vec4(0.)); + + for (int j = 0; j < 2 + ANGLE_loops; j++) + { + float tb; + vec2 coords2 = ro_refr.xy * no2.z + ro_refr.yz * no2.x + ro_refr.zx * no2.y; + vec3 eye2 = vec3(coords2, -1.); + vec3 rd2trans = rd2.yzx * no2.x + rd2.zxy * no2.y + rd2.xyz * no2.z; + + rd2trans.z = -rd2trans.z; + vec4 internalcol = insides(eye2, rd2trans, no2, l_dir, tb); + if (tb > 0.) + { + internalcol.rgb *= accum; + colo[j]=internalcol; + } + + if ((tb <= 0.) || (internalcol.a < 1.)) + { + float tout = box(ro_refr, rd2, BOXDIMS, no2, false); + no2 = n.zyx * no2.x + n.xzy * no2.y + n.yxz * no2.z; + vec3 rout = ro_refr + tout * rd2; + vec3 rdout = refract(rd2, -no2, IOR); + float fresnel2 = R0 + (1. - R0) * pow(1. - dot(rdout, no2), 1.3); + rd2 = reflect(rd2, -no2); + +#ifdef backside_refl + if((dot(rdout, no2))>0.5){fresnel2=1.;} +#endif + ro_refr = rout; + ro_refr.z = max(ro_refr.z, -0.999); + + accum *= fresnel2; + } + } + float fresnel = R0 + (1. - R0) * pow(1. - dot(-rd, nr), 5.); + col = mix(mix(colo[1].rgb * colo[1].a, colo[0].rgb, colo[0].a)*fadeborders, reflcol, pow(fresnel, 1.5)); + col=clamp(col,0.,1.); +#ifdef AA_CUBE + } + incol_once=col; + if(!bg_in_once){ + bg_in_once=true; + float alpha; + incolbg_once = vec4(background(eye, rd, l_dir, alpha), 0.15); +#if defined(BG_ALPHA)||defined(ONLY_BOX)||defined(SHADOW_ALPHA) + incolbg_once.w = alpha; +#endif + } +#endif + + float cineshader_alpha = 0.; + cineshader_alpha = clamp(0.15*dot(eye,ro),0.,1.); + vec4 tcolx = vec4(col, cineshader_alpha); +#if defined(BG_ALPHA)||defined(ONLY_BOX)||defined(SHADOW_ALPHA) + tcolx.w = 1.; +#endif + tot += tcolx; + } + else + { + vec4 tcolx = vec4(0.); +#ifdef AA_CUBE + if(!bg_out_once){ + bg_out_once=true; +#endif + float alpha; + tcolx = vec4(background(eye, rd, l_dir, alpha), 0.15); +#if defined(BG_ALPHA)||defined(ONLY_BOX)||defined(SHADOW_ALPHA) + tcolx.w = alpha; +#endif +#ifdef AA_CUBE + outcolbg_once=tcolx; + }else tcolx=max(outcolbg_once,incolbg_once); +#endif + tot += tcolx; + } +#if defined(AA_CUBE)||defined(AA_ALL) + } + tot /= float(AA*AA); +#endif + fragColor = tot; +#ifdef NO_ALPHA + fragColor.w = 1.; +#endif + fragColor.rgb=clamp(fragColor.rgb,0.,1.); + // Note: iChannel0 line removed (texture channel not supported) + // Original line was for optional background blending when BG_ALPHA/ONLY_BOX/SHADOW_ALPHA defined + // #if defined(BG_ALPHA)||defined(ONLY_BOX)||defined(SHADOW_ALPHA) + // fragColor.rgb=fragColor.rgb*fragColor.w+texture(iChannel0, fragCoord/iResolution.xy).rgb*(1.-fragColor.w); + // #endif +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/dbz/dbz.frag.msl b/shaders/dbz/dbz.frag.msl new file mode 100644 index 0000000..aff2880 --- /dev/null +++ b/shaders/dbz/dbz.frag.msl @@ -0,0 +1,127 @@ +#include +using namespace metal; + +// New Leaked 3I/Atlas NASA Footage — msm01 +// MSL port of dbz.vk.glsl. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +constant float NBCaps = 3.0; + +static float2x2 r2d(float a) { + float c = cos(a), s = sin(a); + return float2x2(c, s, -s, c); +} + +static float hash12(float2 p) { + float3 p3 = fract(float3(p.xyx) * 0.1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +static float fbm(float2 v_p) { + float pvpx = v_p.x; + float2 V1 = float2(floor(pvpx)); + float2 V2 = float2(floor(pvpx + 1.0)); + return mix(hash12(V1), hash12(V2), smoothstep(0.0, 1.0, fract(pvpx))); +} + +#define S(a,b,c) smoothstep(a,b,c) + +fragment float4 dbz_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 p = float2((1.0 / U.iResolution.y) * (fragCoord.x - U.iResolution.x / 2.0), + fragCoord.y / U.iResolution.y - 0.5); + + p.x = -p.x; + p *= 150.0; + + float4 col = float4(0.05, 0.05, 0.15, 1.0); + + float2 save1 = p; + + p = p * r2d(-0.05); + col = mix(col, float4(0.2, 0.3, 0.5, 1.0), + smoothstep(75.0, 0.0, abs(p.y - 5.0 * fbm(float2(0.01 * (p.x - 33.333 * U.iTime))) + 3.5))); + p = p * r2d(0.05); + + p = p * r2d(-0.05); + p *= 0.35; + p += float2(-5.0 * U.iTime, 0.0); + + float2 b = fract(5.0 * p); + p = floor(5.0 * p); + if (fbm(float2(p.x * p.y)) > 0.996) { + col += clamp(1.0 - pow(3.0 * length(b + float2(-0.5)), 0.5), 0.0, 1.0); + } + + p = save1; + float2 save3; + + float Nb_Capsules = clamp(NBCaps, 0.0, 4.0); + for (float i = 0.0; i < Nb_Capsules; i++) { + p = save1; + p = p * r2d(-0.05); + p *= 2.5; + p *= 1.0 - 0.25 * i; + p += float2(150.0 * fbm(float2(0.15 * U.iTime + i * 54.321)) - 75.0, + 50.0 * sin(0.25 * U.iTime + i * 54.321) - 25.0); + save3 = p; + + p *= 0.04; + p.y = abs(p.y); + + if (p.x > 0.0) { + col += float4(0.0, 1.0, 0.5, 1.0) * smoothstep(0.2, 0.0, abs(p.y - 0.05 * fbm(float2(1.5 * p.x - 40.0 * U.iTime))) - 0.05) * smoothstep(29.0, 0.0, abs(p.x)); + col += float4(1.0, 1.0, 1.0, 1.0) * smoothstep(0.1, 0.0, abs(p.y - 0.05 * fbm(float2(1.5 * p.x - 40.0 * U.iTime))) - 0.05) * smoothstep(29.0, 0.0, abs(p.x)); + } + + p = save3; + p.y = abs(p.y); + p += float2(-10.0, 0.0); + p *= float2(0.75, 1.0); + + col += 0.8 * float4(0.0, 1.0, 0.5, 1.0) * S(20.0, 0.0, length(p) - 25.0 + 7.0 * sin(0.30 * length(p) * atan2(p.y, p.x) + 55.0 * U.iTime)); + col += 0.8 * float4(1.0, 1.0, 1.0, 1.0) * S(20.0, 0.0, length(p) - 20.0 + 7.0 * sin(0.30 * length(p) * atan2(p.y, p.x) + 55.0 * U.iTime)); + + p = save3; + + col = mix(col, float4(1.0), 0.5 * S(10.0, 0.0, length(p + float2(5.0, 0.0)) - 20.0) * abs(sin(50.0 * U.iTime))); + col = mix(col, float4(1.0), 0.5 * S(20.0, 0.0, length(p + float2(5.0, 0.0)) - 20.0)); + col = mix(col, float4(1.0), S(0.01, 0.0, length(p) - 20.0)); + + if (length(p) - 20.0 < 0.0) { + col = mix(col, float4(0.65, 0.68, 0.68 + 0.1 * (3.0 - i), 1.0), S(0.5, 0.0, length(p - float2(2.0, 0.0)) - 17.0)); + if (S(0.0, 1.0, length(float2(3.0, 2.0) * p + float2(33.5, 0.0)) - 23.0) > 0.0) { + col = mix(col, float4(0.45, 0.55, 0.55 + 0.1 * (3.0 - i), 1.0), + 0.75 * S(0.5, 0.0, length(p - float2(2.0, 0.0) + 0.5 * fbm(float2(4.5 * atan2(p.y, p.x)))) - 9.0)); + } + + col = mix(col, float4(0.0), S(0.2, 0.0, abs(length(p) - 19.9) - 0.20)); + col = mix(col, float4(0.5, 0.2, 0.3, 1.0) + - S(5.0, 0.0, length(p + float2(-6.0, 15.0)) - 20.0) + - S(0.25, 0.0, abs(length(p + float2(0.0, 3.0)) - 15.0) - 0.4) + - S(0.0, 1.5, p.y - 8.5) + + 0.25 * float4(1.0, 0.5, 0.0, 1.0) * S(10.0, 0.0, abs(p.y)) + , + S(0.5, 0.0, length(float2(3.0, 2.0) * p + float2(35.0, 0.0)) - 19.9)); + + col = mix(col, float4(0.0, 0.0, 0.0, 1.0), S(1.0, 0.0, abs(length(float2(3.0, 2.0) * p + float2(35.0, 0.0)) - 19.9) - 0.1)); + col = mix(col, float4(0.0, 0.0, 0.0, 1.0), S(1.0, 0.0, abs(length(float2(3.0, 2.0) * p + float2(33.5, 0.0)) - 23.0) - 0.1)); + + if (p.y > 0.0) col = mix(col, float4(0.0, 0.0, 0.0, 1.0), S(1.0, 0.0, abs(length(float2(3.0, 2.0) * p + float2(29.0, 0.0)) - 30.0) - 0.1)); + if (p.y < 0.0) col = mix(col, float4(0.0, 0.0, 0.0, 1.0), S(1.0, 0.0, abs(length(float2(3.0, 2.0) * p + float2(-31.0, 0.0)) - 30.0) - 0.1)); + } + } + + return clamp(col, 0.0, 1.0); +} diff --git a/shaders/dbz/dbz.frag.spv b/shaders/dbz/dbz.frag.spv new file mode 100644 index 0000000..716fe9b Binary files /dev/null and b/shaders/dbz/dbz.frag.spv differ diff --git a/shaders/dbz/dbz.vk.glsl b/shaders/dbz/dbz.vk.glsl new file mode 100644 index 0000000..0419868 --- /dev/null +++ b/shaders/dbz/dbz.vk.glsl @@ -0,0 +1,127 @@ +#version 450 + +// Name: New Leaked 3I/Atlas NASA Footage +// Author: msm01 +// URL: https://www.shadertoy.com/view/3ftcRr + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +#define s(a,b,c) smoothstep(a,b,c) +#define PI 3.14159 +#define NBCaps 3. + +mat2 r2d(float a) { float c = cos(a), s = sin(a); return mat2(c, s, -s, c); } +float metaDiamond(vec2 p, vec2 pixel, float r) { vec2 d = abs(p - pixel); return r / (d.x + d.y); } + +float hash12(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * .1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +float fbm(in vec2 v_p) { + float pvpx = v_p.x; + vec2 V1 = vec2(floor(pvpx)); + vec2 V2 = vec2(floor(pvpx + 1.0)); + return mix(hash12(V1), hash12(V2), smoothstep(0.0, 1.0, fract(pvpx))); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 p = vec2((1.0 / iResolution.y) * (fragCoord.x - iResolution.x / 2.0), + fragCoord.y / iResolution.y - 0.5); + + p.x = -p.x; + p *= 150.0; + + vec4 col = vec4(0.05, 0.05, 0.15, 1.0); + + vec2 save1 = p; + vec2 save2 = p; + + p *= r2d(-0.05); + col = mix(col, vec4(0.2, 0.3, 0.5, 1.0), + smoothstep(75.0, 0.0, abs(p.y - 5.0 * fbm(vec2(0.01 * (p.x - 33.333 * iTime))) + 3.5))); + p *= r2d(0.05); + + p *= r2d(-0.05); + p *= 0.35; + p += vec2(-5.0 * iTime, 0.0); + + vec2 b = fract(5.0 * p); + p = floor(5.0 * p); + if (fbm(vec2(p.x * p.y)) > 0.996) col += clamp(1.0 - pow(3.0 * length(b + vec2(-0.5)), 0.5), 0.0, 1.0); + + p = save1; + vec2 save3; + + float Nb_Capsules = clamp(NBCaps, 0.0, 4.0); + for (float i = 0.0; i < Nb_Capsules; i++) { + p = save1; + p *= r2d(-0.05); + p *= 2.5; + p *= 1.0 - 0.25 * i; + p += vec2(150.0 * fbm(vec2(0.15 * iTime + i * 54.321)) - 75.0, + 50.0 * sin(0.25 * iTime + i * 54.321) - 25.0); + save3 = p; + + p *= 0.04; + p.y = abs(p.y); + + if (p.x > 0.0) { + col += vec4(0.0, 1.0, 0.5, 1.0) * smoothstep(0.2, 0.0, abs(p.y - 0.05 * fbm(vec2(1.5 * p.x - 40.0 * iTime))) - 0.05) * smoothstep(29.0, 0.0, abs(p.x)); + col += vec4(1.0, 1.0, 1.0, 1.0) * smoothstep(0.1, 0.0, abs(p.y - 0.05 * fbm(vec2(1.5 * p.x - 40.0 * iTime))) - 0.05) * smoothstep(29.0, 0.0, abs(p.x)); + } + + p = save3; + p.y = abs(p.y); + p += vec2(-10.0, 0.0); + p *= vec2(0.75, 1.0); + + col += 0.8 * vec4(0.0, 1.0, 0.5, 1.0) * s(20.0, 0.0, length(p) - 25.0 + 7.0 * sin(0.30 * length(p) * atan(p.y, p.x) + 55.0 * iTime)); + col += 0.8 * vec4(1.0, 1.0, 1.0, 1.0) * s(20.0, 0.0, length(p) - 20.0 + 7.0 * sin(0.30 * length(p) * atan(p.y, p.x) + 55.0 * iTime)); + + p = save3; + + col = mix(col, vec4(1.0), 0.5 * s(10.0, 0.0, length(p + vec2(5.0, 0.0)) - 20.0) * abs(sin(50.0 * iTime))); + col = mix(col, vec4(1.0), 0.5 * s(20.0, 0.0, length(p + vec2(5.0, 0.0)) - 20.0)); + + col = mix(col, vec4(1.0), s(0.01, 0.0, length(p) - 20.0)); + + if (length(p) - 20.0 < 0.0) { + col = mix(col, vec4(0.65, 0.68, 0.68 + 0.1 * (3.0 - i), 1.0), s(0.5, 0.0, length(p - vec2(2.0, 0.0)) - 17.0)); + if (s(0.0, 1.0, length(vec2(3.0, 2.0) * p + vec2(33.5, 0.0)) - 23.0) > 0.0) + col = mix(col, vec4(0.45, 0.55, 0.55 + 0.1 * (3.0 - i), 1.0), + 0.75 * s(0.5, 0.0, length(p - vec2(2.0, 0.0) + 0.5 * fbm(vec2(4.5 * atan(p.y, p.x)))) - 9.0)); + + col = mix(col, vec4(0.0), s(0.2, 0.0, abs(length(p) - 19.9) - 0.20)); + col = mix(col, vec4(0.5, 0.2, 0.3, 1.0) + - s(5.0, 0.0, length(p + vec2(-6.0, 15.0)) - 20.0) + - s(0.25, 0.0, abs(length(p + vec2(0.0, 3.0)) - 15.0) - 0.4) + - s(0.0, 1.5, p.y - 8.5) + + 0.25 * vec4(1.0, 0.5, 0.0, 1.0) * s(10.0, 0.0, abs(p.y)) + , + s(0.5, 0.0, length(vec2(3.0, 2.0) * p + vec2(35.0, 0.0)) - 19.9)); + + col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), s(1.0, 0.0, abs(length(vec2(3.0, 2.0) * p + vec2(35.0, 0.0)) - 19.9) - 0.1)); + col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), s(1.0, 0.0, abs(length(vec2(3.0, 2.0) * p + vec2(33.5, 0.0)) - 23.0) - 0.1)); + + if (p.y > 0.0) col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), s(1.0, 0.0, abs(length(vec2(3.0, 2.0) * p + vec2(29.0, 0.0)) - 30.0) - 0.1)); + if (p.y < 0.0) col = mix(col, vec4(0.0, 0.0, 0.0, 1.0), s(1.0, 0.0, abs(length(vec2(3.0, 2.0) * p + vec2(-31.0, 0.0)) - 30.0) - 0.1)); + } + } + + fragColor = clamp(col, 0.0, 1.0); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/fractal_pyramid/fractal_pyramid.frag.msl b/shaders/fractal_pyramid/fractal_pyramid.frag.msl new file mode 100644 index 0000000..5403a15 --- /dev/null +++ b/shaders/fractal_pyramid/fractal_pyramid.frag.msl @@ -0,0 +1,67 @@ +#include +using namespace metal; + +// Fractal Pyramid — bradjamesgrant +// MSL port of fractal_pyramid.vk.glsl. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +static float3 palette(float d) { + return mix(float3(0.2, 0.7, 0.9), float3(1.0, 0.0, 1.0), d); +} + +static float2 rotate(float2 p, float a) { + float c = cos(a); + float s = sin(a); + return p * float2x2(c, s, -s, c); +} + +static float mapScene(float3 p, float iTime) { + for (int i = 0; i < 8; ++i) { + float t = iTime * 0.2; + p.xz = rotate(p.xz, t); + p.xy = rotate(p.xy, t * 1.89); + p.xz = abs(p.xz); + p.xz -= 0.5; + } + return dot(sign(p), p) / 5.0; +} + +static float4 rm(float3 ro, float3 rd, float iTime) { + float t = 0.0; + float3 col = float3(0.0); + float d = 1.0; + for (int i = 0; i < 64; ++i) { + float3 p = ro + rd * t; + d = mapScene(p, iTime) * 0.5; + if (d < 0.02) break; + if (d > 100.0) break; + col += palette(length(p) * 0.1) / (400.0 * d); + t += d; + } + return float4(col, 1.0 / (d * 100.0)); +} + +fragment float4 fractal_pyramid_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 uv = (fragCoord - (U.iResolution * 0.5)) / U.iResolution.x; + float3 ro = float3(0.0, 0.0, -50.0); + ro.xz = rotate(ro.xz, U.iTime); + float3 cf = normalize(-ro); + float3 cs = normalize(cross(cf, float3(0.0, 1.0, 0.0))); + float3 cu = normalize(cross(cf, cs)); + + float3 uuv = ro + cf * 3.0 + uv.x * cs + uv.y * cu; + float3 rd = normalize(uuv - ro); + + return rm(ro, rd, U.iTime); +} diff --git a/shaders/fractal_pyramid/fractal_pyramid.frag.spv b/shaders/fractal_pyramid/fractal_pyramid.frag.spv new file mode 100644 index 0000000..a97a38e Binary files /dev/null and b/shaders/fractal_pyramid/fractal_pyramid.frag.spv differ diff --git a/shaders/fractal_pyramid/fractal_pyramid.vk.glsl b/shaders/fractal_pyramid/fractal_pyramid.vk.glsl new file mode 100644 index 0000000..7029fb1 --- /dev/null +++ b/shaders/fractal_pyramid/fractal_pyramid.vk.glsl @@ -0,0 +1,71 @@ +#version 450 + +// Name: Fractal Pyramid +// Author: bradjamesgrant +// URL: https://www.shadertoy.com/view/tsXBzS + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +vec3 palette(float d) { + return mix(vec3(0.2, 0.7, 0.9), vec3(1.0, 0.0, 1.0), d); +} + +vec2 rotate(vec2 p, float a) { + float c = cos(a); + float s = sin(a); + return p * mat2(c, s, -s, c); +} + +float mapScene(vec3 p) { + for (int i = 0; i < 8; ++i) { + float t = iTime * 0.2; + p.xz = rotate(p.xz, t); + p.xy = rotate(p.xy, t * 1.89); + p.xz = abs(p.xz); + p.xz -= 0.5; + } + return dot(sign(p), p) / 5.0; +} + +vec4 rm(vec3 ro, vec3 rd) { + float t = 0.0; + vec3 col = vec3(0.0); + float d = 1.0; + for (int i = 0; i < 64; ++i) { + vec3 p = ro + rd * t; + d = mapScene(p) * 0.5; + if (d < 0.02) break; + if (d > 100.0) break; + col += palette(length(p) * 0.1) / (400.0 * d); + t += d; + } + return vec4(col, 1.0 / (d * 100.0)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = (fragCoord - (iResolution.xy * 0.5)) / iResolution.x; + vec3 ro = vec3(0.0, 0.0, -50.0); + ro.xz = rotate(ro.xz, iTime); + vec3 cf = normalize(-ro); + vec3 cs = normalize(cross(cf, vec3(0.0, 1.0, 0.0))); + vec3 cu = normalize(cross(cf, cs)); + + vec3 uuv = ro + cf * 3.0 + uv.x * cs + uv.y * cu; + vec3 rd = normalize(uuv - ro); + + vec4 col = rm(ro, rd); + fragColor = col; +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/just_another_cube/just_another_cube.frag.msl b/shaders/just_another_cube/just_another_cube.frag.msl new file mode 100644 index 0000000..a30666a --- /dev/null +++ b/shaders/just_another_cube/just_another_cube.frag.msl @@ -0,0 +1,89 @@ +#include +using namespace metal; + +// Just Another Cube — mrange +// MSL port of just_another_cube.vk.glsl. The Shadertoy original uses +// mutable file-scope globals; in MSL we pass them by reference. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +constant float M = 1e-3; + +static float D(float3 p, + thread float2x2& R, + thread float& d, + thread float& G) { + p.xy = p.xy * R; + p.xz = p.xz * R; + + float3 S = sin(123.0 * p); + + float shell = abs(length(p) - 0.6); + p *= p * p * p; + d = pow(dot(p, p), 0.125) - 0.5 + - pow(1.0 + S.x * S.y * S.z, 8.0) / 1e5; + + G = min(G, max(shell, d)); + + return d; +} + +fragment float4 just_another_cube_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 C = in.uv * U.iResolution; + + float2x2 R; + float d = 1.0, z = 0.0, G = 9.0; + + float3 r = float3(U.iResolution, U.iResolution.y); + float3 I = normalize(float3(C - 0.5 * r.xy, r.y)); + float3 B = float3(1, 2, 9) * M; + float3 p = float3(0.0); + float3 O = float3(0.0); + + { + float4 cs = cos(0.3 * U.iTime + float4(0, 11, 33, 0)); + R = float2x2(cs.x, cs.y, cs.z, cs.w); + } + + for (; z < 9.0 && d > M; z += D(p, R, d, G)) { + p = z * I; + p.z -= 2.0; + } + + if (z < 9.0) { + for (int i = 0; i < 3; ) { + r = float3(0.0); + r[i] = M; + O[i++] = D(p + r, R, d, G) - D(p - r, R, d, G); + } + + O = normalize(O); + z = 1.0 + dot(O, I); + + r = reflect(I, O); + + C = (p + r * (5.0 - p.y) / abs(r.y)).xz; + + float3 colorTerm; + if (r.y > 0.0) { + d = sqrt(length(C * C)) + 1.0; + colorTerm = 5e2 * smoothstep(5.0, 4.0, d) * d * B; + } else { + colorTerm = exp(-2.0 * length(C)) * (B / M - 1.0); + } + + O = z * z * colorTerm + pow(1.0 + O.y, 5.0) * B; + } + + float4 result = sqrt(float4(O + B / G, O.x + B.x / G)); + return result; +} diff --git a/shaders/just_another_cube/just_another_cube.frag.spv b/shaders/just_another_cube/just_another_cube.frag.spv new file mode 100644 index 0000000..661fe27 Binary files /dev/null and b/shaders/just_another_cube/just_another_cube.frag.spv differ diff --git a/shaders/just_another_cube/just_another_cube.vk.glsl b/shaders/just_another_cube/just_another_cube.vk.glsl new file mode 100644 index 0000000..cefafcb --- /dev/null +++ b/shaders/just_another_cube/just_another_cube.vk.glsl @@ -0,0 +1,88 @@ +#version 450 + +// Name: Just Another Cube +// Author: mrange +// URL: https://www.shadertoy.com/view/3XdXRr +// CC0: Just another cube + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +mat2 R; +float d = 1.; +float z = 0.; +float G = 9.; +float M = 1e-3; + +float D(vec3 p) { + p.xy *= R; + p.xz *= R; + + vec3 S = sin(123. * p); + + G = min( + G, + max( + abs(length(p) - .6), + d = pow(dot(p *= p * p * p, p), .125) - .5 + - pow(1. + S.x * S.y * S.z, 8.) / 1e5 + ) + ); + + return d; +} + +void mainImage(out vec4 o, vec2 C) { + vec3 p, + O, + r = vec3(iResolution.xy, iResolution.y), + I = normalize(vec3(C - .5 * r.xy, r.y)), + B = vec3(1, 2, 9) * M; + + for ( + R = mat2(cos(.3 * iTime + vec4(0, 11, 33, 0))); + z < 9. && d > M; + z += D(p) + ) + p = z * I, + p.z -= 2.; + + O = vec3(0.0); + + if (z < 9.) { + for (int i = 0; i < 3; ) { + r -= r; + r[i] = M; + O[i++] = D(p + r) - D(p - r); + } + + z = 1. + dot(O = normalize(O), I); + + r = reflect(I, O); + + C = (p + r * (5. - p.y) / abs(r.y)).xz; + + O = + z * z * + ( + r.y > 0. + ? 5e2 * smoothstep(5., 4., d = sqrt(length(C * C)) + 1.) * d * B + : exp(-2. * length(C)) * (B / M - 1.) + ) + + pow(1. + O.y, 5.) * B; + } + + o = sqrt(O + B / G).xyzx; +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/octograms/octograms.frag.msl b/shaders/octograms/octograms.frag.msl new file mode 100644 index 0000000..1298725 --- /dev/null +++ b/shaders/octograms/octograms.frag.msl @@ -0,0 +1,95 @@ +#include +using namespace metal; + +// Octograms — whisky_shusuky +// MSL port of octograms.vk.glsl. The Shadertoy original uses a mutable +// file-scope `gTime`; in MSL we pass it as a parameter through the chain. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +static float2x2 rot(float a) { + float c = cos(a), s = sin(a); + return float2x2(c, s, -s, c); +} + +static float sdBox(float3 p, float3 b) { + float3 q = abs(p) - b; + return length(max(q, float3(0.0))) + min(max(q.x, max(q.y, q.z)), 0.0); +} + +static float boxGeom(float3 pos, float scale) { + pos *= scale; + float base = sdBox(pos, float3(0.4, 0.4, 0.1)) / 1.5; + pos.xy = (pos.xy * 5.0 - float2(0.0, 3.5)) * rot(0.75); + return -base; +} + +static float box_set(float3 pos, float gTime) { + float3 pos_origin = pos; + + pos = pos_origin; + pos.y += sin(gTime * 0.4) * 2.5; + pos.xy = pos.xy * rot(0.8); + float box1 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.y -= sin(gTime * 0.4) * 2.5; + pos.xy = pos.xy * rot(0.8); + float box2 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.x += sin(gTime * 0.4) * 2.5; + pos.xy = pos.xy * rot(0.8); + float box3 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.x -= sin(gTime * 0.4) * 2.5; + pos.xy = pos.xy * rot(0.8); + float box4 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.xy = pos.xy * rot(0.8); + float box5 = boxGeom(pos, 0.5) * 6.0; + + pos = pos_origin; + float box6 = boxGeom(pos, 0.5) * 6.0; + + return max(max(max(max(max(box1, box2), box3), box4), box5), box6); +} + +fragment float4 octograms_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 p = (fragCoord * 2.0 - U.iResolution) / min(U.iResolution.x, U.iResolution.y); + + float3 ro = float3(0.0, -0.2, U.iTime * 4.0); + float3 ray = normalize(float3(p, 1.5)); + ray.xy = ray.xy * rot(sin(U.iTime * 0.03) * 5.0); + ray.yz = ray.yz * rot(sin(U.iTime * 0.05) * 0.2); + float t = 0.1; + float ac = 0.0; + + for (int i = 0; i < 99; i++) { + float3 pos = ro + ray * t; + pos = fract((pos - 2.0) / 4.0) * 4.0 - 2.0; + float gTime = U.iTime - float(i) * 0.01; + + float d = box_set(pos, gTime); + d = max(abs(d), 0.01); + ac += exp(-d * 23.0); + t += d * 0.55; + } + + float3 col = float3(ac * 0.02); + col += float3(0.0, 0.2 * abs(sin(U.iTime)), 0.5 + sin(U.iTime) * 0.2); + + return float4(col, 1.0 - t * (0.02 + 0.02 * sin(U.iTime))); +} diff --git a/shaders/octograms/octograms.frag.spv b/shaders/octograms/octograms.frag.spv new file mode 100644 index 0000000..a2f3797 Binary files /dev/null and b/shaders/octograms/octograms.frag.spv differ diff --git a/shaders/octograms/octograms.vk.glsl b/shaders/octograms/octograms.vk.glsl new file mode 100644 index 0000000..598d867 --- /dev/null +++ b/shaders/octograms/octograms.vk.glsl @@ -0,0 +1,109 @@ +#version 450 + +// Name: Octograms +// Author: whisky_shusuky +// URL: https://www.shadertoy.com/view/tlVGDt + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +float gTime = 0.0; +const float REPEAT = 5.0; + +mat2 rot(float a) { + float c = cos(a), s = sin(a); + return mat2(c, s, -s, c); +} + +float sdBox(vec3 p, vec3 b) { + vec3 q = abs(p) - b; + return length(max(q, vec3(0.0))) + min(max(q.x, max(q.y, q.z)), 0.0); +} + +float boxGeom(vec3 pos, float scale) { + pos *= scale; + float base = sdBox(pos, vec3(.4, .4, .1)) / 1.5; + pos.xy *= 5.0; + pos.y -= 3.5; + pos.xy *= rot(.75); + float result = -base; + return result; +} + +float box_set(vec3 pos, float iTimeLocal) { + vec3 pos_origin = pos; + pos = pos_origin; + pos.y += sin(gTime * 0.4) * 2.5; + pos.xy *= rot(.8); + float box1 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.y -= sin(gTime * 0.4) * 2.5; + pos.xy *= rot(.8); + float box2 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.x += sin(gTime * 0.4) * 2.5; + pos.xy *= rot(.8); + float box3 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.x -= sin(gTime * 0.4) * 2.5; + pos.xy *= rot(.8); + float box4 = boxGeom(pos, 2.0 - abs(sin(gTime * 0.4)) * 1.5); + + pos = pos_origin; + pos.xy *= rot(.8); + float box5 = boxGeom(pos, .5) * 6.0; + + pos = pos_origin; + float box6 = boxGeom(pos, .5) * 6.0; + + float result = max(max(max(max(max(box1, box2), box3), box4), box5), box6); + return result; +} + +float mapScene(vec3 pos, float iTimeLocal) { + return box_set(pos, iTimeLocal); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 p = (fragCoord.xy * 2.0 - iResolution.xy) / min(iResolution.x, iResolution.y); + vec3 ro = vec3(0.0, -0.2, iTime * 4.0); + vec3 ray = normalize(vec3(p, 1.5)); + ray.xy = ray.xy * rot(sin(iTime * .03) * 5.0); + ray.yz = ray.yz * rot(sin(iTime * .05) * .2); + float t = 0.1; + vec3 col = vec3(0.0); + float ac = 0.0; + + for (int i = 0; i < 99; i++) { + vec3 pos = ro + ray * t; + pos = mod(pos - 2.0, 4.0) - 2.0; + gTime = iTime - float(i) * 0.01; + + float d = mapScene(pos, iTime); + + d = max(abs(d), 0.01); + ac += exp(-d * 23.0); + + t += d * 0.55; + } + + col = vec3(ac * 0.02); + col += vec3(0.0, 0.2 * abs(sin(iTime)), 0.5 + sin(iTime) * 0.2); + + fragColor = vec4(col, 1.0 - t * (0.02 + 0.02 * sin(iTime))); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/remember/remember.frag.msl b/shaders/remember/remember.frag.msl new file mode 100644 index 0000000..ac29bbb --- /dev/null +++ b/shaders/remember/remember.frag.msl @@ -0,0 +1,64 @@ +#include +using namespace metal; + +// Remember — diatribes +// MSL port of remember.vk.glsl. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +static float hash12(float2 p) { + float3 p3 = fract(float3(p.xyx) * 0.1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +fragment float4 remember_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 u = fragCoord; + + float3 q, p = float3(U.iResolution, U.iResolution.x / U.iResolution.y); + + float i = 0.0, s = 0.0; + float d = 0.125 * hash12(u); + float t = U.iTime * 0.1; + + u = (u + u - p.xy) / p.y; + if (abs(u.y) > 0.8) { return float4(0); } + + float4 o = float4(0.0); + + for (; i < 64.0; i++) { + + q = p = float3(u * d, d + t * 5.0); + // mat2(cos(.1*p.z+.1*t+vec4(0,33,11,0))) — column-major: (m00,m10,m01,m11) + float4 cs = cos(0.1 * p.z + 0.1 * t + float4(0, 33, 11, 0)); + float2x2 m = float2x2(cs.x, cs.y, cs.z, cs.w); + p.xy = p.xy * m; + + q.xz = cos(q.xz); + p.z = cos(p.z); + + for (s = 1.0; s++ < 6.0;) { + q += sin(0.6 * t + p.zxy * 0.6); + p += sin(t + t + p.yzx * s) * 0.6; + } + + s = 0.02 + abs(min(length(p + 3.0 * sin(p.z * 0.5)) - 4.0, length(q - 2.0 * sin(p.z * 0.4)) - 6.0)) * 0.2; + d += s; + + float4 brightTerm = min(0.01 * float4(6, 2, 1, 0) / max(length(u * sin(t + t + t)), 0.001), float4(50.0)); + o += brightTerm + 1.0 / s * length(u); + } + + o = tanh(max(o / 6e2 + dot(u, u) * 0.35, 0.0)); + return o; +} diff --git a/shaders/remember/remember.frag.spv b/shaders/remember/remember.frag.spv new file mode 100644 index 0000000..d819392 Binary files /dev/null and b/shaders/remember/remember.frag.spv differ diff --git a/shaders/remember/remember.vk.glsl b/shaders/remember/remember.vk.glsl new file mode 100644 index 0000000..5a31987 --- /dev/null +++ b/shaders/remember/remember.vk.glsl @@ -0,0 +1,61 @@ +#version 450 + +// Name: Remember +// Author: diatribes +// URL: https://www.shadertoy.com/view/tXSBDK + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +// fuzzy brain — Hash function to replace iChannel0 texture noise +float hash12(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * .1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +void mainImage(out vec4 o, vec2 u) { + + vec3 q, p = vec3(iResolution.xy, iResolution.x / iResolution.y); + + float i = 0.0, s, + d = .125 * hash12(u), + t = iTime * .1; + + u = (u + u - p.xy) / p.y; + if (abs(u.y) > .8) { o = vec4(0); return; } + + o = vec4(0.0); + + for (; i < 64.; i++) { + + q = p = vec3(u * d, d + t * 5.); + p.xy *= mat2(cos(.1 * p.z + .1 * t + vec4(0, 33, 11, 0))); + + q.xz = cos(q.xz); + p.z = cos(p.z); + for (s = 1.; s++ < 6.; + q += sin(.6 * t + p.zxy * .6), + p += sin(t + t + p.yzx * s) * .6); + + d += s = .02 + abs(min(length(p + 3. * sin(p.z * .5)) - 4., length(q - 2. * sin(p.z * .4)) - 6.)) * .2; + + vec4 brightTerm = min(.01 * vec4(6, 2, 1, 0) / max(length(u * sin(t + t + t)), 0.001), vec4(50.0)); + o += brightTerm + 1. / s * length(u); + + } + + o = tanh(max(o / 6e2 + dot(u, u) * .35, 0.)); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/seascape/seascape.frag.msl b/shaders/seascape/seascape.frag.msl new file mode 100644 index 0000000..bcd12ae --- /dev/null +++ b/shaders/seascape/seascape.frag.msl @@ -0,0 +1,181 @@ +#include +using namespace metal; + +// Seascape — Alexander Alekseev (TDM, 2014) +// MSL port of seascape.vk.glsl. iTime threaded through helpers because +// MSL does not allow file-scope mutable globals. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +constant int NUM_STEPS = 32; +constant float PI = 3.141592; +constant float EPSILON = 1e-3; + +constant int ITER_GEOMETRY = 3; +constant int ITER_FRAGMENT = 5; +constant float SEA_HEIGHT = 0.6; +constant float SEA_CHOPPY = 4.0; +constant float SEA_SPEED = 0.8; +constant float SEA_FREQ = 0.16; +constant float3 SEA_BASE = float3(0.0, 0.09, 0.18); +constant float3 SEA_WATER_COLOR = float3(0.8, 0.9, 0.6) * 0.6; +constant float2x2 octave_m = float2x2(1.6, 1.2, -1.2, 1.6); + +static float3x3 fromEuler(float3 ang) { + float2 a1 = float2(sin(ang.x), cos(ang.x)); + float2 a2 = float2(sin(ang.y), cos(ang.y)); + float2 a3 = float2(sin(ang.z), cos(ang.z)); + float3x3 m; + m[0] = float3(a1.y * a3.y + a1.x * a2.x * a3.x, a1.y * a2.x * a3.x + a3.y * a1.x, -a2.y * a3.x); + m[1] = float3(-a2.y * a1.x, a1.y * a2.y, a2.x); + m[2] = float3(a3.y * a1.x * a2.x + a1.y * a3.x, a1.x * a3.x - a1.y * a3.y * a2.x, a2.y * a3.y); + return m; +} + +static float hash(float2 p) { + float h = dot(p, float2(127.1, 311.7)); + return fract(sin(h) * 43758.5453123); +} + +static float noise(float2 p) { + float2 i = floor(p); + float2 f = fract(p); + float2 u = f * f * (3.0 - 2.0 * f); + return -1.0 + 2.0 * mix(mix(hash(i + float2(0.0, 0.0)), + hash(i + float2(1.0, 0.0)), u.x), + mix(hash(i + float2(0.0, 1.0)), + hash(i + float2(1.0, 1.0)), u.x), u.y); +} + +static float diffuseLight(float3 n, float3 l, float p) { + return pow(dot(n, l) * 0.4 + 0.6, p); +} + +static float specularLight(float3 n, float3 l, float3 e, float s) { + float nrm = (s + 8.0) / (PI * 8.0); + return pow(max(dot(reflect(e, n), l), 0.0), s) * nrm; +} + +static float3 getSkyColor(float3 e) { + e.y = (max(e.y, 0.0) * 0.8 + 0.2) * 0.8; + return float3(pow(1.0 - e.y, 2.0), 1.0 - e.y, 0.6 + (1.0 - e.y) * 0.4) * 1.1; +} + +static float sea_octave(float2 uv, float choppy) { + uv += noise(uv); + float2 wv = 1.0 - abs(sin(uv)); + float2 swv = abs(cos(uv)); + wv = mix(wv, swv, wv); + return pow(1.0 - pow(wv.x * wv.y, 0.65), choppy); +} + +static float seaMap(float3 p, float iTime, int iter) { + float SEA_TIME = 1.0 + iTime * SEA_SPEED; + float freq = SEA_FREQ; + float amp = SEA_HEIGHT; + float choppy = SEA_CHOPPY; + float2 uv = p.xz; uv.x *= 0.75; + + float d, h = 0.0; + for (int i = 0; i < iter; i++) { + d = sea_octave((uv + SEA_TIME) * freq, choppy); + d += sea_octave((uv - SEA_TIME) * freq, choppy); + h += d * amp; + uv = uv * octave_m; + freq *= 1.9; + amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); + } + return p.y - h; +} + +static float3 getSeaColor(float3 p, float3 n, float3 l, float3 eye, float3 dist) { + float fresnel = clamp(1.0 - dot(n, -eye), 0.0, 1.0); + fresnel = min(fresnel * fresnel * fresnel, 0.5); + + float3 reflected = getSkyColor(reflect(eye, n)); + float3 refracted = SEA_BASE + diffuseLight(n, l, 80.0) * SEA_WATER_COLOR * 0.12; + + float3 color = mix(refracted, reflected, fresnel); + + float atten = max(1.0 - dot(dist, dist) * 0.001, 0.0); + color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten; + + color += specularLight(n, l, eye, 600.0 * rsqrt(dot(dist, dist))); + + return color; +} + +static float3 getNormal(float3 p, float eps, float iTime) { + float3 n; + n.y = seaMap(p, iTime, ITER_FRAGMENT); + n.x = seaMap(float3(p.x + eps, p.y, p.z), iTime, ITER_FRAGMENT) - n.y; + n.z = seaMap(float3(p.x, p.y, p.z + eps), iTime, ITER_FRAGMENT) - n.y; + n.y = eps; + return normalize(n); +} + +static float heightMapTracing(float3 ori, float3 dir, thread float3& p, float iTime) { + float tm = 0.0; + float tx = 1000.0; + float hx = seaMap(ori + dir * tx, iTime, ITER_GEOMETRY); + if (hx > 0.0) { + p = ori + dir * tx; + return tx; + } + float hm = seaMap(ori, iTime, ITER_GEOMETRY); + for (int i = 0; i < NUM_STEPS; i++) { + float tmid = mix(tm, tx, hm / (hm - hx)); + p = ori + dir * tmid; + float hmid = seaMap(p, iTime, ITER_GEOMETRY); + if (hmid < 0.0) { + tx = tmid; + hx = hmid; + } else { + tm = tmid; + hm = hmid; + } + if (abs(hmid) < EPSILON) break; + } + return mix(tm, tx, hm / (hm - hx)); +} + +static float3 getPixel(float2 coord, float time, float2 iResolution, float iTime) { + float2 uv = coord / iResolution; + uv = uv * 2.0 - 1.0; + uv.x *= iResolution.x / iResolution.y; + + float3 ang = float3(sin(time * 3.0) * 0.1, sin(time) * 0.2 + 0.3, time); + float3 ori = float3(0.0, 3.5, time * 5.0); + float3 dir = normalize(float3(uv.xy, -2.0)); + dir.z += length(uv) * 0.14; + dir = normalize(dir) * fromEuler(ang); + + float3 p; + heightMapTracing(ori, dir, p, iTime); + float3 dist = p - ori; + float EPSILON_NRM = 0.1 / iResolution.x; + float3 n = getNormal(p, dot(dist, dist) * EPSILON_NRM, iTime); + float3 light = normalize(float3(0.0, 1.0, 0.8)); + + return mix( + getSkyColor(dir), + getSeaColor(p, n, light, dir, dist), + pow(smoothstep(0.0, -0.02, dir.y), 0.2)); +} + +fragment float4 seascape_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float time = U.iTime * 0.3; + float3 color = getPixel(fragCoord, time, U.iResolution, U.iTime); + return float4(pow(color, float3(0.65)), 1.0); +} diff --git a/shaders/seascape/seascape.frag.spv b/shaders/seascape/seascape.frag.spv new file mode 100644 index 0000000..5dc028a Binary files /dev/null and b/shaders/seascape/seascape.frag.spv differ diff --git a/shaders/seascape/seascape.vk.glsl b/shaders/seascape/seascape.vk.glsl new file mode 100644 index 0000000..ddb72a7 --- /dev/null +++ b/shaders/seascape/seascape.vk.glsl @@ -0,0 +1,200 @@ +#version 450 + +// Name: Seascape +// Author: Alexander Alekseev +// URL: https://www.shadertoy.com/view/Ms2SD1 +// +// "Seascape" by Alexander Alekseev aka TDM - 2014 +// CC BY-NC-SA 3.0 Unported License. + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +const int NUM_STEPS = 32; +const float PI = 3.141592; +const float EPSILON = 1e-3; +#define EPSILON_NRM (0.1 / iResolution.x) + +const int ITER_GEOMETRY = 3; +const int ITER_FRAGMENT = 5; +const float SEA_HEIGHT = 0.6; +const float SEA_CHOPPY = 4.0; +const float SEA_SPEED = 0.8; +const float SEA_FREQ = 0.16; +const vec3 SEA_BASE = vec3(0.0, 0.09, 0.18); +const vec3 SEA_WATER_COLOR = vec3(0.8, 0.9, 0.6) * 0.6; +#define SEA_TIME (1.0 + iTime * SEA_SPEED) +const mat2 octave_m = mat2(1.6, 1.2, -1.2, 1.6); + +mat3 fromEuler(vec3 ang) { + vec2 a1 = vec2(sin(ang.x), cos(ang.x)); + vec2 a2 = vec2(sin(ang.y), cos(ang.y)); + vec2 a3 = vec2(sin(ang.z), cos(ang.z)); + mat3 m; + m[0] = vec3(a1.y * a3.y + a1.x * a2.x * a3.x, a1.y * a2.x * a3.x + a3.y * a1.x, -a2.y * a3.x); + m[1] = vec3(-a2.y * a1.x, a1.y * a2.y, a2.x); + m[2] = vec3(a3.y * a1.x * a2.x + a1.y * a3.x, a1.x * a3.x - a1.y * a3.y * a2.x, a2.y * a3.y); + return m; +} + +float hash(vec2 p) { + float h = dot(p, vec2(127.1, 311.7)); + return fract(sin(h) * 43758.5453123); +} + +float noise(in vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + vec2 u = f * f * (3.0 - 2.0 * f); + return -1.0 + 2.0 * mix(mix(hash(i + vec2(0.0, 0.0)), + hash(i + vec2(1.0, 0.0)), u.x), + mix(hash(i + vec2(0.0, 1.0)), + hash(i + vec2(1.0, 1.0)), u.x), u.y); +} + +float diffuse(vec3 n, vec3 l, float p) { + return pow(dot(n, l) * 0.4 + 0.6, p); +} + +float specular(vec3 n, vec3 l, vec3 e, float s) { + float nrm = (s + 8.0) / (PI * 8.0); + return pow(max(dot(reflect(e, n), l), 0.0), s) * nrm; +} + +vec3 getSkyColor(vec3 e) { + e.y = (max(e.y, 0.0) * 0.8 + 0.2) * 0.8; + return vec3(pow(1.0 - e.y, 2.0), 1.0 - e.y, 0.6 + (1.0 - e.y) * 0.4) * 1.1; +} + +float sea_octave(vec2 uv, float choppy) { + uv += noise(uv); + vec2 wv = 1.0 - abs(sin(uv)); + vec2 swv = abs(cos(uv)); + wv = mix(wv, swv, wv); + return pow(1.0 - pow(wv.x * wv.y, 0.65), choppy); +} + +float map(vec3 p) { + float freq = SEA_FREQ; + float amp = SEA_HEIGHT; + float choppy = SEA_CHOPPY; + vec2 uv = p.xz; uv.x *= 0.75; + + float d, h = 0.0; + for (int i = 0; i < ITER_GEOMETRY; i++) { + d = sea_octave((uv + SEA_TIME) * freq, choppy); + d += sea_octave((uv - SEA_TIME) * freq, choppy); + h += d * amp; + uv *= octave_m; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); + } + return p.y - h; +} + +float map_detailed(vec3 p) { + float freq = SEA_FREQ; + float amp = SEA_HEIGHT; + float choppy = SEA_CHOPPY; + vec2 uv = p.xz; uv.x *= 0.75; + + float d, h = 0.0; + for (int i = 0; i < ITER_FRAGMENT; i++) { + d = sea_octave((uv + SEA_TIME) * freq, choppy); + d += sea_octave((uv - SEA_TIME) * freq, choppy); + h += d * amp; + uv *= octave_m; freq *= 1.9; amp *= 0.22; + choppy = mix(choppy, 1.0, 0.2); + } + return p.y - h; +} + +vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) { + float fresnel = clamp(1.0 - dot(n, -eye), 0.0, 1.0); + fresnel = min(fresnel * fresnel * fresnel, 0.5); + + vec3 reflected = getSkyColor(reflect(eye, n)); + vec3 refracted = SEA_BASE + diffuse(n, l, 80.0) * SEA_WATER_COLOR * 0.12; + + vec3 color = mix(refracted, reflected, fresnel); + + float atten = max(1.0 - dot(dist, dist) * 0.001, 0.0); + color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten; + + color += specular(n, l, eye, 600.0 * inversesqrt(dot(dist, dist))); + + return color; +} + +vec3 getNormal(vec3 p, float eps) { + vec3 n; + n.y = map_detailed(p); + n.x = map_detailed(vec3(p.x + eps, p.y, p.z)) - n.y; + n.z = map_detailed(vec3(p.x, p.y, p.z + eps)) - n.y; + n.y = eps; + return normalize(n); +} + +float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) { + float tm = 0.0; + float tx = 1000.0; + float hx = map(ori + dir * tx); + if (hx > 0.0) { + p = ori + dir * tx; + return tx; + } + float hm = map(ori); + for (int i = 0; i < NUM_STEPS; i++) { + float tmid = mix(tm, tx, hm / (hm - hx)); + p = ori + dir * tmid; + float hmid = map(p); + if (hmid < 0.0) { + tx = tmid; + hx = hmid; + } else { + tm = tmid; + hm = hmid; + } + if (abs(hmid) < EPSILON) break; + } + return mix(tm, tx, hm / (hm - hx)); +} + +vec3 getPixel(in vec2 coord, float time) { + vec2 uv = coord / iResolution.xy; + uv = uv * 2.0 - 1.0; + uv.x *= iResolution.x / iResolution.y; + + vec3 ang = vec3(sin(time * 3.0) * 0.1, sin(time) * 0.2 + 0.3, time); + vec3 ori = vec3(0.0, 3.5, time * 5.0); + vec3 dir = normalize(vec3(uv.xy, -2.0)); dir.z += length(uv) * 0.14; + dir = normalize(dir) * fromEuler(ang); + + vec3 p; + heightMapTracing(ori, dir, p); + vec3 dist = p - ori; + vec3 n = getNormal(p, dot(dist, dist) * EPSILON_NRM); + vec3 light = normalize(vec3(0.0, 1.0, 0.8)); + + return mix( + getSkyColor(dir), + getSeaColor(p, n, light, dir, dist), + pow(smoothstep(0.0, -0.02, dir.y), 0.2)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float time = iTime * 0.3; + vec3 color = getPixel(fragCoord, time); + fragColor = vec4(pow(color, vec3(0.65)), 1.0); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/shader_art_coding_introduction/shader_art_coding_introduction.frag.msl b/shaders/shader_art_coding_introduction/shader_art_coding_introduction.frag.msl new file mode 100644 index 0000000..3e2854b --- /dev/null +++ b/shaders/shader_art_coding_introduction/shader_art_coding_introduction.frag.msl @@ -0,0 +1,47 @@ +#include +using namespace metal; + +// Shader Art Coding Introduction — kishimisu +// MSL port of shader_art_coding_introduction.vk.glsl. + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +static float3 palette(float t) { + float3 a = float3(0.5, 0.5, 0.5); + float3 b = float3(0.5, 0.5, 0.5); + float3 c = float3(1.0, 1.0, 1.0); + float3 d = float3(0.263, 0.416, 0.557); + return a + b * cos(6.28318 * (c * t * d)); +} + +fragment float4 shader_art_coding_introduction_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 uv = (fragCoord * 2.0 - U.iResolution) / U.iResolution.y; + float2 uv0 = uv; + float3 finalColor = float3(0.0); + + for (float i = 0.0; i < 4.0; i++) { + uv = fract(uv * 1.5) - 0.5; + + float d = length(uv) * exp(-length(uv0)); + + float3 col = palette(length(uv0) + i * 0.4 + U.iTime * 0.4); + + d = sin(d * 8.0 + U.iTime) / 8.0; + d = abs(d); + d = pow(0.01 / d, 1.2); + + finalColor += col * d; + } + + return float4(finalColor, 1.0); +} diff --git a/shaders/shader_art_coding_introduction/shader_art_coding_introduction.frag.spv b/shaders/shader_art_coding_introduction/shader_art_coding_introduction.frag.spv new file mode 100644 index 0000000..a92b9ca Binary files /dev/null and b/shaders/shader_art_coding_introduction/shader_art_coding_introduction.frag.spv differ diff --git a/shaders/shader_art_coding_introduction/shader_art_coding_introduction.vk.glsl b/shaders/shader_art_coding_introduction/shader_art_coding_introduction.vk.glsl new file mode 100644 index 0000000..4ba4788 --- /dev/null +++ b/shaders/shader_art_coding_introduction/shader_art_coding_introduction.vk.glsl @@ -0,0 +1,50 @@ +#version 450 + +// Name: Shader Art Coding Introduction +// Author: kishimisu +// URL: https://www.shadertoy.com/view/mtyGWy + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +vec3 palette(float t) { + vec3 a = vec3(0.5, 0.5, 0.5); + vec3 b = vec3(0.5, 0.5, 0.5); + vec3 c = vec3(1.0, 1.0, 1.0); + vec3 d = vec3(0.263, 0.416, 0.557); + return a + b * cos(6.28318 * (c * t * d)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y; + vec2 uv0 = uv; + vec3 finalColor = vec3(0.0); + + for (float i = 0.0; i < 4.0; i++) { + uv = fract(uv * 1.5) - 0.5; + + float d = length(uv) * exp(-length(uv0)); + + vec3 col = palette(length(uv0) + i * 0.4 + iTime * 0.4); + + d = sin(d * 8.0 + iTime) / 8.0; + d = abs(d); + d = pow(0.01 / d, 1.2); + + finalColor += col * d; + } + + fragColor = vec4(finalColor, 1.0); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +} diff --git a/shaders/test/test.frag.spv b/shaders/test/test.frag.spv index e887b4a..5d83798 100644 Binary files a/shaders/test/test.frag.spv and b/shaders/test/test.frag.spv differ diff --git a/shaders/test/test.vk.glsl b/shaders/test/test.vk.glsl index 819ab8e..3d0312e 100644 --- a/shaders/test/test.vk.glsl +++ b/shaders/test/test.vk.glsl @@ -4,7 +4,8 @@ // Author: JailDesigner // // Vulkan port of test.gl.glsl. Bindings follow the SDL3 GPU convention: -// set=3, binding=0 — fragment uniform buffer (ShadertoyUniforms in C++). +// set=3, binding=0 — fragment uniform buffer (anonymous block: members +// are accessible directly as iTime / iResolution, like Shadertoy). layout(location = 0) in vec2 vUV; layout(location = 0) out vec4 FragColor; @@ -12,7 +13,7 @@ layout(location = 0) out vec4 FragColor; layout(set = 3, binding = 0) uniform ShadertoyUBO { float iTime; vec2 iResolution; -} u; +}; vec3 palette(float t) { vec3 a = vec3(1.0, 0.5, 0.5); @@ -23,10 +24,10 @@ vec3 palette(float t) { } void mainImage(out vec4 fragColor, in vec2 fragCoord) { - vec2 uv = (fragCoord * 2.0 - u.iResolution) / u.iResolution.y; + vec2 uv = (fragCoord * 2.0 - iResolution) / iResolution.y; float d = length(uv); vec3 col = palette(d); - d = sin(d * 8.0 + u.iTime) / 8.0; + d = sin(d * 8.0 + iTime) / 8.0; d = abs(d); d = 0.02 / d; col *= d; @@ -34,7 +35,7 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) { } void main() { - vec2 fragCoordPixels = vUV * u.iResolution; + vec2 fragCoordPixels = vUV * iResolution; vec4 outColor; mainImage(outColor, fragCoordPixels); FragColor = outColor; diff --git a/shaders/water/water.frag.msl b/shaders/water/water.frag.msl new file mode 100644 index 0000000..82249d5 --- /dev/null +++ b/shaders/water/water.frag.msl @@ -0,0 +1,40 @@ +#include +using namespace metal; + +// Water — diatribes +// MSL port of water.vk.glsl. Entry point is named after the shader (water_fs). + +struct ShadertoyUBO { + float iTime; + float2 iResolution; +}; + +struct PassthroughVOut { + float4 pos [[position]]; + float2 uv; +}; + +fragment float4 water_fs(PassthroughVOut in [[stage_in]], + constant ShadertoyUBO& U [[buffer(0)]]) { + float2 fragCoord = in.uv * U.iResolution; + float2 u = fragCoord; + + float s = 0.002, i = 0.0, n; + float3 r = float3(U.iResolution, U.iResolution.x / U.iResolution.y); + float3 p = float3(0); + u = (u - r.xy / 2.0) / r.y - 0.3; + + float4 o = float4(0); + + for (; i < 32.0 && s > 0.001; i++) { + float4 term = float4(5, 2, 1, 0) / max(length(u - 0.1), 0.001); + o += min(term, float4(100.0)); + p += float3(u * s, s); + s = 1.0 + p.y; + for (n = 0.01; n < 1.0; n += n) { + s += abs(dot(sin(p.z + U.iTime + p / n), float3(1))) * n * 0.1; + } + } + o = tanh(o / 5e2); + return o; +} diff --git a/shaders/water/water.frag.spv b/shaders/water/water.frag.spv new file mode 100644 index 0000000..0bbbc28 Binary files /dev/null and b/shaders/water/water.frag.spv differ diff --git a/shaders/water/water.vk.glsl b/shaders/water/water.vk.glsl new file mode 100644 index 0000000..56d59f8 --- /dev/null +++ b/shaders/water/water.vk.glsl @@ -0,0 +1,45 @@ +#version 450 + +// Name: Water +// Author: diatribes +// URL: https://www.shadertoy.com/view/tXjXDy + +layout(location = 0) in vec2 vUV; +layout(location = 0) out vec4 FragColor; + +layout(set = 3, binding = 0) uniform ShadertoyUBO { + float iTime; + vec2 iResolution; +}; + +/* + -2 by @FabriceNeyret2 + thanks!! :D + + If it doesn't display correctly, change line "r/r" to "vec3(1)" +*/ + +void mainImage( out vec4 o, vec2 u ) { + float s=.002, i=0., n; + vec3 r = vec3(iResolution.xy, iResolution.x/iResolution.y); + vec3 p = vec3(0); + u = (u-r.xy/2.)/r.y-.3; + + o = vec4(0); + + for(; i < 32. && s > .001; i++) { + vec4 term = vec4(5,2,1,0)/max(length(u-.1), 0.001); + o += min(term, vec4(100.0)); + for (p += vec3(u*s,s), s = 1. + p.y, n =.01; n < 1.; n+=n) { + s += abs(dot(sin(p.z+iTime+p / n), vec3(1))) * n*.1; + } + } + o = tanh(o/5e2); +} + +void main() { + vec2 fragCoordPixels = vUV * iResolution; + vec4 outColor; + mainImage(outColor, fragCoordPixels); + FragColor = outColor; +}