updates
Some checks failed
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m22s
CI / Windows Release Package (push) Has been cancelled

This commit is contained in:
2026-05-08 18:07:45 +10:00
parent eede6938cb
commit f322abf79a
24 changed files with 270 additions and 43 deletions

View File

@@ -50,12 +50,17 @@ float rawAlphaAt(float2 uv, ShaderContext context)
return saturate(alpha);
}
float refinedAlphaAt(float2 uv, ShaderContext context)
float matteAlphaAt(float2 uv)
{
return saturate(sampleVideo(saturate(uv)).a);
}
float refinedAlphaFromMatte(float2 uv, ShaderContext context)
{
float2 pixel = 1.0 / max(context.outputResolution, float2(1.0, 1.0));
float blur = max(matteBlur, 0.0);
float aaRadius = max(blur, 0.65);
float centerAlpha = rawAlphaAt(uv, context);
float centerAlpha = matteAlphaAt(uv);
float alpha = centerAlpha * 0.30;
if (aaRadius > 0.0001)
@@ -64,51 +69,51 @@ float refinedAlphaAt(float2 uv, ShaderContext context)
float2 halfRadius = radius * 0.5;
float alphaMin = centerAlpha;
float alphaMax = centerAlpha;
float sampleAlpha = rawAlphaAt(uv + float2(halfRadius.x, 0.0), context);
float sampleAlpha = matteAlphaAt(uv + float2(halfRadius.x, 0.0));
alpha += sampleAlpha * 0.065;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv - float2(halfRadius.x, 0.0), context);
sampleAlpha = matteAlphaAt(uv - float2(halfRadius.x, 0.0));
alpha += sampleAlpha * 0.065;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv + float2(0.0, halfRadius.y), context);
sampleAlpha = matteAlphaAt(uv + float2(0.0, halfRadius.y));
alpha += sampleAlpha * 0.065;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv - float2(0.0, halfRadius.y), context);
sampleAlpha = matteAlphaAt(uv - float2(0.0, halfRadius.y));
alpha += sampleAlpha * 0.065;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv + float2(radius.x, 0.0), context);
sampleAlpha = matteAlphaAt(uv + float2(radius.x, 0.0));
alpha += sampleAlpha * 0.06;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv - float2(radius.x, 0.0), context);
sampleAlpha = matteAlphaAt(uv - float2(radius.x, 0.0));
alpha += sampleAlpha * 0.06;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv + float2(0.0, radius.y), context);
sampleAlpha = matteAlphaAt(uv + float2(0.0, radius.y));
alpha += sampleAlpha * 0.06;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv - float2(0.0, radius.y), context);
sampleAlpha = matteAlphaAt(uv - float2(0.0, radius.y));
alpha += sampleAlpha * 0.06;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv + radius, context);
sampleAlpha = matteAlphaAt(uv + radius);
alpha += sampleAlpha * 0.05;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv - radius, context);
sampleAlpha = matteAlphaAt(uv - radius);
alpha += sampleAlpha * 0.05;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv + float2(radius.x, -radius.y), context);
sampleAlpha = matteAlphaAt(uv + float2(radius.x, -radius.y));
alpha += sampleAlpha * 0.05;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
sampleAlpha = rawAlphaAt(uv + float2(-radius.x, radius.y), context);
sampleAlpha = matteAlphaAt(uv + float2(-radius.x, radius.y));
alpha += sampleAlpha * 0.05;
alphaMin = min(alphaMin, sampleAlpha);
alphaMax = max(alphaMax, sampleAlpha);
@@ -118,7 +123,7 @@ float refinedAlphaAt(float2 uv, ShaderContext context)
}
else
{
alpha = rawAlphaAt(uv, context);
alpha = centerAlpha;
}
alpha = saturate((alpha - clipBlack) / max(clipWhite - clipBlack, 0.0001));
@@ -147,17 +152,43 @@ float3 despillColor(float3 color, float alpha)
return saturate(neutralized);
}
float4 shadeVideo(ShaderContext context)
float cropMaskAt(float2 uv, ShaderContext context)
{
float2 feather = 1.0 / max(context.outputResolution, float2(1.0, 1.0));
float left = smoothstep(saturate(cropLeft), saturate(cropLeft) + feather.x, uv.x);
float right = 1.0 - smoothstep(1.0 - saturate(cropRight) - feather.x, 1.0 - saturate(cropRight), uv.x);
float top = smoothstep(saturate(cropTop), saturate(cropTop) + feather.y, uv.y);
float bottom = 1.0 - smoothstep(1.0 - saturate(cropBottom) - feather.y, 1.0 - saturate(cropBottom), uv.y);
return saturate(left * right * top * bottom);
}
float4 buildRawMatte(ShaderContext context)
{
float4 src = context.sourceColor;
float3 color = saturate(src.rgb);
float alpha = refinedAlphaAt(context.uv, context);
float alpha = rawAlphaAt(context.uv, context);
return float4(color, alpha);
}
float4 refineMatte(ShaderContext context)
{
float4 raw = sampleVideo(context.uv);
float alpha = refinedAlphaFromMatte(context.uv, context);
return float4(saturate(raw.rgb), alpha);
}
float4 applyKey(ShaderContext context)
{
float4 keyed = sampleVideo(context.uv);
float3 color = saturate(keyed.rgb);
float alpha = saturate(keyed.a);
float spill = spillAmountForColor(color);
float3 despilled = despillColor(color, alpha);
float cropMask = cropMaskAt(context.uv, context);
alpha *= cropMask;
float edgeAmount = saturate(1.0 - abs(alpha * 2.0 - 1.0));
despilled = lerp(despilled, despilled * saturate(edgeColor.rgb), edgeAmount * saturate(edgeRecover));
alpha = saturate(lerp(alpha, rawAlphaAt(context.uv, context), edgeAmount * saturate(edgeRecover) * 0.35));
if (viewMode == 1)
return float4(alpha, alpha, alpha, 1.0);
@@ -167,10 +198,15 @@ float4 shadeVideo(ShaderContext context)
return float4(despilled, 1.0);
if (viewMode == 4)
{
float rawAlpha = rawAlphaAt(context.uv, context);
float rawAlpha = rawAlphaAt(context.uv, context) * cropMask;
return float4(rawAlpha, alpha, spill, 1.0);
}
float3 premultiplied = saturate(despilled) * alpha;
return float4(premultiplied, alpha);
}
float4 shadeVideo(ShaderContext context)
{
return applyKey(context);
}