UI fix
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m26s
CI / Windows Release Package (push) Successful in 2m28s

This commit is contained in:
Aiden
2026-05-10 21:27:13 +10:00
parent 8fcb51d140
commit 46129a6044
6 changed files with 142 additions and 76 deletions

View File

@@ -3,45 +3,37 @@ float luminance(float3 color)
return dot(color, float3(0.2126, 0.7152, 0.0722));
}
float4 buildHistory(ShaderContext context)
float4 updateBackgroundModel(ShaderContext context)
{
float4 previousFeedback = sampleFeedback(context.uv);
float4 previousHistory = context.feedbackAvailable > 0
? previousFeedback
: float4(0.0, 0.0, 0.0, 0.0);
float3 liveColor = context.sourceColor.rgb;
if (context.feedbackAvailable <= 0)
return float4(liveColor, 1.0);
// Highlight selection is always based on the live source image only.
// The stored feedback never feeds back into the threshold test.
float currentLuma = luminance(context.sourceColor.rgb);
float thresholdWidth = max(softness, 0.0001);
float brightMask = smoothstep(highlightThreshold - thresholdWidth, highlightThreshold + thresholdWidth, currentLuma);
// Treat RGBA as a 4-slot rolling scalar history:
// R = current frame, G = 1 frame ago, B = 2 frames ago, A = 3 frames ago.
// Each frame shifts the history forward and drops the oldest sample.
float currentContribution = currentLuma * brightMask * max(accumulateAmount, 0.0);
float4 nextHistory = float4(
currentContribution,
previousHistory.r,
previousHistory.g,
previousHistory.b
);
return saturate(nextHistory);
float3 previousBackground = sampleFeedback(context.uv).rgb;
float rate = saturate(learnRate);
float3 nextBackground = lerp(previousBackground, liveColor, rate);
return float4(saturate(nextBackground), 1.0);
}
float4 displayHistory(ShaderContext context)
float4 displayBackgroundDifference(ShaderContext context)
{
// In the display pass, context.sourceColor is the same-frame historyBuffer
// produced by buildHistory().
float4 history = context.sourceColor;
float recentEnergy = history.r + history.g + history.b;
float3 originalColor = sampleLayerInput(context.uv).rgb;
float highlightBoost = recentEnergy * max(displayGain, 0.0);
float3 sourceHue = originalColor / max(max(originalColor.r, originalColor.g), max(originalColor.b, 0.0001));
float3 displayColor =
originalColor +
sourceHue * highlightBoost * 1.5;
// In the display pass, context.sourceColor is the same-frame background
// model produced by updateBackgroundModel().
float3 backgroundModel = context.sourceColor.rgb;
float3 liveColor = sampleLayerInput(context.uv).rgb;
float3 delta = abs(liveColor - backgroundModel);
float difference = max(delta.r, max(delta.g, delta.b));
float thresholdWidth = max(softness, 0.0001);
float motionMask = smoothstep(
differenceThreshold - thresholdWidth,
differenceThreshold + thresholdWidth,
difference);
float3 baseColor = lerp(liveColor, backgroundModel, saturate(backgroundMix));
float3 overlayColor = overlayTint.rgb * max(luminance(liveColor), 0.15);
float overlayAmount = motionMask * saturate(overlayOpacity) * overlayTint.a;
float3 displayColor = lerp(baseColor, baseColor + overlayColor, overlayAmount);
return float4(saturate(displayColor), 1.0);
}