mirror of
https://github.com/libretro/slang-shaders.git
synced 2024-06-22 14:21:47 -04:00
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:
parent
ecdbd7b271
commit
573b339c98
7
bfi/120hz-safe-BFI.slangp
Normal file
7
bfi/120hz-safe-BFI.slangp
Normal file
|
@ -0,0 +1,7 @@
|
|||
shaders = 1
|
||||
|
||||
shader0 = shaders/120hz-safe-BFI.slang
|
||||
scale_type0 = source
|
||||
scale0 = 1.0
|
||||
|
||||
filter_linear0 = false
|
20
bfi/120hz-smart-BFI.slangp
Normal file
20
bfi/120hz-smart-BFI.slangp
Normal 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
|
66
bfi/shaders/120hz-safe-BFI.slang
Normal file
66
bfi/shaders/120hz-safe-BFI.slang
Normal 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;
|
||||
}
|
51
bfi/shaders/120hz-smart-BFI/bfi_flicker.slang
Normal file
51
bfi/shaders/120hz-smart-BFI/bfi_flicker.slang
Normal 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;
|
||||
}
|
85
bfi/shaders/120hz-smart-BFI/calculations.slang
Normal file
85
bfi/shaders/120hz-smart-BFI/calculations.slang
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue