add safe-120 BFI shaders and update motion interpolation for 120 FPS (#599)

* add safe-120 BFI shaders and update motion interpolation for 120 FPS

* revert motion-inteprolation changes

* delete accidentally added files
This commit is contained in:
hunterk 2024-06-03 18:54:18 -05:00 committed by GitHub
parent ecdbd7b271
commit 573b339c98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 229 additions and 0 deletions

View file

@ -0,0 +1,7 @@
shaders = 1
shader0 = shaders/120hz-safe-BFI.slang
scale_type0 = source
scale0 = 1.0
filter_linear0 = false

View file

@ -0,0 +1,20 @@
shaders = 3
shader0 = ../stock.slang
scale_type0 = source
scale0 = 1.0
filter_linear0 = false
alias0 = bfiRefPass
shader1 = shaders/120hz-smart-BFI/calculations.slang
scale_type1 = source
scale1 = 1.0
filter_linear1 = false
wrap_mode1 = mirrored_repeat
mipmap_input1 = true
alias1 = calcPass
shader2 = shaders/120hz-smart-BFI/bfi_flicker.slang
scale_type2 = source
scale2 = 1.0
filter_linear2 = false

View file

@ -0,0 +1,66 @@
#version 450
// 120 Hz non-voltage-accumulating BFI
// by hunterk
// license: public domain
layout(push_constant) uniform Push
{
float deadline, debug_toggle;
} params;
#pragma parameter deadline "Max Cadence Flip Interval (in min)" 1.0 0.25 10.0 0.25
#pragma parameter debug_toggle "Debug (show only cadence swaps)" 0.0 0.0 1.0 1.0
bool debug = bool(params.debug_toggle);
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
vec4 FinalViewportSize;
uint FrameCount;
uint FrameDirection;
uint CurrentSubFrame;
uint TotalSubFrames;
uint Rotation;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D PassFeedback0;
#define feedback PassFeedback0
void main()
{
// The current cadence, which we store from frame to frame.
float cadence = texture(feedback, vec2(0.5,0.5)).a;
// How often to flip the cadence of the BFI. Default is 1 min, assuming 60 frames per second, but can be reduced/extended.
float timer = mod(global.FrameCount, 3600.0 * params.deadline);
// Flip the cadence whenever the timer rolls over.
cadence = (int(timer) == 0) ? float(!bool(cadence)) : cadence;
// The BFI tick oscillates between 0 and 1. TODO/FIXME: make this work with arbitrary total subframe values (or, at least evenly numbered ones)
float bfiTick = clamp(float(global.CurrentSubFrame - 1), 0.0, 1.0);
bfiTick = (bool(cadence)) ? bfiTick : float(!bool(bfiTick));
// sample the image
vec3 img = texture(Source, vTexCoord).rgb;
FragColor.rgb = img * bfiTick;
// Store the cadence in the alpha channel where it won't cause any trouble
FragColor.a = cadence;
if(debug) FragColor.rgb = FragColor.aaa;
}

View file

@ -0,0 +1,51 @@
#version 450
layout(push_constant) uniform Push
{
float debug_toggle;
} params;
#pragma parameter debug_toggle "Debug (timer, cadence, bfi, luma)" 0.0 0.0 4.0 1.0
int debug = int(params.debug_toggle);
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
vec4 FinalViewportSize;
uint FrameCount;
uint FrameDirection;
uint CurrentSubFrame;
uint TotalSubFrames;
uint Rotation;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D bfiRefPass;
layout(set = 0, binding = 3) uniform sampler2D calcPass;
void main()
{
vec3 img = texture(bfiRefPass, vTexCoord).rgb;
vec4 calc = (global.TotalSubFrames < 2) ? vec4(1.0) : texture(calcPass, vec2(0.5,0.5));
FragColor = vec4(img * calc.z, 1.0);
if(debug == 1) FragColor.rgb = calc.xxx / 3600.0;
if(debug == 2) FragColor.rgb = calc.yyy;
if(debug == 3) FragColor.rgb = calc.zzz;
if(debug == 4) FragColor.rgb = calc.www;
}

View file

@ -0,0 +1,85 @@
#version 450
// 120 Hz non-voltage-accumulating BFI
// by hunterk
// license: public domain
layout(push_constant) uniform Push
{
float deadline;
} params;
#pragma format R16G16B16A16_SFLOAT
#pragma alias calcPass
#pragma parameter deadline "Max Cadence Flip Interval (in min)" 1.0 0.25 10.0 0.25
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
vec4 FinalViewportSize;
uint FrameCount;
uint FrameDirection;
uint CurrentSubFrame;
uint TotalSubFrames;
uint Rotation;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D calcPassFeedback;
#define feedback calcPassFeedback
void main()
{
if(global.TotalSubFrames < 2)
{
return;
}
else
{
vec4 stored = texture(feedback, vec2(0.5,0.5));
// Our manually tracked framecount
float counter = stored.x;
// The current cadence, which we store from frame to frame.
float cadence = stored.y;
// When to roll over the counter
float rollover = 3600.0 * params.deadline;
// Sample the original image to detect dark/black screens
vec3 img = texture(Source, vTexCoord, 9.0).rgb;
float luma = dot(img, vec3(0.2126, 0.7152, 0.0722));
// Go ahead and reset the counter if we're within some threshold of the target whenever we get a dark/black screen
counter = ((luma < 0.05) && (counter > (0.5 * rollover))) ? 0.0 : counter;
// How often to flip the cadence of the BFI. Default is 1 min, assuming 60 frames per second, but can be reduced/extended.
counter = mod(counter, rollover);
// Flip the cadence whenever the counter rolls over.
cadence = (int(counter) < 1) ? float(!bool(cadence)) : cadence;
// The BFI tick oscillates between 0 and 1. TODO/FIXME: make this work with arbitrary total subframe values (or, at least evenly numbered ones)
float flickerTicker = clamp(float(global.CurrentSubFrame - 1), 0.0, 1.0);
flickerTicker = (bool(cadence)) ? flickerTicker : float(!bool(flickerTicker));
// Tick the counter
counter += 1.0;
// Store the values we want to mess with later, either in the next pass or the next frame
FragColor.x = counter;
FragColor.y = cadence;
FragColor.z = flickerTicker;
FragColor.w = luma;
}
}