data storage
This commit is contained in:
72
shaders/feedback-highlight-accumulator/shader.json
Normal file
72
shaders/feedback-highlight-accumulator/shader.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"id": "feedback-highlight-accumulator",
|
||||
"name": "Feedback Highlight Accumulator",
|
||||
"description": "Demonstrates shader-local feedback by accumulating only the brightest-looking parts of the image over a timed window, then resetting and starting again. The highlight selection is an approximation based on a luminance threshold rather than an exact percentile reduction.",
|
||||
"category": "Feedback",
|
||||
"entryPoint": "shadeVideo",
|
||||
"feedback": {
|
||||
"enabled": true
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"id": "highlightThreshold",
|
||||
"label": "Highlight Threshold",
|
||||
"type": "float",
|
||||
"default": 0.99,
|
||||
"min": 0.5,
|
||||
"max": 1.5,
|
||||
"step": 0.001,
|
||||
"description": "Approximate cutoff for the brightest parts of the frame."
|
||||
},
|
||||
{
|
||||
"id": "softness",
|
||||
"label": "Threshold Softness",
|
||||
"type": "float",
|
||||
"default": 0.05,
|
||||
"min": 0.001,
|
||||
"max": 0.25,
|
||||
"step": 0.001,
|
||||
"description": "Softens the threshold so near-highlights can contribute gradually."
|
||||
},
|
||||
{
|
||||
"id": "accumulateAmount",
|
||||
"label": "Accumulate Amount",
|
||||
"type": "float",
|
||||
"default": 0.2,
|
||||
"min": 0.0,
|
||||
"max": 2.0,
|
||||
"step": 0.001,
|
||||
"description": "How much of each bright sample gets added into the running feedback image."
|
||||
},
|
||||
{
|
||||
"id": "displayGain",
|
||||
"label": "Display Gain",
|
||||
"type": "float",
|
||||
"default": 1.0,
|
||||
"min": 0.0,
|
||||
"max": 4.0,
|
||||
"step": 0.01,
|
||||
"description": "Brightness applied to the accumulated feedback when displayed."
|
||||
},
|
||||
{
|
||||
"id": "baseMix",
|
||||
"label": "Base Mix",
|
||||
"type": "float",
|
||||
"default": 0.25,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01,
|
||||
"description": "Amount of the live source image kept under the accumulation."
|
||||
},
|
||||
{
|
||||
"id": "resetSeconds",
|
||||
"label": "Reset Seconds",
|
||||
"type": "float",
|
||||
"default": 10.0,
|
||||
"min": 1.0,
|
||||
"max": 60.0,
|
||||
"step": 0.1,
|
||||
"description": "Length of each accumulation window before the feedback resets."
|
||||
}
|
||||
]
|
||||
}
|
||||
31
shaders/feedback-highlight-accumulator/shader.slang
Normal file
31
shaders/feedback-highlight-accumulator/shader.slang
Normal file
@@ -0,0 +1,31 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user