32 lines
1.3 KiB
Plaintext
32 lines
1.3 KiB
Plaintext
float luminance(float3 color)
|
|
{
|
|
return dot(color, float3(0.2126, 0.7152, 0.0722));
|
|
}
|
|
|
|
float currentResetPhase(float timeSeconds, float resetInterval)
|
|
{
|
|
float safeInterval = max(resetInterval, 0.001);
|
|
float cycleIndex = floor(timeSeconds / safeInterval);
|
|
return frac(cycleIndex * 0.5) >= 0.5 ? 1.0 : 0.0;
|
|
}
|
|
|
|
float4 shadeVideo(ShaderContext context)
|
|
{
|
|
float safeResetSeconds = max(resetSeconds, 0.001);
|
|
float phase = currentResetPhase(context.time, safeResetSeconds);
|
|
|
|
float4 previousFeedback = sampleFeedback(context.uv);
|
|
bool phaseMatches = context.feedbackAvailable > 0 && abs(previousFeedback.a - phase) < 0.25;
|
|
float3 previousAccumulation = phaseMatches ? previousFeedback.rgb : float3(0.0, 0.0, 0.0);
|
|
|
|
float currentLuma = luminance(context.sourceColor.rgb);
|
|
float thresholdWidth = max(softness, 0.0001);
|
|
float brightMask = smoothstep(highlightThreshold - thresholdWidth, highlightThreshold + thresholdWidth, currentLuma);
|
|
|
|
float3 currentContribution = context.sourceColor.rgb * brightMask * max(accumulateAmount, 0.0);
|
|
float3 nextAccumulation = saturate(previousAccumulation + currentContribution);
|
|
|
|
float3 displayColor = context.sourceColor.rgb * saturate(baseMix) + nextAccumulation * max(displayGain, 0.0);
|
|
return float4(saturate(displayColor), phase);
|
|
}
|