From ad24a20fdb4a6a4cc0f314ed64a81ec717006cc0 Mon Sep 17 00:00:00 2001 From: Aiden Date: Fri, 8 May 2026 17:40:09 +1000 Subject: [PATCH] Multi pass test --- shaders/gaussian-blur/shader.json | 18 +++++++++++- shaders/gaussian-blur/shader.slang | 42 +++++++++++++++++----------- shaders/multipass-test/shader.json | 43 +++++++++++++++++++++++++++++ shaders/multipass-test/shader.slang | 38 +++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 shaders/multipass-test/shader.json create mode 100644 shaders/multipass-test/shader.slang diff --git a/shaders/gaussian-blur/shader.json b/shaders/gaussian-blur/shader.json index 3dc9a25..ab89db1 100644 --- a/shaders/gaussian-blur/shader.json +++ b/shaders/gaussian-blur/shader.json @@ -1,9 +1,25 @@ { "id": "gaussian-blur", "name": "Gaussian Blur", - "description": "Applies a simple Gaussian-style blur to the decoded video input.", + "description": "Applies a separable two-pass Gaussian-style blur to the decoded video input.", "category": "Transform", "entryPoint": "shadeVideo", + "passes": [ + { + "id": "horizontal", + "source": "shader.slang", + "entryPoint": "blurHorizontal", + "inputs": ["layerInput"], + "output": "blurHorizontal" + }, + { + "id": "vertical", + "source": "shader.slang", + "entryPoint": "blurVertical", + "inputs": ["blurHorizontal"], + "output": "layerOutput" + } + ], "parameters": [ { "id": "radius", diff --git a/shaders/gaussian-blur/shader.slang b/shaders/gaussian-blur/shader.slang index 606b176..dbefbd0 100644 --- a/shaders/gaussian-blur/shader.slang +++ b/shaders/gaussian-blur/shader.slang @@ -1,25 +1,22 @@ -float4 shadeVideo(ShaderContext context) +float4 gaussianBlurDirection(ShaderContext context, float2 direction) { float2 texel = 1.0 / max(context.inputResolution, float2(1.0, 1.0)); - float blurRadius = max(radius, 0.0); - float2 sampleStep = texel * blurRadius; + float blurRadius = max(radius, 0.0) * saturate(strength); + float2 sampleStep = texel * blurRadius * direction; int sampleRadius = int(clamp(samples, 0.0, 8.0) + 0.5); float4 center = sampleVideo(context.uv); float4 blur = float4(0.0, 0.0, 0.0, 0.0); float totalWeight = 0.0; - for (int y = -sampleRadius; y <= sampleRadius; ++y) + for (int x = -sampleRadius; x <= sampleRadius; ++x) { - for (int x = -sampleRadius; x <= sampleRadius; ++x) - { - float distanceSquared = float(x * x + y * y); - float sigma = max(float(sampleRadius) * 0.5, 0.5); - float weight = exp(-distanceSquared / (2.0 * sigma * sigma)); - float2 offset = float2(float(x), float(y)) * sampleStep; - blur += sampleVideo(context.uv + offset) * weight; - totalWeight += weight; - } + float distanceSquared = float(x * x); + float sigma = max(float(sampleRadius) * 0.5, 0.5); + float weight = exp(-distanceSquared / (2.0 * sigma * sigma)); + float2 offset = float(x) * sampleStep; + blur += sampleVideo(context.uv + offset) * weight; + totalWeight += weight; } if (sampleRadius == 0) @@ -29,7 +26,20 @@ float4 shadeVideo(ShaderContext context) } blur /= max(totalWeight, 0.0001); - - float mixValue = saturate(strength); - return lerp(center, blur, mixValue); + return blur; +} + +float4 blurHorizontal(ShaderContext context) +{ + return gaussianBlurDirection(context, float2(1.0, 0.0)); +} + +float4 blurVertical(ShaderContext context) +{ + return gaussianBlurDirection(context, float2(0.0, 1.0)); +} + +float4 shadeVideo(ShaderContext context) +{ + return blurVertical(context); } diff --git a/shaders/multipass-test/shader.json b/shaders/multipass-test/shader.json new file mode 100644 index 0000000..c376fa2 --- /dev/null +++ b/shaders/multipass-test/shader.json @@ -0,0 +1,43 @@ +{ + "id": "multipass-test", + "name": "Multipass Test", + "description": "Diagnostic two-pass shader that generates a mask in pass one, then samples that named intermediate in pass two.", + "category": "Utility", + "entryPoint": "shadeVideo", + "passes": [ + { + "id": "mask", + "source": "shader.slang", + "entryPoint": "buildMask", + "inputs": ["layerInput"], + "output": "generatedMask" + }, + { + "id": "final", + "source": "shader.slang", + "entryPoint": "applyMask", + "inputs": ["generatedMask"], + "output": "layerOutput" + } + ], + "parameters": [ + { + "id": "intensity", + "label": "Intensity", + "type": "float", + "default": 1.0, + "min": 0.0, + "max": 1.0, + "step": 0.01 + }, + { + "id": "scale", + "label": "Scale", + "type": "float", + "default": 10.0, + "min": 2.0, + "max": 32.0, + "step": 1.0 + } + ] +} diff --git a/shaders/multipass-test/shader.slang b/shaders/multipass-test/shader.slang new file mode 100644 index 0000000..399f6cb --- /dev/null +++ b/shaders/multipass-test/shader.slang @@ -0,0 +1,38 @@ +float ringMask(float2 uv) +{ + float2 centered = uv * 2.0 - 1.0; + float radius = length(centered); + float ring = 1.0 - smoothstep(0.015, 0.035, abs(radius - 0.55)); + float cross = 1.0 - smoothstep(0.006, 0.018, min(abs(centered.x), abs(centered.y))); + return saturate(max(ring, cross)); +} + +float gridMask(float2 uv) +{ + float2 cell = abs(frac(uv * max(scale, 1.0)) - 0.5); + float line = 1.0 - smoothstep(0.455, 0.495, max(cell.x, cell.y)); + return saturate(line * 0.55); +} + +float4 buildMask(ShaderContext context) +{ + float mask = saturate(max(ringMask(context.uv), gridMask(context.uv))); + return float4(mask, context.uv.x, context.uv.y, 1.0); +} + +float4 applyMask(ShaderContext context) +{ + float4 generated = sampleVideo(context.uv); + float mask = generated.r; + float2 encodedUv = generated.gb; + float checker = step(0.5, frac((encodedUv.x + encodedUv.y) * max(scale, 1.0))); + float3 testColor = lerp(float3(0.0, 0.75, 1.0), float3(1.0, 0.1, 0.85), checker); + float3 base = context.sourceColor.rgb * 0.35; + float3 color = lerp(base, testColor, mask * saturate(intensity)); + return float4(color, context.sourceColor.a); +} + +float4 shadeVideo(ShaderContext context) +{ + return applyMask(context); +}