Twitter/X

@emollick's shader (posted 2026-06-16) is a single-file GLSL fragment program…

Brief

@emollick's shader (posted 2026-06-16) is a single-file GLSL fragment program that constructs a rainy, lightning-lit nightscape by raymarching SDFs. A cinematic camera (ro: x = sin(time0.08)25, y ≈ 55 + sin(time0.2)8, z = time5 + 40) sweeps over a procedurally tiled gothic city (cellSize = 18.0) whose towers use octagonal SDFs, tapered profiles and cone spires (main heights 35.0 + rnd270.0). The ocean sits at oceanBase = -1.5 with layered Gerstner-like waves plus fbm; foam, volumetric height fog and four parallax rain layers add atmosphere. Lightning is probabilistic (flash when hash(floor(time*1.5)) > 0.92) with explicit bolt sampling (8 iterations), chromatic aberration (ca = 0.003) and per-channel raymarch refinement, then ACES tonemapping (a=2.51,b=0.03,c=2.43,d=0.59,e=0.14), vignette and film grain finalize the look.

Cleaned source text

precision highp float;

uniform vec2 resolution;

uniform float time;

// --- Hash & Noise Functions

float hash(vec2 p) {

p = fract(p * vec2(123.34, 456.21));

p += dot(p, p + 45.32);

return fract(p.x * p.y);

float noise(vec2 p) {

vec2 i = floor(p);

vec2 f = fract(p);

f = f * f * (3.0 - 2.0 * f);

return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),

mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x), f.y);

float fbm(vec2 p) {

float v = 0.0;

float a = 0.5;

mat2 m = mat2(1.6, 1.2, -1.2, 1.6);

for(int i = 0; i < 5; i++) {

v += a * noise(p);

p = m * p;

a *= 0.5;

return v;

// --- SDFs

float sdOctagon(vec2 p, float r) {

p = abs(p);

float d = max(p.x, p.y) - r;

d = max(d, dot(p, vec2(0.70710678)) - r * 1.12);

return d;

float sdCone(vec3 p, vec2 dim) {

vec2 q = vec2(length(p.xz), p.y);

return max(dot(q, vec2(dim.y, -dim.x)), -q.y - dim.x);

// --- Ocean (Gerstner-inspired waves)

float waveHeight(vec2 p) {

float t = time * 1.5;

float h = 0.0;

h += sin(p.x * 0.15 + t) * 3.0;

h += sin(p.y * 0.25 - t * 1.3) * 2.0;

h += sin((p.x + p.y) * 0.3 + t * 1.7) * 1.5;

h += fbm(p * 0.4 + vec2(t * 0.2, -t * 0.3)) * 5.0;

return h;

// --- Scene Map

vec2 map(vec3 p) {

float oceanBase = -1.5;

float ocean = p.y - (oceanBase + waveHeight(p.xz));

float city = 1000.0;

float cellSize = 18.0;

vec2 id = floor(p.xz / cellSize);

vec2 q = mod(p.xz, cellSize) - cellSize * 0.5;

float rnd = hash(id);

float rnd2 = hash(id + 1.0);

if (rnd > 0.15) {

float w = 2.5 + rnd * 1.5;

float h = 35.0 + rnd2 * 70.0;

float baseY = -25.0;

// Tapered Main Body

float taperY = clamp((p.y - baseY) / max(0.1, h - baseY), 0.0, 1.0);

float taper = mix(1.3, 0.5, taperY);

float dOct = sdOctagon(q / taper, w) * taper;

// Gothic Vertical Ribs

float angle = atan(q.x, q.y);

float ribs = cos(angle * 8.0) * 0.15;

dOct += ribs * smoothstep(h, h - 15.0, p.y) * smoothstep(baseY, baseY + 10.0, p.y);

float body = max(dOct, max(p.y - h, baseY - p.y));

city = min(city, body);

// Central Spire

if (p.y > h - 2.0) {

float spireH = 20.0 + rnd2 * 15.0;

float spire = sdCone(vec3(q.x, p.y - h, q.y), vec2(w * 0.8, spireH));

city = min(city, spire);

// Corner Spires (Buttresses)

vec2 cornerOffset = vec2(w + 1.5);

for(int i = 0; i < 4; i++) {

vec2 c = cornerOffset;

if(i == 1) c.x = -c.x;

if(i == 2) c.y = -c.y;

if(i == 3) c = -c;

vec2 cq = q - c;

float c_h = h * 0.75 + rnd2 * 10.0;

float c_taperY = clamp((p.y - baseY) / max(0.1, c_h - baseY), 0.0, 1.0);