experimental backend WebGL2 · not opted in
Enable WebGPU controls in settings. WebGL2 remains unchanged. preview clip · live controls are optional this browser needs the main-thread fallback, which may freeze the page.
20.00
0.03
0.55
0.58
0.46
0.25
0.47
0.42
0.51
0.20
0.86
0.22
1.27
0.63
1.33
1.25
0.55
0.24
rgb
rgb
0.46
1.31
1.35
2.80
/*{ "DESCRIPTION": "Sun-baked playa: warped mineral plates, deep irregular gaps, and sparse hairline fractures.", "CREDIT": "depatchedmode", "CATEGORIES": ["Generator", "Texture"], "INPUTS": [ { "NAME": "plateScale", "TYPE": "float", "DEFAULT": 20.0, "MIN": 3.0, "MAX": 20.0 }, { "NAME": "gapWidth", "TYPE": "float", "DEFAULT": 0.025, "MIN": 0.025, "MAX": 0.14 }, { "NAME": "gapVariance", "TYPE": "float", "DEFAULT": 0.55, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "gapDebris", "TYPE": "float", "DEFAULT": 0.58, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "fragmentAmount", "TYPE": "float", "DEFAULT": 0.46, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "hairlineAmount", "TYPE": "float", "DEFAULT": 0.25, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "relief", "TYPE": "float", "DEFAULT": 0.47, "MIN": 0.0, "MAX": 1.4 }, { "NAME": "curlCoverage", "TYPE": "float", "DEFAULT": 0.42, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "curlWidthVariance", "TYPE": "float", "DEFAULT": 0.51, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "cupping", "TYPE": "float", "DEFAULT": 0.2, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "cuppingIrregularity", "TYPE": "float", "DEFAULT": 0.86, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "heightVariance", "TYPE": "float", "DEFAULT": 0.22, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "lightAngle", "TYPE": "float", "DEFAULT": 1.27, "MIN": 0.0, "MAX": 6.283 }, { "NAME": "lightElevation", "TYPE": "float", "DEFAULT": 0.63, "MIN": 0.1, "MAX": 1.5 }, { "NAME": "sunStrength", "TYPE": "float", "DEFAULT": 1.33, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "moonStrength", "TYPE": "float", "DEFAULT": 1.25, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "warmth", "TYPE": "float", "DEFAULT": 0.55, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "mineralVariation", "TYPE": "float", "DEFAULT": 0.24, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "clayColor", "TYPE": "color", "DEFAULT": [0.72, 0.70, 0.64, 1.0] }, { "NAME": "crackColor", "TYPE": "color", "DEFAULT": [0.404, 0.380, 0.337, 1.0] }, { "NAME": "crackSpeed", "TYPE": "float", "DEFAULT": 0.46, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "hairlineSpeed", "TYPE": "float", "DEFAULT": 1.31, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "edgeSpeed", "TYPE": "float", "DEFAULT": 1.35, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "seed", "TYPE": "float", "DEFAULT": 2.8, "MIN": 0.0, "MAX": 20.0 } ] }*/ precision highp float; // The browser preview supplies these from its location-aware celestial clock. // They default to manual daylight when opened in an ISF host without that clock. uniform float celestialLighting; uniform vec3 celestialSunDirection; uniform vec3 celestialMoonDirection; uniform vec3 celestialSunColor; uniform vec3 celestialMoonColor; uniform vec3 celestialAmbient; uniform float celestialSunIntensity; uniform float celestialMoonIntensity; float hash11(float p) { p = fract(p * 0.1031); p *= p + 33.33; return fract(p * (p + p)); } vec2 hash22(vec2 p) { vec3 q = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973)); q += dot(q, q.yzx + 33.33); return fract((q.xx + q.yz) * q.zy); } float valueNoise(vec2 p) { vec2 cell = floor(p); vec2 local = fract(p); local = local * local * (3.0 - 2.0 * local); float a = hash11(dot(cell, vec2(127.1, 311.7))); float b = hash11(dot(cell + vec2(1.0, 0.0), vec2(127.1, 311.7))); float c = hash11(dot(cell + vec2(0.0, 1.0), vec2(127.1, 311.7))); float d = hash11(dot(cell + vec2(1.0), vec2(127.1, 311.7))); return mix(mix(a, b, local.x), mix(c, d, local.x), local.y); } float fbm(vec2 p) { float sum = 0.0; float weight = 0.5; mat2 turn = mat2(0.80, -0.60, 0.60, 0.80); for (int octave = 0; octave < 4; octave++) { sum += weight * valueNoise(p); p = turn * p * 2.03 + 9.17; weight *= 0.5; } return sum; } vec2 featurePoint(vec2 cellId, vec2 motionPhase, float motionRadius) { vec2 center = 0.14 + 0.72 * hash22(cellId + seed); vec2 axisX = hash22(cellId + seed + vec2(19.17, 73.11)) - 0.5; vec2 axisY = vec2(-axisX.y, axisX.x); return center + (axisX * motionPhase.x + axisY * motionPhase.y) * motionRadius; } vec4 plateMaterialVariation(float plateKey) { if (mineralVariation <= 0.001) { return vec4(0.0); } vec2 primary = hash22(vec2( plateKey * 137.2 + seed * 1.7, plateKey * 61.8 - seed * 2.3 )); vec2 secondary = hash22(primary * 83.1 + vec2(plateKey, seed)); return (vec4(primary, secondary) - 0.5) * mineralVariation; } // Captures the closest edge direction during the existing boundary search for the cupping profile. vec4 voronoiPlate( vec2 p, vec2 motionPhase, float motionRadius, out float plateKey, out vec2 edgeDirection, out float edgeKey, out float cornerness ) { vec2 cell = floor(p); vec2 local = fract(p); vec2 nearestOffset = vec2(0.0); vec2 nearestCell = vec2(0.0); float nearestDistance = 8.0; for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { vec2 neighbor = vec2(float(x), float(y)); vec2 feature = featurePoint(cell + neighbor, motionPhase, motionRadius); vec2 offset = neighbor + feature - local; float distanceSquared = dot(offset, offset); if (distanceSquared < nearestDistance) { nearestDistance = distanceSquared; nearestOffset = offset; nearestCell = neighbor; } } } float borderDistance = 8.0; float secondBorderDistance = 8.0; vec2 edgeNeighbor = nearestCell; edgeDirection = vec2(0.0); vec2 secondEdgeDirection = vec2(0.0); for (int y = -2; y <= 2; y++) { for (int x = -2; x <= 2; x++) { vec2 neighbor = nearestCell + vec2(float(x), float(y)); vec2 feature = featurePoint(cell + neighbor, motionPhase, motionRadius); vec2 offset = neighbor + feature - local; vec2 delta = offset - nearestOffset; if (dot(delta, delta) > 0.0001) { vec2 candidateDirection = normalize(delta); float candidateDistance = dot(0.5 * (nearestOffset + offset), candidateDirection); if (candidateDistance < borderDistance) { secondBorderDistance = borderDistance; secondEdgeDirection = edgeDirection; borderDistance = candidateDistance; edgeDirection = candidateDirection; edgeNeighbor = neighbor; } else if (candidateDistance < secondBorderDistance) { secondBorderDistance = candidateDistance; secondEdgeDirection = candidateDirection; } } } } vec2 plateId = cell + nearestCell; vec2 opposingPlateId = cell + edgeNeighbor; vec2 edgeIdSum = plateId + opposingPlateId; vec2 edgeIdDifference = abs(plateId - opposingPlateId); plateKey = hash11(dot(plateId, vec2(57.2, 113.7)) + seed * 3.1); edgeKey = hash11( dot(edgeIdSum, vec2(23.17, 47.13)) + dot(edgeIdDifference, vec2(91.7, 13.9)) + seed * 5.1 ); float boundarySeparation = max(secondBorderDistance - borderDistance, 0.0); cornerness = 1.0 - smoothstep(0.025, 0.18, boundarySeparation); vec2 blendedEdgeDirection = mix(edgeDirection, secondEdgeDirection, cornerness * 0.5); float blendedLengthSquared = max(dot(blendedEdgeDirection, blendedEdgeDirection), 0.0001); edgeDirection = blendedEdgeDirection * inversesqrt(blendedLengthSquared); float centerDistance = sqrt(max(nearestDistance, 0.0001)); vec2 centerDirection = nearestOffset / centerDistance; return vec4(borderDistance, centerDistance, centerDirection); } vec3 organicCupProfile( vec4 plate, float plateKey, vec2 plateVariation ) { float irregularity = cuppingIrregularity; if (irregularity <= 0.001) { return vec3(plate.zw, smoothstep(0.04, 0.52, plate.y)); } vec2 shiftedCenter = plate.zw * plate.y + plateVariation * irregularity * 0.28; float shiftedDistance = max(length(shiftedCenter), 0.0001); vec2 radialDirection = shiftedCenter / shiftedDistance; float profileScale = mix(1.0, 0.72 + plateKey * 0.56, irregularity); float slope = smoothstep(0.04 * profileScale, 0.52 * profileScale, shiftedDistance); float directionalBias = dot(radialDirection, normalize(plateVariation + vec2(0.0001, 0.0))); slope *= 1.0 + directionalBias * irregularity * 0.22; slope *= mix(1.0, 0.65 + plateKey * 0.75, irregularity); return vec3(radialDirection, slope); } vec3 edgeCurl( vec2 p, float border, float localGap, float pixelWidth, vec2 edgeDirection, float edgeKey, float cornerness ) { if (relief <= 0.001 || curlCoverage <= 0.001) { return vec3(0.0); } vec2 noiseOffset = vec2(edgeKey * 17.3, edgeKey * -11.7) + seed; vec2 edgeTangent = vec2(-edgeDirection.y, edgeDirection.x); float dominantDirection = abs(edgeTangent.x) > abs(edgeTangent.y) ? edgeTangent.x : edgeTangent.y; edgeTangent *= sign(dominantDirection); float curlTravel = TIME * edgeSpeed * 0.035; float placementNoise = valueNoise(p * 1.45 + noiseOffset + edgeTangent * curlTravel); float curlPatch = smoothstep(0.70, 0.80, placementNoise); float edgeGate = smoothstep( 1.0 - curlCoverage, 1.10 - curlCoverage, edgeKey ); float widthSeed = fract(edgeKey * 7.618 + 0.37); float variedWidth = mix(0.065, 0.24, widthSeed); float curlWidth = mix(0.13, variedWidth, curlWidthVariance); float surfaceEdgeDistance = max(border - localGap, 0.0); float curlStart = min(pixelWidth * 1.5, curlWidth * 0.5); float curlSlope = 1.0 - smoothstep(curlStart, curlWidth, surfaceEdgeDistance); float cornerFade = 1.0 - smoothstep(0.20, 0.88, cornerness); float curlMask = edgeGate * curlPatch * cornerFade; float curlOcclusion = curlMask * (1.0 - smoothstep(localGap, localGap + curlWidth * 0.48, border)); return vec3(edgeDirection * curlSlope * curlMask * relief * 0.72, curlOcclusion); } float fineFractures(vec2 p, float macroBorder, vec2 motionPhase) { vec2 fineP = p * 2.65 + vec2(17.3, -9.1); vec2 cell = floor(fineP); vec2 local = fract(fineP); vec2 closestCell = vec2(0.0); float nearestDistance = 8.0; float secondDistance = 8.0; for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { vec2 neighbor = vec2(float(x), float(y)); vec2 feature = featurePoint(cell + neighbor, motionPhase, 0.18); vec2 offset = neighbor + feature - local; float distanceSquared = dot(offset, offset); if (distanceSquared < nearestDistance) { secondDistance = nearestDistance; nearestDistance = distanceSquared; closestCell = neighbor; } else if (distanceSquared < secondDistance) { secondDistance = distanceSquared; } } } float borderDistance = 0.5 * (sqrt(secondDistance) - sqrt(nearestDistance)); float cellKey = hash11(dot(cell + closestCell, vec2(41.7, 89.2)) + seed * 7.0); float brokenNetwork = smoothstep(0.40, 0.78, cellKey + 0.22 * valueNoise(fineP * 0.55)); float hairline = 1.0 - smoothstep(0.010, 0.030, borderDistance); float awayFromGaps = smoothstep(gapWidth * 1.9, gapWidth * 3.4, macroBorder); return hairline * brokenNetwork * awayFromGaps * hairlineAmount; } vec3 crumblyGapFloor( vec2 p, float border, float localGap, vec2 lightPlanar, vec3 gapColor, vec3 clay ) { if (gapDebris <= 0.001 && fragmentAmount <= 0.001) { return gapColor; } float floorPosition = clamp(border / max(localGap, 0.0001), 0.0, 1.0); float wideGap = smoothstep(0.82, 1.28, localGap / max(gapWidth, 0.0001)); float coarseGrain = valueNoise(p * 19.0 + seed * 8.7); float fineGrain = valueNoise(p * 57.0 + vec2(seed * 3.1, -seed * 4.7)); float grain = mix(coarseGrain, fineGrain, 0.38) - 0.5; float wallShadow = smoothstep(0.58, 1.0, floorPosition); float floorPlacement = 1.0 - smoothstep(0.72, 0.98, floorPosition); float debrisStrength = gapDebris * mix(0.42, 1.0, wideGap); gapColor *= 1.0 + grain * debrisStrength * 0.42; gapColor *= 1.0 - wallShadow * debrisStrength * 0.36; float debrisThreshold = mix(0.94, 0.69, gapDebris); float debrisField = fineGrain + (coarseGrain - 0.5) * 0.18; float debrisMask = smoothstep(debrisThreshold, debrisThreshold + 0.055, debrisField); debrisMask *= floorPlacement * debrisStrength; vec3 debrisColor = mix(gapColor, clay, 0.32 + coarseGrain * 0.16); gapColor = mix(gapColor, debrisColor, debrisMask * 0.76); if (fragmentAmount <= 0.001) { return gapColor; } vec2 fragmentOffset = vec2(seed * 5.3, -seed * 2.9); float fragmentField = valueNoise(p * 34.0 + fragmentOffset) + grain * 0.16; float fragmentThreshold = mix(0.94, 0.70, fragmentAmount); float fragmentShape = smoothstep(fragmentThreshold, fragmentThreshold + 0.055, fragmentField); float fragmentOpacity = fragmentAmount * mix(0.28, 1.0, wideGap); float fragments = fragmentShape * floorPlacement * fragmentOpacity; float planarLength = max(length(lightPlanar), 0.0001); vec2 shadowOffset = lightPlanar / planarLength * 0.018; float shadowField = valueNoise((p + shadowOffset) * 34.0 + fragmentOffset) + grain * 0.16; float shiftedShape = smoothstep(fragmentThreshold, fragmentThreshold + 0.055, shadowField); float fragmentShadow = max(shiftedShape - fragmentShape, 0.0); fragmentShadow *= floorPlacement * fragmentOpacity; gapColor *= 1.0 - fragmentShadow * 0.58; vec3 fragmentColor = clay * mix(0.62, 0.88, fineGrain); return mix(gapColor, fragmentColor, fragments * 0.88); } void main() { vec2 uv = isf_FragNormCoord; vec2 p = (uv - 0.5) * vec2(RENDERSIZE.x / RENDERSIZE.y, 1.0); p *= plateScale; float broadWarp = fbm(p * 0.19 + seed); vec2 warp = vec2( valueNoise(p * 0.31 + vec2(seed, 4.2)), valueNoise(p * 0.31 + vec2(8.3, seed)) ) - 0.5; p += warp * 0.88 + vec2(broadWarp - 0.5, 0.0) * 0.42; float crackAngle = TIME * crackSpeed; vec2 crackPhase = vec2(cos(crackAngle), sin(crackAngle)); float plateRandom; vec2 edgeDirection; float edgeKey; float cornerness; vec4 plate = voronoiPlate( p, crackPhase, 0.20, plateRandom, edgeDirection, edgeKey, cornerness ); float hairlineAngle = TIME * hairlineSpeed + 1.7; vec2 hairlinePhase = vec2(cos(hairlineAngle), sin(hairlineAngle)); float edgePhase = TIME * edgeSpeed; vec2 edgeOrbit = vec2(cos(edgePhase), sin(edgePhase)); float chippedEdge = (valueNoise(p * 6.7 + edgeOrbit * 2.8 + 23.0) - 0.5) * 0.022; float border = plate.x + chippedEdge; float widthNoise = valueNoise(p * 1.45 + 31.0); float gapIrregularity = mix(1.0, 0.55 + 0.90 * widthNoise, gapVariance); float localGap = gapWidth * gapIrregularity; float pixelWidth = plateScale / max(RENDERSIZE.y, 1.0); float plateMask = smoothstep(localGap, localGap + pixelWidth * 1.7, border); float mineral = fbm(p * 1.9 + plateRandom * 19.0); float grit = valueNoise(p * 8.0 + seed * 13.0); float stains = fbm(p * 0.53 + vec2(7.0, -12.0)); vec4 plateMaterial = plateMaterialVariation(plateRandom); vec3 coolClay = clayColor.rgb * vec3(0.95, 0.98, 1.04); vec3 warmClay = clayColor.rgb * vec3(1.06, 0.98, 0.86); vec3 clay = mix(coolClay, warmClay, warmth); clay *= vec3( 1.0 + plateMaterial.x * 0.09, 1.0 + plateMaterial.x * 0.025, 1.0 - plateMaterial.x * 0.08 ); clay *= 0.955 + plateMaterial.y * 0.16; clay *= 0.86 + 0.23 * mineral; clay += vec3(0.055, 0.050, 0.038) * (grit - 0.5); if (mineralVariation > 0.001) { float poreNoise = valueNoise(p * 31.0 + plateRandom * 29.0 + seed * 5.7); float poreThreshold = 0.72 - plateMaterial.z * 0.22; float pores = smoothstep(poreThreshold, poreThreshold + 0.10, poreNoise); clay *= 1.0 - pores * mineralVariation * 0.045; } float stainShift = plateMaterial.w * 0.22; float stainMask = smoothstep(0.62 - stainShift, 0.88 - stainShift, stains); float stainStrength = 0.24 * (1.0 + plateMaterial.w * 0.55); clay = mix(clay, clay * vec3(0.73, 0.69, 0.60), stainMask * stainStrength); bool usesCelestialLighting = celestialLighting > 0.5; vec2 manualLightPlanar = vec2(cos(lightAngle), sin(lightAngle)) * cos(lightElevation); vec3 manualLightDirection = vec3(manualLightPlanar, sin(lightElevation)); vec2 lightPlanar = manualLightPlanar; if (usesCelestialLighting) { lightPlanar = celestialSunDirection.xy * celestialSunIntensity * sunStrength; lightPlanar += celestialMoonDirection.xy * celestialMoonIntensity * moonStrength; } vec2 randomTilt = hash22(vec2(plateRandom * 91.7, seed + 4.3)) - 0.5; vec3 cupProfile = organicCupProfile(plate, plateRandom, randomTilt); vec2 heightGradient = cupProfile.xy * cupping * 0.62 * cupProfile.z; heightGradient += randomTilt * heightVariance * 0.42; vec3 curlData = edgeCurl( p, border, localGap, pixelWidth, edgeDirection, edgeKey, cornerness ); heightGradient += curlData.xy; vec3 surfaceNormal = normalize(vec3(-heightGradient, 1.0)); if (!usesCelestialLighting) { float diffuse = max(dot(surfaceNormal, manualLightDirection), 0.0); clay *= 1.0 + sunStrength * (diffuse - 0.58) * 0.72; } clay *= 1.0 + (plateRandom - 0.5) * heightVariance * 0.22; clay *= 1.0 - curlData.z * relief * 0.10; float fissureNoise = fbm(p * 2.4 + 40.0); vec3 gapColor = mix(crackColor.rgb * 0.78, crackColor.rgb * 1.62, fissureNoise); gapColor *= 0.84 + 0.22 * smoothstep(0.0, localGap, border); if (plateMask < 1.0) { gapColor = crumblyGapFloor(p, border, localGap, lightPlanar, gapColor, clay); } float hairlines = fineFractures(p, border, hairlinePhase); clay = mix(clay, clay * vec3(0.43, 0.41, 0.37), hairlines * 0.72); vec3 color = mix(gapColor, clay, plateMask); if (usesCelestialLighting) { float sunDiffuse = max(dot(surfaceNormal, celestialSunDirection), 0.0); float moonDiffuse = max(dot(surfaceNormal, celestialMoonDirection), 0.0); vec3 sunlight = celestialSunColor * celestialSunIntensity * sunStrength * (0.22 + 0.78 * sunDiffuse); vec3 moonlight = celestialMoonColor * celestialMoonIntensity * moonStrength * (0.18 + 0.82 * moonDiffuse); color *= celestialAmbient + sunlight * 0.62 + moonlight * 0.55; } float dust = hash11(dot(gl_FragCoord.xy, vec2(12.9898, 78.233)) + seed * 101.0) - 0.5; color += dust * 0.018; color *= 0.93 + 0.10 * smoothstep(0.0, 1.0, uv.y); color = pow(max(color, 0.0), vec3(0.94)); gl_FragColor = vec4(color, 1.0); }
Sun-baked playa: warped mineral plates, deep irregular gaps, and sparse hairline fractures.
by depatchedmodewitnessed_generationmade with glslopCC0-1.0credit: depatchedmodeactive·created 2026-08-04 04:36Z146 views0 forks24 paramschatgpt-5.6-terra
export clip · render a video in your browser
Renders to video in your browser (no upload), stepping the real renderer frame by frame so multipass + feedback come out right. motion auto-animates the shader's own knobs — each export rolls a fresh take (🎲 re-roll, 🔒 to pin one you like). GIF is slower with a tighter length cap; MP4/WebM are faster. Some devices record in real time (noted below if so) — keep the tab visible.
caps: ≤1920 per side, ≤60fps, ≤18000 frames (GIF ≤300)
embed · drop this shader into any page
Renders client-side in the reader's browser (CC0 — no attribution required, but the backlink is appreciated).