struct FragmentInput { float4 position : SV_Position; float2 texCoord : TEXCOORD0; }; struct ShaderContext { float2 uv; float4 sourceColor; float2 inputResolution; float2 outputResolution; float time; float frameCount; float mixAmount; float bypass; int sourceHistoryLength; int temporalHistoryLength; }; cbuffer GlobalParams { float gTime; float2 gInputResolution; float2 gOutputResolution; float gFrameCount; float gMixAmount; float gBypass; int gSourceHistoryLength; int gTemporalHistoryLength; {{PARAMETER_UNIFORMS}}}; Sampler2D gVideoInput; {{SOURCE_HISTORY_SAMPLERS}}{{TEMPORAL_HISTORY_SAMPLERS}}{{TEXTURE_SAMPLERS}} float4 sampleVideo(float2 tc) { return gVideoInput.Sample(tc); } float4 sampleSourceHistory(int framesAgo, float2 tc) { if (gSourceHistoryLength <= 0) return sampleVideo(tc); int clampedIndex = framesAgo; if (clampedIndex < 0) clampedIndex = 0; if (clampedIndex >= gSourceHistoryLength) clampedIndex = gSourceHistoryLength - 1; switch (clampedIndex) { {{SOURCE_HISTORY_SWITCH_CASES}} default: return sampleVideo(tc); } } float4 sampleTemporalHistory(int framesAgo, float2 tc) { if (gTemporalHistoryLength <= 0) return sampleVideo(tc); int clampedIndex = framesAgo; if (clampedIndex < 0) clampedIndex = 0; if (clampedIndex >= gTemporalHistoryLength) clampedIndex = gTemporalHistoryLength - 1; switch (clampedIndex) { {{TEMPORAL_HISTORY_SWITCH_CASES}} default: return sampleVideo(tc); } } #include "{{USER_SHADER_INCLUDE}}" [shader("fragment")] float4 fragmentMain(FragmentInput input) : SV_Target { ShaderContext context; context.uv = input.texCoord; context.sourceColor = sampleVideo(context.uv); context.inputResolution = gInputResolution; context.outputResolution = gOutputResolution; context.time = gTime; context.frameCount = gFrameCount; context.mixAmount = gMixAmount; context.bypass = gBypass; context.sourceHistoryLength = gSourceHistoryLength; context.temporalHistoryLength = gTemporalHistoryLength; float4 effectedColor = {{ENTRY_POINT_CALL}}; float mixValue = clamp(gBypass > 0.5 ? 0.0 : gMixAmount, 0.0, 1.0); return lerp(context.sourceColor, effectedColor, mixValue); }