add some BFI shaders and blargg's NTSC port (#653)
* Create bfi-simple.slang * Create bfi-simple.slangp * add blargg's NTSC port * Create blargg.slangp * add edge-blended 240 hz rolling scan BFI * Add files via upload * add subframe motionblur test * Create subframe-motionblur-test.slangp * Create checkerboard.slang * Create checkerboard.slangp * start moving motionblur_test to bfi directory * add motionblur_test preset * Delete bfi/shaders/checkerboard.slang doesn't work anyway * Delete bfi/checkerboard.slangp doesn't work anyway * finish moving motionblur_test * finish moving motionblur_test * move some stuff around * optimize pngs * add some missing licenses
14
ntsc/blargg.slangp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
shaders = "3"
|
||||||
|
|
||||||
|
shader0 = "../stock.slang"
|
||||||
|
filter_linear0 = "false"
|
||||||
|
scale_type_x0 = "absolute"
|
||||||
|
scale_x0 = "640.000000"
|
||||||
|
scale_type_y0 = "source"
|
||||||
|
scale_y0 = "1.000000"
|
||||||
|
|
||||||
|
shader1 = "shaders/blargg/blargg-0.slang"
|
||||||
|
filter_linear1 = false
|
||||||
|
|
||||||
|
shader2 = "shaders/blargg/blargg-1.slang"
|
||||||
|
filter_linear2 = false
|
48
ntsc/shaders/blargg/blargg-0.slang
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// NewRisingSun and blargg's NTSC filter
|
||||||
|
// simplified and ported to glsl by metallic77
|
||||||
|
// no license given, but I would expect it to inherit the LGPL license from the C version
|
||||||
|
|
||||||
|
#include "blargg_params.inc"
|
||||||
|
|
||||||
|
#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 * 1.0001;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
|
#define PI 3.1415926
|
||||||
|
|
||||||
|
// Colorspace conversion matrix for RGB-to-YIQ
|
||||||
|
const mat3 RGBYIQ = mat3(
|
||||||
|
0.2989, 0.5870, 0.1140,
|
||||||
|
0.5959, -0.2744, -0.3216,
|
||||||
|
0.2115, -0.5229, 0.3114
|
||||||
|
);
|
||||||
|
#define onedeg 0.017453
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float modulo = 3.0; if (global.OriginalSize.x > 300.0) modulo = 2.0;
|
||||||
|
float phase = floor(vTexCoord.x*params.SourceSize.x)*pi_mod*onedeg + mod(floor(vTexCoord.y*params.SourceSize.y),modulo)*PI*vert_scal;
|
||||||
|
phase += ntsc_hue;
|
||||||
|
if (stat_ph == 1.0) phase += sin(mod(float(params.FrameCount/2),2.0))*PI;
|
||||||
|
|
||||||
|
vec3 YUV = texture(Source,vTexCoord).rgb;
|
||||||
|
YUV = YUV*RGBYIQ;
|
||||||
|
|
||||||
|
YUV *= vec3(ntsc_bri, cos(phase), sin(phase));
|
||||||
|
float signal = YUV.x + YUV.y + YUV.z;
|
||||||
|
FragColor = vec4(vec3(signal), 1.0);
|
||||||
|
}
|
136
ntsc/shaders/blargg/blargg-1.slang
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// NewRisingSun and blargg's NTSC filter
|
||||||
|
// simplified and ported to glsl by metallic77
|
||||||
|
// no license given, but I would expect it to inherit the LGPL license from the C version
|
||||||
|
|
||||||
|
#include "blargg_params.inc"
|
||||||
|
|
||||||
|
#define PI 3.1415926
|
||||||
|
#define fringing_mid 0.8
|
||||||
|
#define fringing_max 1.6
|
||||||
|
#define artifacts_mid 0.4
|
||||||
|
#define artifacts_max 0.6
|
||||||
|
#define onedeg 0.017453
|
||||||
|
|
||||||
|
// Colorspace conversion matrix for YIQ-to-RGB
|
||||||
|
const mat3 YIQ2RGB = mat3(
|
||||||
|
1.0, 0.956, 0.6210,
|
||||||
|
1.0, -0.2720, -0.6474,
|
||||||
|
1.0, -1.1060, 1.7046);
|
||||||
|
|
||||||
|
float blackman (float x)
|
||||||
|
{
|
||||||
|
float b = 0.42 - 0.5 * cos(x) + 0.08 * cos( x * 2.0 );
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 * 1.0001;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 size = params.SourceSize.xy;
|
||||||
|
vec2 uv = vTexCoord;
|
||||||
|
int i = int(kernel_half);
|
||||||
|
float cutoff_factor = -0.03125;
|
||||||
|
float cutoff = ntsc_bleed;
|
||||||
|
if ( cutoff < 0.0 )
|
||||||
|
{
|
||||||
|
// keep extreme value accessible only near upper end of scale (1.0)
|
||||||
|
cutoff *= cutoff;
|
||||||
|
cutoff *= cutoff;
|
||||||
|
cutoff *= cutoff;
|
||||||
|
cutoff *= -30.0 / 0.65;
|
||||||
|
}
|
||||||
|
cutoff = cutoff_factor - 0.65 * cutoff_factor * cutoff;
|
||||||
|
|
||||||
|
// Sample composite signal and decode to YUV
|
||||||
|
vec3 YUV = vec3(0);
|
||||||
|
float sum = 0.0;
|
||||||
|
float to_angle = ntsc_res + 1.0;
|
||||||
|
float rolloff = 1.0 + ntsc_sharp * 0.032;
|
||||||
|
float maxh = kernel_half*2.0;
|
||||||
|
float pow_a_n = pow( rolloff, maxh );
|
||||||
|
to_angle = PI / maxh * LUMA_CUTOFF * (to_angle * to_angle + 1.0);
|
||||||
|
|
||||||
|
for (int n=0; n<i*2+1; n++) { // 2*maxh + 1
|
||||||
|
// blargg-ntsc
|
||||||
|
// generate luma (y) filter using sinc kernel
|
||||||
|
float a = PI * 2.0 / (kernel_half * 2.0) * float(n);
|
||||||
|
float w = blackman(a);
|
||||||
|
vec2 pos = uv - vec2(kernel_half/size.x,0.0) + vec2(float(n) / size.x, 0.0);
|
||||||
|
|
||||||
|
float x = float(n) - kernel_half; // maxh/2
|
||||||
|
|
||||||
|
float angle = x * to_angle;
|
||||||
|
float kernel = 0.0;
|
||||||
|
|
||||||
|
float fringing = 0.0;
|
||||||
|
if (fract(float(n+2)/4.0) == 0.0)
|
||||||
|
{
|
||||||
|
if(fring >0.0)
|
||||||
|
fringing = -fring*(fringing_max-fringing_mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//instability occurs at center point with rolloff very close to 1.0
|
||||||
|
if ( x > 1.056 || pow_a_n > 1.056 || pow_a_n < 0.981 )
|
||||||
|
{
|
||||||
|
float rolloff_cos_a = rolloff * cos( angle );
|
||||||
|
float num = 1.0 - rolloff_cos_a -
|
||||||
|
pow_a_n * cos( maxh * angle ) +
|
||||||
|
pow_a_n * rolloff * cos( (maxh - 1.0) * angle );
|
||||||
|
float den = 1.0 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
|
||||||
|
float dsf = num / den;
|
||||||
|
kernel = dsf - 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
YUV.x += texture(Source, pos).r*w*kernel*(1.0+fringing);
|
||||||
|
|
||||||
|
sum += w*kernel;
|
||||||
|
}
|
||||||
|
YUV.x /= sum;
|
||||||
|
float sumc = 0.0;
|
||||||
|
|
||||||
|
// blargg ntsc-chroma
|
||||||
|
// generate chroma (iq) filter using gaussian kernel
|
||||||
|
|
||||||
|
for (int n=-i; n<i; n++) {
|
||||||
|
vec2 pos = uv + vec2(float(n) / size.x, 0.0);
|
||||||
|
float modulo = 3.0; if (global.OriginalSize.x > 300.0) modulo = 2.0;
|
||||||
|
|
||||||
|
float phase = (floor(vTexCoord.x*params.SourceSize.x)+float(n))*pi_mod*onedeg + mod(floor(vTexCoord.y*params.SourceSize.y),modulo)*PI*vert_scal;
|
||||||
|
if (stat_ph == 1.0) phase += sin(mod(float(params.FrameCount/2),2.0))*PI;
|
||||||
|
|
||||||
|
float r = exp(cutoff*float(n)*float(n));
|
||||||
|
|
||||||
|
float artifacts = 0.0;
|
||||||
|
if (fract(float(n+i+2)/4.0) == 0.0)
|
||||||
|
{
|
||||||
|
if(afacts>0.0)
|
||||||
|
artifacts= -afacts*(artifacts_max-artifacts_mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 carrier = ntsc_sat*vec2(cos(phase), sin(phase));
|
||||||
|
YUV.yz += r*texture(Source, pos).gb * carrier*(1.0+artifacts);
|
||||||
|
sumc += r;
|
||||||
|
}
|
||||||
|
YUV.yz /= sumc;
|
||||||
|
|
||||||
|
// Convert signal to RGB
|
||||||
|
YUV = YUV*YIQ2RGB;
|
||||||
|
FragColor = vec4(YUV, 1.0);
|
||||||
|
}
|
43
ntsc/shaders/blargg/blargg_params.inc
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
vec4 SourceSize;
|
||||||
|
uint FrameCount;
|
||||||
|
float kernel_half, ntsc_sat, ntsc_res, ntsc_bri, ntsc_hue, ntsc_sharp, fring, afacts, ntsc_bleed, LUMA_CUTOFF, stat_ph, dummy, pi_mod, vert_scal;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
#pragma parameter kernel_half "Kernel Half-Size (speed-up)" 16.0 1.0 16.0 1.0
|
||||||
|
#pragma parameter ntsc_sat "Saturation" 2.0 0.0 6.0 0.05
|
||||||
|
#pragma parameter ntsc_res "Resolution" 0.0 -1.0 1.0 0.05
|
||||||
|
#pragma parameter ntsc_sharp "Sharpness" 0.1 -1.0 1.0 0.05
|
||||||
|
#pragma parameter ntsc_bri "Brightness" 1.0 0.0 2.0 0.01
|
||||||
|
#pragma parameter ntsc_hue "Hue" 0.0 -1.0 6.3 0.05
|
||||||
|
#pragma parameter fring "Fringing" 0.0 0.0 1.0 0.05
|
||||||
|
#pragma parameter afacts "Artifacts" 0.0 0.0 1.0 0.05
|
||||||
|
#pragma parameter ntsc_bleed "Chroma Bleed" 0.0 -0.75 2.0 0.05
|
||||||
|
#pragma parameter LUMA_CUTOFF "Luma Cutoff" 0.2 0.0 1.0 0.005
|
||||||
|
#pragma parameter stat_ph "Dot Crawl On/Off" 0.0 0.0 1.0 1.0
|
||||||
|
#pragma parameter dummy " [ System Specific Tweaks] " 0.0 0.0 0.0 0.0
|
||||||
|
#pragma parameter pi_mod "Phase-Horiz. Angle" 96.0 1.0 360.0 1.0
|
||||||
|
#pragma parameter vert_scal "Phase-Vertical Scale" 0.6667 0.0 2.0 0.05555
|
||||||
|
|
||||||
|
#define kernel_half params.kernel_half
|
||||||
|
#define ntsc_sat params.ntsc_sat
|
||||||
|
#define ntsc_res params.ntsc_res
|
||||||
|
#define ntsc_sharp params.ntsc_sharp
|
||||||
|
#define fring params.fring
|
||||||
|
#define afacts params.afacts
|
||||||
|
#define ntsc_bleed params.ntsc_bleed
|
||||||
|
#define LUMA_CUTOFF params.LUMA_CUTOFF
|
||||||
|
#define stat_ph params.stat_ph
|
||||||
|
#define dummy params.dummy
|
||||||
|
#define pi_mod params.pi_mod
|
||||||
|
#define vert_scal params.vert_scal
|
||||||
|
#define ntsc_bri params.ntsc_bri
|
||||||
|
#define ntsc_hue params.ntsc_hue
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
} global;
|
3
subframe-bfi/bfi-simple.slangp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
shaders = 1
|
||||||
|
|
||||||
|
shader0 = shaders/bfi-simple.slang
|
12
subframe-bfi/edge-blended-240hz-bfi.slangp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
shaders = 1
|
||||||
|
|
||||||
|
shader0 = shaders/edge-blended/edge-blended-240hz-bfi.slang
|
||||||
|
|
||||||
|
textures = "top;bot;midtop;midbot"
|
||||||
|
|
||||||
|
top = shaders/edge-blended/resources/240hzTop.png
|
||||||
|
top_wrap_mode = mirrored_repeat
|
||||||
|
bot = shaders/edge-blended/resources/240hzBot.png
|
||||||
|
bot_wrap_mode = mirrored_repeat
|
||||||
|
midtop = shaders/edge-blended/resources/240hzMidTop.png
|
||||||
|
midbot = shaders/edge-blended/resources/240hzMidBot.png
|
9
subframe-bfi/motionblur_test.slangp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
shaders = 1
|
||||||
|
|
||||||
|
shader0 = shaders/motionblur_test/shaders/motionblur_test.slang
|
||||||
|
|
||||||
|
textures = "base;twoSub;threeSub;fourSub"
|
||||||
|
base = shaders/motionblur_test/resources/60.png
|
||||||
|
twoSub = shaders/motionblur_test/resources/120.png
|
||||||
|
threeSub = shaders/motionblur_test/resources/180.png
|
||||||
|
fourSub = shaders/motionblur_test/resources/240.png
|
74
subframe-bfi/shaders/bfi-simple.slang
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// BFI Simple
|
||||||
|
// several different implementations of software BFI
|
||||||
|
// license: public domain
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount, CurrentSubFrame, TotalSubFrames;
|
||||||
|
float bfi_mode, bfidummy0, bfidummy1, bfidummy2, bfidummy3, bfidummy4, bfidummy5;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
#pragma parameter bfi_mode "Sub-Frame BFI Mode" 0.0 0.0 5.0 1.0
|
||||||
|
int mode = int(params.bfi_mode);
|
||||||
|
|
||||||
|
#pragma parameter bfidummy0 "|| Mode 0 -> Disable BFI" 0.00001 0.00001 0.00001 0.00001
|
||||||
|
#pragma parameter bfidummy1 "|| Mode 1 -> Cycle on each sub-frame" 0.00001 0.00001 0.00001 0.00001
|
||||||
|
#pragma parameter bfidummy2 "|| Mode 2 -> Show only the first sub-frame" 0.00001 0.00001 0.00001 0.00001
|
||||||
|
#pragma parameter bfidummy3 "|| Mode 3 -> Show all but the last sub-frame" 0.00001 0.00001 0.00001 0.00001
|
||||||
|
#pragma parameter bfidummy4 "|| Mode 4 -> Fade out" 0.00001 0.00001 0.00001 0.00001
|
||||||
|
#pragma parameter bfidummy5 "|| Mode 5 -> Half blank" 0.00001 0.00001 0.00001 0.00001
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#pragma stage vertex
|
||||||
|
layout(location = 0) in vec4 Position;
|
||||||
|
layout(location = 1) in vec2 TexCoord;
|
||||||
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
layout(location = 1) out vec4 bfi;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = global.MVP * Position;
|
||||||
|
vTexCoord = TexCoord;
|
||||||
|
switch(mode){
|
||||||
|
case 0: // passthru
|
||||||
|
bfi = vec4(1.0);
|
||||||
|
break;
|
||||||
|
case 1: // classic oscillator
|
||||||
|
bfi = vec4(mod(float(params.FrameCount * params.TotalSubFrames + params.CurrentSubFrame), 2.));
|
||||||
|
break;
|
||||||
|
case 2: // blank all subframes after the first (maximize blur reduction)
|
||||||
|
bfi = (params.CurrentSubFrame == 1) ? vec4(1.0) : vec4(0.0);
|
||||||
|
break;
|
||||||
|
case 3: // blank the last subframe (maximize brightness)
|
||||||
|
bfi = (params.CurrentSubFrame == params.TotalSubFrames) ? vec4(0.0) : vec4(1.0);
|
||||||
|
break;
|
||||||
|
case 4: // fade out
|
||||||
|
bfi = vec4(1. - float(params.CurrentSubFrame - 1) / float(params.TotalSubFrames));
|
||||||
|
break;
|
||||||
|
case 5: // half on, half off
|
||||||
|
bfi = (params.CurrentSubFrame > 0.5 * params.TotalSubFrames) ? vec4(1.0) : vec4(0.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 1) in vec4 bfi;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||||
|
if(params.TotalSubFrames < 2) return;
|
||||||
|
else FragColor *= bfi;
|
||||||
|
}
|
101
subframe-bfi/shaders/edge-blended/edge-blended-240hz-bfi.slang
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// edge-blended 240Hz BFI
|
||||||
|
// by hunterk
|
||||||
|
// license: public domain
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
uint CurrentSubFrame;
|
||||||
|
uint TotalSubFrames;
|
||||||
|
float favor_black;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
// setting this to 1 makes 75% of the screen black at all times
|
||||||
|
// while setting it to 0 makes it only 25% black
|
||||||
|
#pragma parameter favor_black "Favor Black" 1.0 0.0 1.0 1.0
|
||||||
|
|
||||||
|
// set a macro here for debugging purposes since there's no way to advance subframes
|
||||||
|
#define debugFrame params.CurrentSubFrame
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#pragma stage vertex
|
||||||
|
layout(location = 0) in vec4 Position;
|
||||||
|
layout(location = 1) in vec2 TexCoord;
|
||||||
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
layout(location = 1) out vec4 check;
|
||||||
|
layout(location = 2) out vec2 lutCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = global.MVP * Position;
|
||||||
|
vTexCoord = TexCoord;
|
||||||
|
// TODO/FIXME: figure out some good way to make the seams roll
|
||||||
|
lutCoord = TexCoord;// + vec2(0., mod(float(params.FrameCount), 250.)/1000.);
|
||||||
|
// set up a bool to check which sub-frame we're currently on
|
||||||
|
bvec4 checkbool = bvec4(debugFrame == 1,
|
||||||
|
debugFrame == 2,
|
||||||
|
debugFrame == 3,
|
||||||
|
debugFrame == 4);
|
||||||
|
// flip the check bool if we want to blackout on all but one sub-frame
|
||||||
|
bvec4 boolflip = bvec4(params.favor_black);
|
||||||
|
check.x = boolflip.x ? float(!checkbool.x) : float(checkbool.x);
|
||||||
|
check.y = boolflip.y ? float(!checkbool.y) : float(checkbool.y);
|
||||||
|
check.z = boolflip.z ? float(!checkbool.z) : float(checkbool.z);
|
||||||
|
check.w = boolflip.w ? float(!checkbool.w) : float(checkbool.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 1) in vec4 check;
|
||||||
|
layout(location = 2) in vec2 lutCoord;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D top;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D bot;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D midtop;
|
||||||
|
layout(set = 0, binding = 6) uniform sampler2D midbot;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||||
|
// early return if we don't have subframes enabled
|
||||||
|
if(params.TotalSubFrames == 1) return;
|
||||||
|
|
||||||
|
// use a nonstandard approximation of linear gamma to blend transitions better
|
||||||
|
// going higher makes the transitions blend better but creates harsh lines elsewhere
|
||||||
|
FragColor = pow(FragColor, vec4(2.5));
|
||||||
|
|
||||||
|
// sample the LUTs, "linearize" them
|
||||||
|
vec4 Top = texture(top, lutCoord);
|
||||||
|
Top = pow(Top, vec4(2.5));
|
||||||
|
vec4 Bot = texture(bot, lutCoord);
|
||||||
|
Bot = pow(Bot, vec4(2.5));
|
||||||
|
vec4 MidTop = texture(midtop, lutCoord);
|
||||||
|
MidTop = pow(MidTop, vec4(2.5));
|
||||||
|
vec4 MidBot = texture(midbot, lutCoord);
|
||||||
|
MidBot = pow(MidBot, vec4(2.5));
|
||||||
|
|
||||||
|
// based on the subframe, apply the blackout LUTs
|
||||||
|
FragColor = (bool(check.x)) ? mix(FragColor, Top, Top.a) : FragColor;
|
||||||
|
FragColor = (bool(check.y)) ? mix(FragColor, MidTop, MidTop.a) : FragColor;
|
||||||
|
FragColor = (bool(check.z)) ? mix(FragColor, MidBot, MidBot.a) : FragColor;
|
||||||
|
FragColor = (bool(check.w)) ? mix(FragColor, Bot, Bot.a) : FragColor;
|
||||||
|
|
||||||
|
// black-out the other transitions when preferring black
|
||||||
|
FragColor *= (params.favor_black > 0.5 && debugFrame == 1 && vTexCoord.y > 0.3333) ? vec4(0.0) : vec4(1.0);
|
||||||
|
FragColor *= (params.favor_black > 0.5 && debugFrame == 3 && (vTexCoord.y > 0.8 || vTexCoord.y < 0.3333)) ? vec4(0.0) : vec4(1.0);
|
||||||
|
FragColor *= (params.favor_black > 0.5 && debugFrame == 2 && (vTexCoord.y > 0.6667 || vTexCoord.y < 0.2)) ? vec4(0.0) : vec4(1.0);
|
||||||
|
FragColor *= (params.favor_black > 0.5 && debugFrame == 4 && vTexCoord.y < 0.6667) ? vec4(0.0) : vec4(1.0);
|
||||||
|
|
||||||
|
// de-"linearize"
|
||||||
|
FragColor = pow(FragColor, vec4(1./2.5));
|
||||||
|
}
|
BIN
subframe-bfi/shaders/edge-blended/resources/240hzBot.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
subframe-bfi/shaders/edge-blended/resources/240hzMidBot.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
subframe-bfi/shaders/edge-blended/resources/240hzMidTop.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
subframe-bfi/shaders/edge-blended/resources/240hzTop.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
subframe-bfi/shaders/motionblur_test/resources/120.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
subframe-bfi/shaders/motionblur_test/resources/180.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
subframe-bfi/shaders/motionblur_test/resources/240.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
subframe-bfi/shaders/motionblur_test/resources/60.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,88 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// motionblur test
|
||||||
|
// by hunterk
|
||||||
|
// license: public domain
|
||||||
|
|
||||||
|
layout(push_constant) uniform Push
|
||||||
|
{
|
||||||
|
vec4 SourceSize;
|
||||||
|
vec4 OriginalSize;
|
||||||
|
vec4 OutputSize;
|
||||||
|
uint FrameCount;
|
||||||
|
uint TotalSubFrames;
|
||||||
|
uint CurrentSubFrame;
|
||||||
|
vec4 FinalViewportSize;
|
||||||
|
float inv_speed;
|
||||||
|
float OriginalAspect;
|
||||||
|
} params;
|
||||||
|
|
||||||
|
#pragma parameter inv_speed "Invader Speed" 1.0 1.0 20.0 1.0
|
||||||
|
float speed = params.FrameCount * params.inv_speed;
|
||||||
|
|
||||||
|
|
||||||
|
layout(std140, set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
mat4 MVP;
|
||||||
|
} global;
|
||||||
|
|
||||||
|
#pragma stage vertex
|
||||||
|
layout(location = 0) in vec4 Position;
|
||||||
|
layout(location = 1) in vec2 TexCoord;
|
||||||
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
layout(location = 1) out vec2 noSubCoord;
|
||||||
|
layout(location = 2) out vec2 fullSubCoord;
|
||||||
|
layout(location = 3) out vec2 halfSubCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = global.MVP * Position;
|
||||||
|
vTexCoord = TexCoord;
|
||||||
|
noSubCoord = vec2(vTexCoord.xy * params.OutputSize.xy) - ivec2(mod(speed * params.TotalSubFrames, params.OutputSize.x),100);
|
||||||
|
fullSubCoord = vec2(vTexCoord.xy * params.OutputSize.xy) - ivec2(mod(speed * params.TotalSubFrames + params.CurrentSubFrame - 1., params.OutputSize.x),400);
|
||||||
|
halfSubCoord = vec2(vTexCoord.xy * params.OutputSize.xy) - ivec2(mod(speed * params.TotalSubFrames + int((params.CurrentSubFrame - 1.) / 2.), params.OutputSize.x),250);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma stage fragment
|
||||||
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 1) in vec2 noSubCoord;
|
||||||
|
layout(location = 2) in vec2 fullSubCoord;
|
||||||
|
layout(location = 3) in vec2 halfSubCoord;
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
layout(set = 0, binding = 3) uniform sampler2D base;
|
||||||
|
layout(set = 0, binding = 4) uniform sampler2D twoSub;
|
||||||
|
layout(set = 0, binding = 5) uniform sampler2D threeSub;
|
||||||
|
layout(set = 0, binding = 6) uniform sampler2D fourSub;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = texture(Source, vTexCoord);
|
||||||
|
if(params.TotalSubFrames == 2)
|
||||||
|
{
|
||||||
|
FragColor = vec4(0.0);
|
||||||
|
vec4 invader60 = texelFetch(base, ivec2(noSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader60, invader60.a);
|
||||||
|
vec4 invader120 = texelFetch(twoSub, ivec2(fullSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader120, invader120.a);
|
||||||
|
}
|
||||||
|
else if(params.TotalSubFrames == 3)
|
||||||
|
{
|
||||||
|
FragColor = vec4(0.0);
|
||||||
|
vec4 invader60 = texelFetch(base, ivec2(noSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader60, invader60.a);
|
||||||
|
vec4 invader180 = texelFetch(threeSub, ivec2(fullSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader180, invader180.a);
|
||||||
|
}
|
||||||
|
else if(params.TotalSubFrames == 4)
|
||||||
|
{
|
||||||
|
FragColor = vec4(0.0);
|
||||||
|
vec4 invader60 = texelFetch(base, ivec2(noSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader60, invader60.a);
|
||||||
|
vec4 invader120 = texelFetch(twoSub, ivec2(halfSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader120, invader120.a);
|
||||||
|
vec4 invader240 = texelFetch(fourSub, ivec2(fullSubCoord), 0);
|
||||||
|
FragColor = mix(FragColor, invader240, invader240.a);
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
}
|