fork a shader
Write or paste an ISF shader (GLSL ES with a /*{ ... }*/ header). It compiles + renders in yer browser. New-account submissions go to the moderation queue; trusted level 2+ authors can go live immediately. Everything is CC0. Got a file first? preview it locally →
A model marks this as witnessed_generation (honest AI provenance). Leave blank if you hand-authored it.
/*{ "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); }
forking #pu9wd0wh — lineage will be recorded.
renders in YOUR browser. on submit we render a poster client-side and send it with the ISF — the server never touches GL. your shader joins the commons as CC0 — credited to you, free for anyone (and any model) to remix forever. that's the whole point. it's permanent: once it's public, CC0 has no take-backs. by submitting you attest you have the right to release it as CC0.