diff --git a/README.md b/README.md index b8de459..3847cd8 100644 --- a/README.md +++ b/README.md @@ -237,10 +237,8 @@ If `SLANG_ROOT` is not set, the workflow falls back to the repo-local default un - Add WebView2 - move to MSDF, typography rasterisation - better shader search UI -- LUT applicator - More comprehensive greenscreen shader -- 16bit float render target, linear compositing? -- add 10bit output path decklink +- linear compositing? - compute shaders or a small 1x1 or nx1 RGBA16f render target for abritary data store - allow shaders to read other shaders data store based on name? or putput over OSC - Mipmappong needed? diff --git a/shaders/balatro-swirl/shader.slang b/shaders/balatro-swirl/shader.slang index b99cbfd..340ff1d 100644 --- a/shaders/balatro-swirl/shader.slang +++ b/shaders/balatro-swirl/shader.slang @@ -1,21 +1,22 @@ -float4 balatroSwirl(float2 screenSize, float2 screenCoords, float time) +float4 balatroSwirl(float2 screenSize, float2 screenCoords, float time, float seed) { const float pi = 3.14159265359; float safeScreenLength = max(length(screenSize), 1.0); - float2 uv = (screenCoords - 0.5 * screenSize) / safeScreenLength - offset; + float2 seedOffset = float2(sin(seed * 6.2831853), cos(seed * 6.2831853)) * 0.035; + float2 uv = (screenCoords - 0.5 * screenSize) / safeScreenLength - offset - seedOffset; float uvLength = length(uv); float speed = spinRotation * spinEase * 0.2; if (isRotate) speed = time * speed; - speed += 302.2; + speed += 302.2 + seed * 6.2831853; float newPixelAngle = atan2(uv.y, uv.x) + speed - spinEase * 20.0 * (spinAmount * uvLength + (1.0 - spinAmount)); float2 mid = (screenSize / safeScreenLength) * 0.5; uv = float2(uvLength * cos(newPixelAngle) + mid.x, uvLength * sin(newPixelAngle) + mid.y) - mid; uv *= 30.0; - speed = time * spinSpeed; + speed = (time + seed * 17.0) * spinSpeed; float2 uv2 = float2(uv.x + uv.y, uv.x + uv.y); for (int i = 0; i < 5; ++i) @@ -42,6 +43,6 @@ float4 balatroSwirl(float2 screenSize, float2 screenCoords, float time) float4 shadeVideo(ShaderContext context) { float2 screenSize = max(context.outputResolution, float2(1.0, 1.0)); - float4 swirl = balatroSwirl(screenSize, context.uv * screenSize, context.time); + float4 swirl = balatroSwirl(screenSize, context.uv * screenSize, context.time, context.startupRandom); return saturate(lerp(swirl, context.sourceColor, sourceMix)); } diff --git a/shaders/data-mosh/shader.slang b/shaders/data-mosh/shader.slang index c56bc3a..58eb967 100644 --- a/shaders/data-mosh/shader.slang +++ b/shaders/data-mosh/shader.slang @@ -7,12 +7,14 @@ float4 shadeVideo(ShaderContext context) { float2 blocks = max(blockCount, float2(1.0, 1.0)); float2 blockId = floor(context.uv * blocks); - float n = hash21(blockId + floor(context.time * 8.0)); + float seed = context.startupRandom * 4096.0; + float frameSeed = floor(context.time * 8.0); + float n = hash21(blockId + float2(frameSeed + seed, frameSeed + seed * 0.17)); float historyFrame = floor(lerp(1.0, 7.0, n)); - float rowNoise = hash21(float2(floor(context.uv.y * blocks.y), floor(context.time * 5.0))); + float rowNoise = hash21(float2(floor(context.uv.y * blocks.y) + seed * 0.37, floor(context.time * 5.0) + seed * 0.13)); float tear = (rowNoise * 2.0 - 1.0) * tearAmount * amount * 0.08; - float2 offset = float2(tear, (hash21(blockId + 19.0) * 2.0 - 1.0) * amount * 0.025); + float2 offset = float2(tear, (hash21(blockId + float2(19.0 + seed, 19.0 + seed * 0.31)) * 2.0 - 1.0) * amount * 0.025); float2 moshedUv = clamp(context.uv + offset, 0.0, 1.0); float4 previous = sampleTemporalHistory(int(historyFrame), moshedUv); diff --git a/shaders/dvd-bounce/shader.slang b/shaders/dvd-bounce/shader.slang index f2e87b7..e53ac54 100644 --- a/shaders/dvd-bounce/shader.slang +++ b/shaders/dvd-bounce/shader.slang @@ -29,7 +29,8 @@ float4 shadeVideo(ShaderContext context) float2 velocityPx = float2( max(20.0, bounceSpeed * minDimension * 1.00), max(24.0, bounceSpeed * minDimension * 0.77)); - float2 motionPx = context.time * velocityPx; + float seed = context.startupRandom; + float2 motionPx = (float2(context.time, context.time) + float2(seed * 32.7, seed * 40.3)) * velocityPx; float2 centerPx = minCenterPx + float2( pingPong(motionPx.x, travelPx.x), pingPong(motionPx.y, travelPx.y)); @@ -38,7 +39,7 @@ float4 shadeVideo(ShaderContext context) int yHits = int(floor(motionPx.y / max(travelPx.y, 1.0))); int totalHits = max(0, xHits + yHits); - float hue = frac(0.09 + float(totalHits) * 0.173); + float hue = frac(0.09 + seed * 0.71 + float(totalHits) * 0.173); float3 badgeColor = hsvToRgb(float3(hue, 0.86, 1.0)); float3 glowColor = hsvToRgb(float3(frac(hue + 0.06), 0.72, 1.0)); diff --git a/shaders/ether/shader.slang b/shaders/ether/shader.slang index 0a94ccd..aac4ed0 100644 --- a/shaders/ether/shader.slang +++ b/shaders/ether/shader.slang @@ -20,14 +20,15 @@ float4 shadeVideo(ShaderContext context) float2 resolution = max(context.outputResolution, float2(1.0, 1.0)); float2 fragCoord = context.uv * resolution; float2 p = fragCoord / resolution.y - offset; - float time = context.time * speed; + float seed = context.startupRandom; + float time = context.time * speed + seed * 41.0; float3 color = float3(0.0, 0.0, 0.0); float d = depth; for (int i = 0; i <= 5; ++i) { - float3 rayPosition = float3(0.0, 0.0, 5.0) + normalize(float3(p, -1.0)) * d; + float3 rayPosition = float3(seed * 0.7 - 0.35, 0.23 - seed * 0.46, 5.0) + normalize(float3(p, -1.0)) * d; float rz = etherMap(rayPosition, time); float f = clamp((rz - etherMap(rayPosition + float3(0.1, 0.1, 0.1), time)) * 0.5, -0.1, 1.0); float3 light = baseColor.rgb + energyColor.rgb * 5.0 * f; diff --git a/shaders/happy-accident/shader.slang b/shaders/happy-accident/shader.slang index 02ee7d8..55555bc 100644 --- a/shaders/happy-accident/shader.slang +++ b/shaders/happy-accident/shader.slang @@ -24,12 +24,13 @@ float4 shadeVideo(ShaderContext context) float2 resolution = max(context.outputResolution, float2(1.0, 1.0)); float2 fragCoord = context.uv * resolution; float2 normalizedCoord = (fragCoord - 0.5 * resolution) / resolution.y / max(scale, 0.001); - float time = context.time * speed; + float seed = context.startupRandom; + float time = context.time * speed + seed * 53.0; float timeCos = cos(0.1 * time); float3 direction = normalize(float3(normalizedCoord, 1.0)); - float3 origin = float3(0.0, 0.0, time); + float3 origin = float3(seed * 0.4 - 0.2, 0.2 - seed * 0.4, time); - float z = happyNoise(fragCoord); + float z = happyNoise(fragCoord + seed * resolution.yx); float distanceToSurface = 0.0; float4 accumulated = float4(0.0, 0.0, 0.0, 0.0); float clampedSteps = clamp(raySteps, 1.0, 77.0); diff --git a/shaders/singularity/shader.slang b/shaders/singularity/shader.slang index b747ac8..d77dad1 100644 --- a/shaders/singularity/shader.slang +++ b/shaders/singularity/shader.slang @@ -14,13 +14,14 @@ float4 shadeVideo(ShaderContext context) float safeScale = max(scale, 0.001); float safeRingRadius = max(ringRadius, 0.001); float safeTightness = max(tightness, 0.001); - float time = context.time * speed; + float seed = context.startupRandom; + float time = context.time * speed + seed * 37.0; float2 p = (fragCoord + fragCoord - resolution) / resolution.y / safeScale; - p -= center; + p -= center + float2(sin(seed * 6.2831853), cos(seed * 6.2831853)) * 0.035; float iterator = 0.2; - float2 diagonal = float2(-1.0, 1.0); + float2 diagonal = normalize(float2(-1.0 + seed * 0.5, 1.0 - seed * 0.35)); float2 blackholeCenter = p - iterator * diagonal; float gravity = iterator * strength / max(dot(blackholeCenter, blackholeCenter), 0.0001); float2 skew = diagonal / (0.1 + gravity); diff --git a/shaders/vhs/shader.slang b/shaders/vhs/shader.slang index 1c501a9..9334eca 100644 --- a/shaders/vhs/shader.slang +++ b/shaders/vhs/shader.slang @@ -161,15 +161,16 @@ float3 blurVhs(float2 uv, float d, int sampleCount) float4 shadeVideo(ShaderContext context) { float2 uv = context.uv; - float framecount = frac(context.time * wiggleSpeed / 7.0) * 7.0; + float time = context.time + context.startupRandom * 113.0; + float framecount = frac(time * wiggleSpeed / 7.0) * 7.0; int sampleCount = int(clamp(blurSamples, 3.0, 15.0) + 0.5); - float d = 0.1 - round(frac(context.time / 3.0)) * 0.1; + float d = 0.1 - round(frac(time / 3.0)) * 0.1; uv = jumpy(uv, framecount); - float s = 0.0001 * -d + 0.0001 * wiggle * sin(context.time * wiggleSpeed); + float s = 0.0001 * -d + 0.0001 * wiggle * sin(time * wiggleSpeed); float e = min(0.30, pow(max(0.0, cos(uv.y * 4.0 + 0.3) - 0.75) * (s + 0.5), 3.0)) * 25.0; float r = 250.0 * (2.0 * s); - uv.x += abs(r * pow(min(0.003, (-uv.y + (0.01 * frac(context.time / 5.0) * 5.0))) * 3.0, 2.0)) * wiggle; + uv.x += abs(r * pow(min(0.003, (-uv.y + (0.01 * frac(time / 5.0) * 5.0))) * 3.0, 2.0)) * wiggle; d = 0.051 + abs(sin(s / 4.0)); float c = max(0.0001, 0.002 * d) * smear; @@ -212,7 +213,7 @@ float4 shadeVideo(ShaderContext context) color = lerp(color, bloomSource, bloomAmount * 0.18); color += bloomSource * float3(1.0, 0.96, 0.92) * bloomMask * 0.24; - float3 speckle = animatedChromaGrain(context.uv, context.time, context.outputResolution, noiseSize); + float3 speckle = animatedChromaGrain(context.uv, time, context.outputResolution, noiseSize); float luma = dot(color, float3(0.299, 0.587, 0.114)); float noiseMask = lerp(0.65, 1.0, 1.0 - saturate(luma)); float chunkiness = lerp(1.0, 2.4, saturate((noiseSize - 1.0) / 5.0)); @@ -221,7 +222,7 @@ float4 shadeVideo(ShaderContext context) color.rg = lerp(color.rg, float2(color.r, color.g) + speckle.xy * noiseAmount * 0.2 * chunkiness, 0.35); color.b = lerp(color.b, color.b + speckle.z * noiseAmount * 0.28 * chunkiness, 0.5); - float3 staticNoise = analogStatic(context.uv, context.time, context.outputResolution); + float3 staticNoise = analogStatic(context.uv, time, context.outputResolution); float staticMask = lerp(0.45, 1.15, 1.0 - saturate(luma)); color += staticNoise * staticAmount * staticMask; color = lerp(color, color + float3(staticNoise.r * 0.22, staticNoise.g * 0.08, -staticNoise.b * 0.08), saturate(staticAmount * 2.0)); diff --git a/shaders/video-cube/shader.json b/shaders/video-cube/shader.json index 7a1b912..e544642 100644 --- a/shaders/video-cube/shader.json +++ b/shaders/video-cube/shader.json @@ -36,7 +36,7 @@ "id": "backgroundMix", "label": "Background Mix", "type": "float", - "default": 0.15, + "default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01 diff --git a/shaders/video-cube/shader.slang b/shaders/video-cube/shader.slang index 17e82b1..6c35111 100644 --- a/shaders/video-cube/shader.slang +++ b/shaders/video-cube/shader.slang @@ -75,7 +75,7 @@ float4 shadeVideo(ShaderContext context) float3 rayOrigin = float3(0.0, 0.0, 2.7); float3 rayDirection = normalize(float3(centeredUv, -2.1)); - float spin = context.time * spinSpeed; + float spin = context.time * spinSpeed + context.startupRandom * 6.2831853; float yaw = spin; float pitch = spin * 0.61 + 0.35;