#version 460
#extension GL_EXT_scalar_block_layout : enable
#extension GL_NV_compute_shader_derivatives : require
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout(derivative_group_quadsNV) in;
layout(set = 0, binding = 0, rgba32f) uniform image2D hdrImage;
layout(push_constant) uniform Push {
float totalTime;
float extra1; // overall gloss/intensity (metal plastic)
float extra2; // distortion / reflection warp amount
float extra3; // specular sweep speed / phase
} pc;
#define PI 3.14159265358979323846
#define TAU (2.0 * PI)
#define PHI 1.618033988749895
#define EPS 0.0001
#define NUM_SHAPES 128u // Reduced for focus on reflections
float hash11(float p) {
p = fract(p * 0.1031);
p *= p 33.33;
return fract(2.0 * p * (p 33.33));
}
float hash(vec2 p) {
p = fract(p * vec2(0.1031, 0.11369));
p = dot(p, p 33.33);
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
float a = hash(i vec2(0,0));
float b = hash(i vec2(1,0));
float c = hash(i vec2(0,1));
float d = hash(i vec2(1,1));
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
float glow(float d, float str) {
return exp(-d * d * str);
}
float sdCircle(vec2 p, float r) {
return length(p) - r;
}
float sdBox(vec2 p, vec2 b) {
vec2 q = abs(p) - b;
return length(max(q, 0.0)) min(max(q.x, q.y), 0.0);
}
float sdTriangle(vec2 p, float s) {
p /= s;
p.y -= 0.577;
float d1 = max( p.x p.y * 0.577, -p.y);
float d2 = max(-p.x p.y * 0.577, -p.y);
float d3 = -p.y 0.577;
return max(max(d1, d2), d3) * s;
}
float sdRoundBar(vec2 p, float thickness, float roundness) {
return length(vec2(p.x, abs(p.y) - thickness * 0.5)) - roundness;
}
void main() {
ivec2 pix = ivec2(gl_GlobalInvocationID.xy);
ivec2 dim = imageSize(hdrImage);
if (any(greaterThanEqual(pix, dim))) return;
vec2 uv = (vec2(pix) 0.5) / vec2(dim);
uv = uv * 2.0 - 1.0;
uv.x *= float(dim.x) / float(dim.y);
float t = pc.totalTime * 0.4; // Slower for moody feel
// Dark ambient base (fewer lights)
vec3 col = vec3(0.08, 0.09, 0.12); // Deep shadows
// Dim floor with subtle reflection
float floorD = smoothstep(-1.0, 0.6, uv.y);
col = mix(col, vec3(0.12, 0.14, 0.18), floorD * 0.4);
// ────────────────────────────────────────────────
// Shiny chrome metal cage bars (strong reflections)
// ────────────────────────────────────────────────
float gloss = 0.8 0.4 * pc.extra1; // Higher = more mirror-like
float warp = 0.03 * pc.extra2;
float specSpeed = 1.2 pc.extra3 * 3.0;
vec2 cageUV = uv;
cageUV.x = sin(uv.y * 10.0 t * 0.8) * warp;
cageUV.y = cos(uv.x * 12.0 t * 0.6) * warp * 0.6;
// Vertical bars (thicker for presence)
float vertSpacing = 0.35;
float vert = mod(cageUV.x 0.5, vertSpacing) - vertSpacing * 0.5;
float vBar = sdRoundBar(vec2(vert, cageUV.y * 2.8), 0.035, 0.018);
// Horizontal bars
float horzSpacing = 0.38;
float horz = mod(cageUV.y 0.5, horzSpacing) - horzSpacing * 0.5;
float hBar = sdRoundBar(vec2(horz * 1.4, cageUV.x * 2.0), 0.028, 0.014);
float cage = min(vBar, hBar);
// Metal normal strong specular
vec3 lightDir = normalize(vec3(sin(t * specSpeed * 0.5), cos(t * specSpeed * 0.7), 1.5));
vec3 normal = normalize(vec3(-dFdx(cage), -dFdy(cage), 1.0));
float NdotL = max(0.0, dot(normal, lightDir));
float spec = pow(max(0.0, dot(reflect(-lightDir, normal), vec3(0,0,1))), 64.0) * gloss * 2.2;
// Fake env reflection (gradient noise for chrome feel)
vec3 env = mix(vec3(0.15, 0.18, 0.25), vec3(0.4, 0.45, 0.55), uv.y * 0.5 0.5);
env = noise(uv * 20.0 t * 0.2) * 0.08;
vec3 metalCol = env * (0.6 spec * 3.0) vec3(0.9, 0.95, 1.0) * spec * 1.8;
float cageMask = smoothstep(0.015, -0.005, cage) * gloss;
float cageRim = glow(cage, 50.0) * 1.2;
col = mix(col, metalCol, cageMask * 0.95);
col = metalCol * cageRim * 1.5;
// ────────────────────────────────────────────────
// Glossy plastic shapes (high specular, low diffuse)
// ────────────────────────────────────────────────
for (uint i = 0u; i < NUM_SHAPES; i) {
float fi = float(i);
float seed = hash11(fi * 0.00019 0.003);
float bounce = abs(sin(t * (1.2 seed * 1.8) seed * 15.0)) * 0.5;
float roll = t * (0.6 seed * 1.0);
vec2 pos = vec2(
sin(seed * TAU roll * 0.4) * 0.85,
-0.75 bounce sin(seed * PHI t * 0.25) * 0.08
);
// Modulate visibility to reduce clutter
if (hash11(fi t * 0.1) > 0.4) continue;
float type = mod(fi * PHI, 3.0);
vec3 baseCol = 0.5 0.5 * vec3(sin(fi * 2.3 t), cos(fi * 1.7 t), sin(fi * PHI t * 1.4));
float d = 1e20;
vec2 tp = uv - pos;
float scale = 0.07 0.03 * seed;
float rot = t * 0.9 seed * 8.0;
tp = mat2(cos(rot), -sin(rot), sin(rot), cos(rot)) * tp;
if (type < 1.0) d = sdCircle(tp, scale);
else if (type < 2.0) d = sdBox(tp, vec2(scale * 1.1, scale * 0.9));
else d = sdTriangle(tp, scale);
// Plastic: low diffuse, high sharp specular rim reflection
float shine = smoothstep(0.0, -0.008, d) * gloss * 1.8;
float plasticSpec = pow(max(0.0, dot(normalize(vec3(-dFdx(d), -dFdy(d), 1.0)), lightDir)), 128.0) * 2.5;
vec3 plasticCol = baseCol * 0.15 baseCol * shine vec3(0.9, 0.95, 1.0) * plasticSpec * 1.2;
col = mix(col, plasticCol, shine * 1.0);
float rim = glow(d, 60.0) * 1.4;
col = baseCol * rim * (0.8 plasticSpec * 0.5);
}
// Subtle vignette (no strong glow)
float vig = 1.0 - length(uv) * 0.8;
col *= vig * 0.95 0.05;
imageStore(hdrImage, pix, vec4(col, 1.0));
}