mirror of
https://github.com/libretro/slang-shaders.git
synced 2024-11-27 02:20:41 +00:00
archive mame_hlsl and update to version based on bgfx code
This commit is contained in:
parent
603be636dc
commit
5db5e6572d
@ -1,85 +1,75 @@
|
||||
# info on how the passes come together can be found in mame/src/osd/modules/render/d3d/d3dhlsl.cpp
|
||||
shaders = 12
|
||||
# info on how the passes come together can be found in mame/bgfx/chains/hlsl.json
|
||||
shaders = 11
|
||||
|
||||
shader0 = shaders/mame_hlsl/shaders/mame_ntsc.slang
|
||||
shader0 = shaders/mame_hlsl/shaders/mame_ntsc_encode.slang
|
||||
filter_linear0 = true
|
||||
alias0 = NTSCPass
|
||||
scale_type0 = source
|
||||
scale0 = 1.0
|
||||
filter_linear0 = true
|
||||
|
||||
shader1 = shaders/mame_hlsl/shaders/mame_color.slang
|
||||
alias1 = ColorPass
|
||||
shader1 = shaders/mame_hlsl/shaders/mame_ntsc_decode.slang
|
||||
filter_linear1 = true
|
||||
alias1 = NTSCPass
|
||||
scale_type1 = source
|
||||
scale1 = 1.0
|
||||
filter_linear1 = true
|
||||
|
||||
shader2 = ../interpolation/shaders/sharp-bilinear.slang
|
||||
alias2 = PrescalePass
|
||||
shader2 = shaders/mame_hlsl/shaders/mame_color.slang
|
||||
alias2 = ColorPass
|
||||
scale_type2 = source
|
||||
scale2 = 1.0
|
||||
filter_linear2 = true
|
||||
scale2 = 4.0
|
||||
|
||||
shader3 = shaders/mame_hlsl/shaders/mame_deconverge.slang
|
||||
alias3 = DeconvergePass
|
||||
shader3 = shaders/mame_hlsl/shaders/mame_prescale.slang
|
||||
alias3 = PrescalePass
|
||||
scale_type3 = viewport
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale3 = 0.5
|
||||
scale3 = 1.0
|
||||
|
||||
shader4 = shaders/mame_hlsl/shaders/mame_scanline.slang
|
||||
alias4 = ScanlinePass
|
||||
shader4 = shaders/mame_hlsl/shaders/mame_deconverge.slang
|
||||
alias4 = DeconvergePass
|
||||
filter_linear4 = true
|
||||
scale_type4 = source
|
||||
scale4 = 2.0
|
||||
scale_type4 = viewport
|
||||
scale4 = 1.0
|
||||
|
||||
shader5 = shaders/mame_hlsl/shaders/mame_focus.slang
|
||||
alias5 = FocusPass
|
||||
shader5 = shaders/mame_hlsl/shaders/mame_scanline.slang
|
||||
alias5 = ScanlinePass
|
||||
filter_linear5 = true
|
||||
scale_type5 = viewport
|
||||
scale5 = 1.0
|
||||
|
||||
shader6 = shaders/mame_hlsl/shaders/mame_phosphor.slang
|
||||
alias6 = PhosphorPass
|
||||
shader6 = shaders/mame_hlsl/shaders/mame_defocus.slang
|
||||
alias6 = FocusPass
|
||||
filter_linear6 = true
|
||||
scale_type6 = viewport
|
||||
scale6 = 1.0
|
||||
|
||||
shader7 = shaders/mame_hlsl/shaders/mame_post.slang
|
||||
alias7 = PostPass
|
||||
filter_linear7 = true
|
||||
scale_type7 = viewport
|
||||
scale7 = 1.0
|
||||
|
||||
shader8 = shaders/mame_hlsl/shaders/mame_chroma.slang
|
||||
alias8 = ChromaPass
|
||||
shader8 = shaders/mame_hlsl/shaders/mame_phosphor.slang
|
||||
alias8 = PhosphorPass
|
||||
filter_linear8 = true
|
||||
scale_type8 = viewport
|
||||
scale8 = 1.0
|
||||
|
||||
shader9 = shaders/mame_hlsl/shaders/mame_downsample.slang
|
||||
alias9 = DownsamplePass
|
||||
shader9 = shaders/mame_hlsl/shaders/mame_chroma.slang
|
||||
alias9 = ChromaPass
|
||||
filter_linear9 = true
|
||||
scale_type9 = viewport
|
||||
scale9 = 1.0
|
||||
|
||||
shader10 = shaders/mame_hlsl/shaders/mame_bloom.slang
|
||||
alias10 = BloomPass
|
||||
shader10 = shaders/mame_hlsl/shaders/mame_distortion.slang
|
||||
alias10 = DistortionPass
|
||||
filter_linear10 = true
|
||||
mipmap_input10 = true
|
||||
scale_type10 = source
|
||||
scale_type10 = viewport
|
||||
scale10 = 1.0
|
||||
|
||||
shader11 = shaders/mame_hlsl/shaders/mame_distortion.slang
|
||||
alias11 = DistortionPass
|
||||
shader11 = shaders/mame_hlsl/shaders/lut.slang
|
||||
filter_linear11 = true
|
||||
|
||||
# doesn't work, so commenting
|
||||
# shader12 = shaders/mame_hlsl/shaders/mame_vector.slang
|
||||
# alias12 = VectorPass
|
||||
# filter_linear12 = true
|
||||
|
||||
# mame's textures are available here: https://github.com/mamedev/mame/tree/master/artwork
|
||||
textures = "MaskTexture"
|
||||
MaskTexture = shaders/mame_hlsl/resources/aperture-grille.png
|
||||
|
||||
parameters = "AUTO_PRESCALE;chromaa_x;chromaa_y;chromab_x;chromab_y;chromac_x;chromac_y;ygain_r;ygain_g;ygain_b"
|
||||
chromaa_x = "0.630"
|
||||
chromaa_y = "0.340"
|
||||
chromab_x = "0.310"
|
||||
chromab_y = "0.595"
|
||||
chromac_x = "0.155"
|
||||
chromac_y = "0.070"
|
||||
ygain_r = "0.1875"
|
||||
ygain_g = "0.6940"
|
||||
ygain_b = "0.1185"
|
||||
AUTO_PRESCALE = "0.0"
|
||||
|
@ -10,6 +10,8 @@ layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OutputSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
@ -12,6 +12,7 @@ layout(push_constant) uniform Push
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
@ -12,6 +12,7 @@ layout(push_constant) uniform Push
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
@ -19,47 +20,47 @@ layout(push_constant) uniform Push
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define s_tex Source
|
||||
|
||||
vec3 RedRatios = vec3(global.col_red, 0.0, 0.0);
|
||||
vec3 GrnRatios = vec3(0.0, global.col_grn, 0.0);
|
||||
vec3 BluRatios = vec3(0.0, 0.0, global.col_blu);
|
||||
vec3 Offset = vec3(global.col_offset_x, global.col_offset_y, global.col_offset_z);
|
||||
vec3 Scale = vec3(global.col_scale_x, global.col_scale_y, global.col_scale_z);
|
||||
float Saturation = global.col_saturation;
|
||||
vec4 u_red_ratios = vec4(global.col_rr, global.col_rg, global.col_rb, 0.0);
|
||||
vec4 u_grn_ratios = vec4(global.col_gr, global.col_gg, global.col_gb, 0.0);
|
||||
vec4 u_blu_ratios = vec4(global.col_br, global.col_bg, global.col_bb, 0.0);
|
||||
vec4 u_offset = vec4(global.col_offset_x, global.col_offset_y, global.col_offset_z, 0.);
|
||||
vec4 u_scale = vec4(global.col_scale_x, global.col_scale_y, global.col_scale_z, 0.);
|
||||
vec4 u_saturation = vec4(global.col_saturation);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 BaseTexel = texture(DiffuseSampler, vTexCoord);
|
||||
vec4 BaseTexel = texture(s_tex, v_texcoord0);
|
||||
|
||||
vec3 OutRGB = BaseTexel.rgb;
|
||||
|
||||
// RGB Tint & Shift
|
||||
float ShiftedRed = dot(OutRGB, RedRatios);
|
||||
float ShiftedGrn = dot(OutRGB, GrnRatios);
|
||||
float ShiftedBlu = dot(OutRGB, BluRatios);
|
||||
float ShiftedRed = dot(OutRGB, u_red_ratios.xyz);
|
||||
float ShiftedGrn = dot(OutRGB, u_grn_ratios.xyz);
|
||||
float ShiftedBlu = dot(OutRGB, u_blu_ratios.xyz);
|
||||
|
||||
// RGB Scale & Offset
|
||||
vec3 OutTexel = vec3(ShiftedRed, ShiftedGrn, ShiftedBlu) * Scale + Offset;
|
||||
vec3 OutTexel = vec3(ShiftedRed, ShiftedGrn, ShiftedBlu) * u_scale.xyz + u_offset.xyz;
|
||||
|
||||
// Saturation
|
||||
vec3 Grayscale = vec3(0.299f, 0.587f, 0.114f);
|
||||
vec3 Grayscale = vec3(0.299, 0.587, 0.114);
|
||||
float OutLuma = dot(OutTexel, Grayscale);
|
||||
vec3 OutChroma = OutTexel - OutLuma;
|
||||
vec3 Saturated = OutLuma + OutChroma * Saturation;
|
||||
vec3 Saturated = OutLuma + OutChroma * u_saturation.x;
|
||||
|
||||
FragColor = vec4(Saturated, BaseTexel.a);
|
||||
}
|
||||
|
@ -12,65 +12,59 @@ layout(push_constant) uniform Push
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
vec3 ConvergeX = vec3(global.converge_x_r, global.converge_x_g, global.converge_x_b);
|
||||
vec3 ConvergeY = vec3(global.converge_y_r, global.converge_y_g, global.converge_y_b);
|
||||
vec3 RadialConvergeX = vec3(global.radial_conv_x_r, global.radial_conv_x_g, global.radial_conv_x_b);
|
||||
vec3 RadialConvergeY = vec3(global.radial_conv_y_r, global.radial_conv_y_g, global.radial_conv_y_b);
|
||||
#define u_source_size params.OutputSize
|
||||
|
||||
vec4 u_converge_red = vec4(global.converge_x_r, global.converge_y_r, 0.,0.);
|
||||
vec4 u_converge_green = vec4(global.converge_x_g, global.converge_y_g, 0.,0.);
|
||||
vec4 u_converge_blue = vec4(global.converge_x_b, global.converge_y_b, 0.,0.);
|
||||
vec4 u_radial_converge_red = vec4(global.radial_conv_x_r, global.radial_conv_y_r, 0.,0.);
|
||||
vec4 u_radial_converge_green = vec4(global.radial_conv_x_g, global.radial_conv_y_g, 0.,0.);
|
||||
vec4 u_radial_converge_blue = vec4(global.radial_conv_x_b, global.radial_conv_y_b, 0.,0.);
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec3 TexCoordX;
|
||||
layout(location = 1) out vec3 TexCoordY;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
layout(location = 1) out vec2 v_texcoord1;
|
||||
layout(location = 2) out vec2 v_texcoord2;
|
||||
layout(location = 3) out vec2 v_texcoord3;
|
||||
|
||||
#define a_texcoord0 TexCoord.xy
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
|
||||
// imaginary texel dimensions independed from screen dimension, but ratio
|
||||
vec2 TexelDims = vec2(1.0 / 1024.);
|
||||
vec2 half_value = vec2(0.5, 0.5);
|
||||
|
||||
TexCoordX = TexCoord.xxx;
|
||||
TexCoordY = TexCoord.yyy;
|
||||
|
||||
// center coordinates
|
||||
TexCoordX -= 0.5;
|
||||
TexCoordY -= 0.5;
|
||||
|
||||
// radial converge offset to "translate" the most outer pixel as thay would be translated by the linar converge with the same amount
|
||||
vec2 radialConvergeOffset = vec2(2.0);
|
||||
|
||||
// radial converge
|
||||
TexCoordX *= 1.0 + RadialConvergeX * TexelDims.xxx * radialConvergeOffset.xxx;
|
||||
TexCoordY *= 1.0 + RadialConvergeY * TexelDims.yyy * radialConvergeOffset.yyy;
|
||||
|
||||
// un-center coordinates
|
||||
TexCoordX += 0.5;
|
||||
TexCoordY += 0.5;
|
||||
|
||||
// linear converge
|
||||
TexCoordX += ConvergeX * TexelDims.xxx;
|
||||
TexCoordY += ConvergeY * TexelDims.yyy;
|
||||
v_texcoord0 = a_texcoord0;
|
||||
v_texcoord1 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_red.xy ) + half_value + u_converge_red.xy * (vec2(1.0, 1.0) / u_source_size.xy);
|
||||
v_texcoord2 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_green.xy) + half_value + u_converge_green.xy * (vec2(1.0, 1.0) / u_source_size.xy);
|
||||
v_texcoord3 = (a_texcoord0 - half_value) * (1.0 + u_radial_converge_blue.xy ) + half_value + u_converge_blue.xy * (vec2(1.0, 1.0) / u_source_size.xy);
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec3 TexCoordX;
|
||||
layout(location = 1) in vec3 TexCoordY;
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 1) in vec2 v_texcoord1;
|
||||
layout(location = 2) in vec2 v_texcoord2;
|
||||
layout(location = 3) in vec2 v_texcoord3;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define s_tex Source
|
||||
#define v_color0 vec4(1.,1.,1.,1.)
|
||||
|
||||
void main()
|
||||
{
|
||||
float r = texture(DiffuseSampler, vec2(TexCoordX.x, TexCoordY.x)).r;
|
||||
float g = texture(DiffuseSampler, vec2(TexCoordX.y, TexCoordY.y)).g;
|
||||
float b = texture(DiffuseSampler, vec2(TexCoordX.z, TexCoordY.z)).b;
|
||||
float a = texture(s_tex, v_texcoord0).a;
|
||||
float r = texture(s_tex, v_texcoord1).r;
|
||||
float g = texture(s_tex, v_texcoord2).g;
|
||||
float b = texture(s_tex, v_texcoord3).b;
|
||||
|
||||
FragColor = vec4(r, g, b, 1.0);
|
||||
FragColor = vec4(r, g, b, a) * v_color0;
|
||||
}
|
||||
|
75
crt/shaders/mame_hlsl/shaders/mame_defocus.slang
Normal file
75
crt/shaders/mame_hlsl/shaders/mame_defocus.slang
Normal file
@ -0,0 +1,75 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defocus Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define s_tex Source
|
||||
#define v_color0 vec4(1.,1.,1.,1.)
|
||||
|
||||
vec4 u_defocus = vec4(global.defocus_x, global.defocus_y, 0., 0.);
|
||||
|
||||
void main()
|
||||
{
|
||||
// previously this pass was applied two times with offsets of 0.25, 0.5, 0.75, 1.0
|
||||
// now this pass is applied only once with offsets of 0.25, 0.55, 1.0, 1.6 to achieve the same appearance as before till a maximum defocus of 2.0
|
||||
// 0.075x² + 0.225x + 0.25
|
||||
const vec2 Coord1Offset = vec2(-1.60, 0.25);
|
||||
const vec2 Coord2Offset = vec2(-1.00, -0.55);
|
||||
const vec2 Coord3Offset = vec2(-0.55, 1.00);
|
||||
const vec2 Coord4Offset = vec2(-0.25, -1.60);
|
||||
const vec2 Coord5Offset = vec2( 0.25, 1.60);
|
||||
const vec2 Coord6Offset = vec2( 0.55, -1.00);
|
||||
const vec2 Coord7Offset = vec2( 1.00, 0.55);
|
||||
const vec2 Coord8Offset = vec2( 1.60, -0.25);
|
||||
|
||||
// imaginary texel dimensions independed from source and target dimension
|
||||
vec2 TexelDims = vec2(1.0 / 1024.0);
|
||||
|
||||
vec2 DefocusTexelDims = u_defocus.xy * TexelDims.xy;
|
||||
|
||||
vec4 d0 = texture(s_tex, v_texcoord0);
|
||||
vec4 d1 = texture(s_tex, v_texcoord0 + Coord1Offset * DefocusTexelDims);
|
||||
vec4 d2 = texture(s_tex, v_texcoord0 + Coord2Offset * DefocusTexelDims);
|
||||
vec4 d3 = texture(s_tex, v_texcoord0 + Coord3Offset * DefocusTexelDims);
|
||||
vec4 d4 = texture(s_tex, v_texcoord0 + Coord4Offset * DefocusTexelDims);
|
||||
vec4 d5 = texture(s_tex, v_texcoord0 + Coord5Offset * DefocusTexelDims);
|
||||
vec4 d6 = texture(s_tex, v_texcoord0 + Coord6Offset * DefocusTexelDims);
|
||||
vec4 d7 = texture(s_tex, v_texcoord0 + Coord7Offset * DefocusTexelDims);
|
||||
vec4 d8 = texture(s_tex, v_texcoord0 + Coord8Offset * DefocusTexelDims);
|
||||
|
||||
vec4 blurred = (d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8) / 9.0;
|
||||
|
||||
blurred.a = blurred.a + d0.a;
|
||||
|
||||
FragColor = blurred * v_color0;
|
||||
}
|
@ -17,29 +17,40 @@ layout(push_constant) uniform Push
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
#define saturate(c) clamp(c, 0.0, 1.0)
|
||||
#define mul(a,b) (b*a)
|
||||
const int ScreenCount = 1;
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
const float Epsilon = 1.0e-7;
|
||||
const float PI = 3.1415927;
|
||||
const float E = 2.7182817;
|
||||
const float Gelfond = 23.140692; // e^pi (Gelfond constant)
|
||||
const float GelfondSchneider = 2.6651442; // 2^sqrt(2) (Gelfond-Schneider constant)
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
vec4 u_distortion = vec4(global.distortion_amount);
|
||||
vec4 u_cubic_distortion = vec4(global.cubic_distortion_amount);
|
||||
vec4 u_distort_corner = vec4(global.distort_corner_amount);
|
||||
vec4 u_round_corner = vec4(global.round_corner_amount);
|
||||
vec4 u_smooth_border = vec4(global.smooth_border_amount);
|
||||
vec4 u_vignetting = vec4(global.vignette_amount);
|
||||
vec4 u_reflection = vec4(global.reflection_amount);
|
||||
|
||||
#define s_tex Source
|
||||
#define saturate(c) clamp(c, 0., 1.)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
|
||||
float random(vec2 seed)
|
||||
float rand(vec2 seed)
|
||||
{
|
||||
// irrationals for pseudo randomness
|
||||
vec2 i = vec2(Gelfond, GelfondSchneider);
|
||||
vec2 i = vec2(23.140692, 2.6651442); // e^pi (Gelfond constant), 2^sqrt(2) (Gelfond-Schneider constant)
|
||||
|
||||
return fract(cos(dot(seed, i)) * 123456.0);
|
||||
}
|
||||
@ -48,7 +59,7 @@ float random(vec2 seed)
|
||||
float normalizedSigmoid(float n, float k)
|
||||
{
|
||||
// valid for n and k in range of -1.0 and 1.0
|
||||
return (n - n * k) / (k - abs(n) * 2.0 * k + 1);
|
||||
return (n - n * k) / (k - abs(n) * 2.0 * k + 1.0);
|
||||
}
|
||||
|
||||
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
@ -57,41 +68,10 @@ float roundBox(vec2 p, vec2 b, float r)
|
||||
return length(max(abs(p) - b + r, 0.0)) - r;
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
float DistortionAmount = global.distortion_amount; // k - quartic distortion coefficient
|
||||
float CubicDistortionAmount = global.cubic_distortion_amount; // kcube - cubic distortion modifier
|
||||
float DistortCornerAmount = global.distort_corner_amount;
|
||||
float RoundCornerAmount = global.round_corner_amount;
|
||||
float SmoothBorderAmount = global.smooth_border_amount;
|
||||
float VignettingAmount = global.vignette_amount;
|
||||
float ReflectionAmount = global.reflection_amount;
|
||||
vec3 LightReflectionColor = vec3(global.reflection_col_r, global.reflection_col_g, global.reflection_col_b); // color temperature 5.000 Kelvin
|
||||
|
||||
vec2 QuadDims = params.OutputSize.xy;
|
||||
vec2 TargetDims = params.FinalViewportSize.xy;
|
||||
float TargetScale = 1.0;
|
||||
|
||||
float GetNoiseFactor(vec3 n, float random)
|
||||
float GetNoiseFactor(float n, float random)
|
||||
{
|
||||
// smaller n become more noisy
|
||||
return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n.x));
|
||||
return 1.0 + random * max(0.0, 0.25 * pow(2.7182817, -8.0 * n));
|
||||
}
|
||||
|
||||
float GetVignetteFactor(vec2 coord, float amount)
|
||||
@ -99,10 +79,10 @@ float GetVignetteFactor(vec2 coord, float amount)
|
||||
vec2 VignetteCoord = coord;
|
||||
|
||||
float VignetteLength = length(VignetteCoord);
|
||||
float VignetteBlur = (amount * 0.75f) + 0.25;
|
||||
float VignetteBlur = (amount * 0.75) + 0.25;
|
||||
|
||||
// 0.5 full screen fitting circle
|
||||
float VignetteRadius = 1.0f - (amount * 0.25f);
|
||||
float VignetteRadius = 1.0 - (amount * 0.25);
|
||||
float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength);
|
||||
|
||||
return saturate(Vignette);
|
||||
@ -113,12 +93,10 @@ float GetSpotAddend(vec2 coord, float amount)
|
||||
vec2 SpotCoord = coord;
|
||||
|
||||
// upper right quadrant
|
||||
vec2 spotOffset = vec2(-0.25f, 0.25f);
|
||||
vec2 spotOffset = vec2(-0.25, 0.25);
|
||||
|
||||
// normalized screen canvas ratio
|
||||
vec2 CanvasRatio = SwapXY
|
||||
? vec2(1.0f, QuadDims.x / QuadDims.y)
|
||||
: vec2(1.0f, QuadDims.y / QuadDims.x);
|
||||
vec2 CanvasRatio = ((u_swap_xy.x > 0.0) ? vec2(1.0, u_quad_dims.x / u_quad_dims.y) : vec2(1.0, u_quad_dims.y / u_quad_dims.x));
|
||||
|
||||
SpotCoord += spotOffset;
|
||||
SpotCoord *= CanvasRatio;
|
||||
@ -126,13 +104,13 @@ float GetSpotAddend(vec2 coord, float amount)
|
||||
float SpotBlur = amount;
|
||||
|
||||
// 0.5 full screen fitting circle
|
||||
float SpotRadius = amount * 0.75f;
|
||||
float SpotRadius = amount * 0.75;
|
||||
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
|
||||
|
||||
float SigmoidSpot = amount * normalizedSigmoid(Spot, 0.75);
|
||||
|
||||
// increase strength by 100%
|
||||
SigmoidSpot = SigmoidSpot * 2.0f;
|
||||
SigmoidSpot = SigmoidSpot * 2.0;
|
||||
|
||||
return saturate(SigmoidSpot);
|
||||
}
|
||||
@ -143,18 +121,18 @@ float GetBoundsFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothA
|
||||
smoothAmount = min(smoothAmount, radiusAmount);
|
||||
|
||||
float range = min(bounds.x, bounds.y);
|
||||
float amountMinimum = 1.0f / range;
|
||||
float amountMinimum = range > 0.0f ? 1.0f / range : 0.0f;
|
||||
float radius = range * max(radiusAmount, amountMinimum);
|
||||
float smooth_ = 1.0f / (range * max(smoothAmount, amountMinimum * 2.0f));
|
||||
float smooth_val = 1.0f / (range * max(smoothAmount, amountMinimum * 2.0f));
|
||||
|
||||
// compute box
|
||||
float box = roundBox(bounds * (coord * 2.0f), bounds, radius);
|
||||
|
||||
// apply smooth
|
||||
box *= smooth_;
|
||||
box += 1.0f - pow(smooth_ * 0.5f, 0.5f);
|
||||
box *= smooth_val;
|
||||
box += 1.0 - pow(smooth_val * 0.5, 0.5);
|
||||
|
||||
float border = smoothstep(1.0f, 0.0f, box);
|
||||
float border = smoothstep(1.0, 0.0, box);
|
||||
|
||||
return saturate(border);
|
||||
}
|
||||
@ -170,12 +148,10 @@ vec2 GetDistortedCoords(vec2 centerCoord, float amount, float amountCube)
|
||||
|
||||
// compute cubic distortion factor
|
||||
float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y;
|
||||
float f = kcube == 0.0f
|
||||
? 1.0f + r2 * k
|
||||
: 1.0f + r2 * (k + kcube * sqrt(r2));
|
||||
float f = kcube == 0.0 ? 1.0 + r2 * k : 1.0 + r2 * (k + kcube * sqrt(r2));
|
||||
|
||||
// fit screen bounds
|
||||
f /= 1.0f + amount * 0.25f + amountCube * 0.125f;
|
||||
f /= 1.0 + amount * 0.25 + amountCube * 0.125;
|
||||
|
||||
// apply cubic distortion factor
|
||||
centerCoord *= f;
|
||||
@ -186,13 +162,13 @@ vec2 GetDistortedCoords(vec2 centerCoord, float amount, float amountCube)
|
||||
vec2 GetTextureCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5f;
|
||||
coord -= 0.5;
|
||||
|
||||
// distort coordinates
|
||||
coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount);
|
||||
|
||||
// un-center coordinates
|
||||
coord += 0.5f;
|
||||
coord += 0.5;
|
||||
|
||||
return coord;
|
||||
}
|
||||
@ -200,7 +176,7 @@ vec2 GetTextureCoords(vec2 coord, float distortionAmount, float cubicDistortionA
|
||||
vec2 GetQuadCoords(vec2 coord, vec2 scale, float distortionAmount, float cubicDistortionAmount)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5f;
|
||||
coord -= 0.5;
|
||||
|
||||
// apply scale
|
||||
coord *= scale;
|
||||
@ -211,83 +187,101 @@ vec2 GetQuadCoords(vec2 coord, vec2 scale, float distortionAmount, float cubicDi
|
||||
return coord;
|
||||
}
|
||||
|
||||
float noise(vec2 p){
|
||||
vec2 ip = floor(p);
|
||||
vec2 u = fract(p);
|
||||
u = u*u*(3.0-2.0*u);
|
||||
|
||||
float res = mix(
|
||||
mix(rand(ip),rand(ip+vec2(1.0,0.0)),u.x),
|
||||
mix(rand(ip+vec2(0.0,1.0)),rand(ip+vec2(1.0,1.0)),u.x),u.y);
|
||||
return res*res;
|
||||
}
|
||||
|
||||
vec2 noisecoord(vec2 coord){
|
||||
float offset_x = noise(sin(gl_FragCoord.xy) * float(mod(params.FrameCount + 873, 3061.)));
|
||||
float offset_y = noise(cos(gl_FragCoord.yx) * float(mod(params.FrameCount + 2157, 8703.)));
|
||||
return coord + vec2(offset_x, offset_y) * 0.001 * global.noise_amt;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!Distortion)
|
||||
if (!Distortion)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
FragColor = texture(s_tex, v_texcoord0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// image distortion
|
||||
float distortionAmount = DistortionAmount;
|
||||
float cubicDistortionAmount = CubicDistortionAmount > 0.0f
|
||||
? CubicDistortionAmount * 1.1f // cubic distortion need to be a little higher to compensate the quartic distortion
|
||||
: CubicDistortionAmount * 1.2f; // negativ values even more
|
||||
float distortionAmount = u_distortion.x;
|
||||
float cubicDistortionAmount = u_cubic_distortion.x > 0.0
|
||||
? u_cubic_distortion.x * 1.1 // cubic distortion need to be a little higher to compensate the quartic distortion
|
||||
: u_cubic_distortion.x * 1.2; // negativ values even more
|
||||
|
||||
// corner distortion at least by the amount of the image distorition
|
||||
float distortCornerAmount = max(DistortCornerAmount, DistortionAmount + CubicDistortionAmount);
|
||||
float distortCornerAmount = max(u_distort_corner.x, u_distortion.x + u_cubic_distortion.x);
|
||||
|
||||
float roundCornerAmount = RoundCornerAmount * 0.5f;
|
||||
float smoothBorderAmount = SmoothBorderAmount * 0.5f;
|
||||
float roundCornerAmount = u_round_corner.x * 0.5;
|
||||
float smoothBorderAmount = u_smooth_border.x * 0.5;
|
||||
|
||||
vec2 TexelDims = 1.0f / TargetDims;
|
||||
vec2 TexelDims = vec2(1.0 / u_target_dims.x, 1.0 / u_target_dims.y);
|
||||
|
||||
// base-target dimensions (without oversampling)
|
||||
vec2 BaseTargetDims = TargetDims / TargetScale;
|
||||
BaseTargetDims = SwapXY
|
||||
vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy;
|
||||
BaseTargetDims = (u_swap_xy.x > 0.0)
|
||||
? BaseTargetDims.yx
|
||||
: BaseTargetDims.xy;
|
||||
|
||||
// base-target/quad difference scale
|
||||
vec2 BaseTargetQuadScale = (ScreenCount == 1)
|
||||
? BaseTargetDims / QuadDims // keeps the coords inside of the quad bounds of a single screen
|
||||
: vec2(1.0);
|
||||
vec2 BaseTargetQuadScale = (u_screen_count.x > 0.0 && u_screen_count.x < 2.0)
|
||||
? BaseTargetDims / u_quad_dims.xy // keeps the coords inside of the quad bounds of a single screen
|
||||
: vec2(1.0, 1.0);
|
||||
|
||||
// Screen Texture Curvature
|
||||
vec2 BaseCoord = GetTextureCoords(vTexCoord, distortionAmount, cubicDistortionAmount);
|
||||
vec2 BaseCoord = GetTextureCoords(v_texcoord0, distortionAmount, cubicDistortionAmount);
|
||||
BaseCoord = noisecoord(BaseCoord);
|
||||
|
||||
// Screen Quad Curvature
|
||||
vec2 QuadCoord = GetQuadCoords(vTexCoord, BaseTargetQuadScale, distortCornerAmount, 0.0f);
|
||||
/*
|
||||
// clip border
|
||||
if (BaseCoord.x < 0.0f - TexelDims.x || BaseCoord.y < 0.0f - TexelDims.y ||
|
||||
BaseCoord.x > 1.0f + TexelDims.x || BaseCoord.y > 1.0f + TexelDims.y)
|
||||
{
|
||||
// we don't use the clip function, because we don't clear the render target before
|
||||
return vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
*/
|
||||
|
||||
vec2 QuadCoord = GetQuadCoords(v_texcoord0, BaseTargetQuadScale, distortCornerAmount, 0.0);
|
||||
|
||||
// Color
|
||||
vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
|
||||
BaseColor.a = 1.0f;
|
||||
vec4 BaseColor = texture(s_tex, BaseCoord);
|
||||
|
||||
// Vignetting Simulation
|
||||
vec2 VignetteCoord = QuadCoord;
|
||||
// Clamp
|
||||
if (BaseCoord.x > 1.0 + TexelDims.x || BaseCoord.y > 1.0 + TexelDims.y || BaseCoord.x < 0.0 - TexelDims.x || BaseCoord.y < 0.0 - TexelDims.y)
|
||||
{
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vignetting Simulation
|
||||
vec2 VignetteCoord = QuadCoord;
|
||||
|
||||
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
|
||||
BaseColor.rgb *= VignetteFactor;
|
||||
float VignetteFactor = GetVignetteFactor(VignetteCoord, u_vignetting.x);
|
||||
BaseColor.rgb *= VignetteFactor;
|
||||
|
||||
// Light Reflection Simulation
|
||||
vec2 SpotCoord = QuadCoord;
|
||||
// Light Reflection Simulation
|
||||
vec4 LightColor = vec4(1.0, 0.90, 0.80, 1.0); // color temperature 5.000 Kelvin
|
||||
|
||||
vec3 SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount) * LightReflectionColor;
|
||||
BaseColor.rgb += SpotAddend * GetNoiseFactor(SpotAddend, random(SpotCoord));
|
||||
vec2 SpotCoord = QuadCoord;
|
||||
vec2 NoiseCoord = QuadCoord;
|
||||
|
||||
// Round Corners Simulation
|
||||
vec2 RoundCornerCoord = QuadCoord;
|
||||
vec2 RoundCornerBounds = (ScreenCount == 1)
|
||||
? QuadDims // align corners to quad bounds of a single screen
|
||||
: BaseTargetDims; // align corners to target bounds of multiple screens
|
||||
RoundCornerBounds = SwapXY
|
||||
? RoundCornerBounds.yx
|
||||
: RoundCornerBounds.xy;
|
||||
float SpotAddend = GetSpotAddend(SpotCoord, u_reflection.x);
|
||||
float NoiseFactor = GetNoiseFactor(SpotAddend, rand(NoiseCoord));
|
||||
BaseColor += SpotAddend * NoiseFactor * LightColor;
|
||||
|
||||
float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount);
|
||||
BaseColor.rgb *= roundCornerFactor;
|
||||
// Round Corners Simulation
|
||||
vec2 RoundCornerCoord = QuadCoord;
|
||||
vec2 RoundCornerBounds = (u_screen_count.x > 0.0 && u_screen_count.x < 2.0)
|
||||
? u_quad_dims.xy // align corners to screen quad bounds
|
||||
: BaseTargetDims; // align corners to target texture bounds
|
||||
RoundCornerBounds = (u_swap_xy.x > 0.0)
|
||||
? RoundCornerBounds.yx
|
||||
: RoundCornerBounds.xy;
|
||||
|
||||
FragColor = BaseColor;
|
||||
float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount);
|
||||
BaseColor.rgb *= roundCornerFactor;
|
||||
|
||||
FragColor = BaseColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
331
crt/shaders/mame_hlsl/shaders/mame_ntsc_decode.slang
Normal file
331
crt/shaders/mame_hlsl/shaders/mame_ntsc_decode.slang
Normal file
@ -0,0 +1,331 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// NTSC Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
vec4 u_a_value = vec4(global.avalue);
|
||||
vec4 u_b_value = vec4(global.bvalue);
|
||||
vec4 u_cc_value = vec4(global.ccvalue);
|
||||
vec4 u_o_value = vec4(global.ovalue);
|
||||
vec4 u_scan_time = vec4(global.scantime);
|
||||
vec4 u_notch_width = vec4(global.notch_width);
|
||||
vec4 u_y_freq_response = vec4(global.yfreqresponse);
|
||||
vec4 u_i_freq_response = vec4(global.ifreqresponse);
|
||||
vec4 u_q_freq_response = vec4(global.qfreqresponse);
|
||||
vec4 u_jitter_offset = vec4(global.jitter_offset);
|
||||
|
||||
vec4 u_jitter_amount = vec4(global.jitter);
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D Original;
|
||||
|
||||
#define s_tex Source
|
||||
#define s_screen Source
|
||||
#define v_color0 vec4(1.,1.,1.,1.)
|
||||
|
||||
////// Sticking with old NTSC decode because it actually works ///////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float PI = 3.1415927f;
|
||||
const float PI2 = PI * 2.0f;
|
||||
|
||||
const vec4 YDot = vec4(0.299f, 0.587f, 0.114f, 0.0f);
|
||||
const vec4 IDot = vec4(0.595716f, -0.274453f, -0.321263f, 0.0f);
|
||||
const vec4 QDot = vec4(0.211456f, -0.522591f, 0.311135f, 0.0f);
|
||||
|
||||
const vec3 RDot = vec3(1.0f, 0.956f, 0.621f);
|
||||
const vec3 GDot = vec3(1.0f, -0.272f, -0.647f);
|
||||
const vec3 BDot = vec3(1.0f, -1.106f, 1.703f);
|
||||
|
||||
const vec4 OffsetX = vec4(0.0f, 0.25f, 0.50f, 0.75f);
|
||||
const vec4 NotchOffset = vec4(0.0f, 1.0f, 2.0f, 3.0f);
|
||||
|
||||
const int SampleCount = 64;
|
||||
const int HalfSampleCount = SampleCount / 2;
|
||||
|
||||
float AValue = global.avalue;
|
||||
float BValue = global.bvalue;
|
||||
float CCValue = global.ccvalue;
|
||||
float OValue = global.ovalue;
|
||||
float PValue = global.pvalue;
|
||||
float ScanTime = global.scantime;
|
||||
|
||||
float NotchHalfWidth = global.notch_width / 2.0;
|
||||
float YFreqResponse = global.yfreqresponse;
|
||||
float IFreqResponse = global.ifreqresponse;
|
||||
float QFreqResponse = global.qfreqresponse;
|
||||
float SignalOffset = 0.0;//global.jitter_offset;
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!NTSCSignal)
|
||||
{
|
||||
FragColor = texture(s_tex, v_texcoord0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 BaseTexel = texture(s_tex, v_texcoord0);
|
||||
|
||||
float TimePerSample = ScanTime / (u_source_dims.x * 4.0f);
|
||||
|
||||
float Fc_y1 = (CCValue - NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y2 = (CCValue + NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y3 = YFreqResponse * TimePerSample;
|
||||
float Fc_i = IFreqResponse * TimePerSample;
|
||||
float Fc_q = QFreqResponse * TimePerSample;
|
||||
float Fc_i_2 = Fc_i * 2.0f;
|
||||
float Fc_q_2 = Fc_q * 2.0f;
|
||||
float Fc_y1_2 = Fc_y1 * 2.0f;
|
||||
float Fc_y2_2 = Fc_y2 * 2.0f;
|
||||
float Fc_y3_2 = Fc_y3 * 2.0f;
|
||||
float Fc_i_pi2 = Fc_i * PI2;
|
||||
float Fc_q_pi2 = Fc_q * PI2;
|
||||
float Fc_y1_pi2 = Fc_y1 * PI2;
|
||||
float Fc_y2_pi2 = Fc_y2 * PI2;
|
||||
float Fc_y3_pi2 = Fc_y3 * PI2;
|
||||
float PI2Length = PI2 / SampleCount;
|
||||
|
||||
float W = PI2 * CCValue * ScanTime;
|
||||
float WoPI = W / PI;
|
||||
|
||||
float HOffset = (BValue + SignalOffset) / WoPI;
|
||||
float VScale = (AValue * u_source_dims.y) / WoPI;
|
||||
|
||||
vec4 YAccum = vec4(0.0);
|
||||
vec4 IAccum = vec4(0.0);
|
||||
vec4 QAccum = vec4(0.0);
|
||||
|
||||
vec4 Cy = v_texcoord0.yyyy;
|
||||
vec4 VPosition = Cy;
|
||||
|
||||
for (float i = 0; i < SampleCount; i += 4.0f)
|
||||
{
|
||||
float n = i - HalfSampleCount;
|
||||
vec4 n4 = n + NotchOffset;
|
||||
|
||||
vec4 Cx = v_texcoord0.x + (n4 * 0.25f) / u_source_dims.x;
|
||||
vec4 HPosition = Cx;
|
||||
|
||||
vec4 C = texture(Source, vec2(Cx.r, Cy.r));
|
||||
|
||||
vec4 T = HPosition + HOffset + VPosition * VScale;
|
||||
vec4 WT = W * T + OValue;
|
||||
|
||||
vec4 SincKernel = 0.54f + 0.46f * cos(PI2Length * n4);
|
||||
|
||||
vec4 SincYIn1 = Fc_y1_pi2 * n4;
|
||||
vec4 SincYIn2 = Fc_y2_pi2 * n4;
|
||||
vec4 SincYIn3 = Fc_y3_pi2 * n4;
|
||||
vec4 SincIIn = Fc_i_pi2 * n4;
|
||||
vec4 SincQIn = Fc_q_pi2 * n4;
|
||||
|
||||
vec4 SincY1, SincY2, SincY3;
|
||||
|
||||
SincY1.x = (SincYIn1.x != 0.0f) ? sin(SincYIn1.x) / SincYIn1.x : 1.0f;
|
||||
SincY1.y = (SincYIn1.y != 0.0f) ? sin(SincYIn1.y) / SincYIn1.y : 1.0f;
|
||||
SincY1.z = (SincYIn1.z != 0.0f) ? sin(SincYIn1.z) / SincYIn1.z : 1.0f;
|
||||
SincY1.w = (SincYIn1.w != 0.0f) ? sin(SincYIn1.w) / SincYIn1.w : 1.0f;
|
||||
SincY2.x = (SincYIn2.x != 0.0f) ? sin(SincYIn2.x) / SincYIn2.x : 1.0f;
|
||||
SincY2.y = (SincYIn2.y != 0.0f) ? sin(SincYIn2.y) / SincYIn2.y : 1.0f;
|
||||
SincY2.z = (SincYIn2.z != 0.0f) ? sin(SincYIn2.z) / SincYIn2.z : 1.0f;
|
||||
SincY2.w = (SincYIn2.w != 0.0f) ? sin(SincYIn2.w) / SincYIn2.w : 1.0f;
|
||||
SincY3.x = (SincYIn3.x != 0.0f) ? sin(SincYIn3.x) / SincYIn3.x : 1.0f;
|
||||
SincY3.y = (SincYIn3.y != 0.0f) ? sin(SincYIn3.y) / SincYIn3.y : 1.0f;
|
||||
SincY3.z = (SincYIn3.z != 0.0f) ? sin(SincYIn3.z) / SincYIn3.z : 1.0f;
|
||||
SincY3.w = (SincYIn3.w != 0.0f) ? sin(SincYIn3.w) / SincYIn3.w : 1.0f;
|
||||
|
||||
vec4 IdealY, IdealI, IdealQ;
|
||||
|
||||
IdealY = (Fc_y1_2 * SincY1 - Fc_y2_2 * SincY2) + Fc_y3_2 * SincY3;
|
||||
IdealI.x = Fc_i_2 * (SincIIn.x != 0.0f ? sin(SincIIn.x) / SincIIn.x : 1.0f);
|
||||
IdealI.y = Fc_i_2 * (SincIIn.y != 0.0f ? sin(SincIIn.y) / SincIIn.y : 1.0f);
|
||||
IdealI.z = Fc_i_2 * (SincIIn.z != 0.0f ? sin(SincIIn.z) / SincIIn.z : 1.0f);
|
||||
IdealI.w = Fc_i_2 * (SincIIn.w != 0.0f ? sin(SincIIn.w) / SincIIn.w : 1.0f);
|
||||
IdealQ.x = Fc_q_2 * (SincQIn.x != 0.0f ? sin(SincQIn.x) / SincQIn.x : 1.0f);
|
||||
IdealQ.y = Fc_q_2 * (SincQIn.y != 0.0f ? sin(SincQIn.y) / SincQIn.y : 1.0f);
|
||||
IdealQ.z = Fc_q_2 * (SincQIn.z != 0.0f ? sin(SincQIn.z) / SincQIn.z : 1.0f);
|
||||
IdealQ.w = Fc_q_2 * (SincQIn.w != 0.0f ? sin(SincQIn.w) / SincQIn.w : 1.0f);
|
||||
|
||||
vec4 FilterY = SincKernel * IdealY;
|
||||
vec4 FilterI = SincKernel * IdealI;
|
||||
vec4 FilterQ = SincKernel * IdealQ;
|
||||
|
||||
YAccum = YAccum + C * FilterY;
|
||||
IAccum = IAccum + C * cos(WT) * FilterI;
|
||||
QAccum = QAccum + C * sin(WT) * FilterQ;
|
||||
}
|
||||
|
||||
vec3 YIQ = vec3(
|
||||
(YAccum.r + YAccum.g + YAccum.b + YAccum.a),
|
||||
(IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0f,
|
||||
(QAccum.r + QAccum.g + QAccum.b + QAccum.a) * 2.0f);
|
||||
|
||||
vec3 RGB = vec3(
|
||||
dot(YIQ, RDot),
|
||||
dot(YIQ, GDot),
|
||||
dot(YIQ, BDot));
|
||||
|
||||
FragColor = vec4(RGB, BaseTexel.a);
|
||||
}
|
||||
}
|
||||
|
||||
////// new version included for future debugging purposes ///////////
|
||||
/*
|
||||
void main()
|
||||
{
|
||||
vec4 BaseTexel = texture(s_screen, v_texcoord0.xy);
|
||||
|
||||
vec4 zero = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 quarter = vec4(0.25, 0.25, 0.25, 0.25);
|
||||
vec4 onehalf = vec4(0.5, 0.5, 0.5, 0.5);
|
||||
vec4 one = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
vec4 two = vec4(2.0, 2.0, 2.0, 2.0);
|
||||
vec4 four = vec4(4.0, 4.0, 4.0, 4.0);
|
||||
int iSampleCount = 64;
|
||||
vec4 SampleCount = vec4(64.0, 64.0, 64.0, 64.0);
|
||||
vec4 HalfSampleCount = SampleCount / two;
|
||||
|
||||
vec4 TimePerSample = u_scan_time.xxxx / (u_source_dims.xxxx * four);
|
||||
|
||||
vec4 PI = vec4(3.1415927, 3.1415927, 3.1415927, 3.1415927);
|
||||
vec4 PI2 = vec4(6.2831854, 6.2831854, 6.2831854, 6.2831854);
|
||||
|
||||
vec4 Fc_y1 = (u_cc_value.xxxx - u_notch_width.xxxx * onehalf) * TimePerSample;
|
||||
vec4 Fc_y2 = (u_cc_value.xxxx + u_notch_width.xxxx * onehalf) * TimePerSample;
|
||||
vec4 Fc_y3 = u_y_freq_response.xxxx * TimePerSample;
|
||||
vec4 Fc_i = u_i_freq_response.xxxx * TimePerSample;
|
||||
vec4 Fc_q = u_q_freq_response.xxxx * TimePerSample;
|
||||
vec4 Fc_i_2 = Fc_i * two;
|
||||
vec4 Fc_q_2 = Fc_q * two;
|
||||
vec4 Fc_y1_2 = Fc_y1 * two;
|
||||
vec4 Fc_y2_2 = Fc_y2 * two;
|
||||
vec4 Fc_y3_2 = Fc_y3 * two;
|
||||
vec4 Fc_i_pi2 = Fc_i * PI2;
|
||||
vec4 Fc_q_pi2 = Fc_q * PI2;
|
||||
vec4 Fc_y1_pi2 = Fc_y1 * PI2;
|
||||
vec4 Fc_y2_pi2 = Fc_y2 * PI2;
|
||||
vec4 Fc_y3_pi2 = Fc_y3 * PI2;
|
||||
vec4 PI2Length = PI2 / SampleCount;
|
||||
|
||||
vec4 W = PI2 * u_cc_value.xxxx * u_scan_time.xxxx;
|
||||
vec4 WoPI = W / PI;
|
||||
|
||||
vec4 HOffset = (u_b_value.xxxx + u_jitter_amount.xxxx * u_jitter_offset.xxxx) / WoPI;
|
||||
vec4 VScale = (u_a_value.xxxx * u_source_dims.yyyy) / WoPI;
|
||||
|
||||
vec4 YAccum = vec4(0.0);
|
||||
vec4 IAccum = vec4(0.0);
|
||||
vec4 QAccum = vec4(0.0);
|
||||
|
||||
vec4 Cy = v_texcoord0.yyyy;
|
||||
vec4 VPosition = Cy;
|
||||
|
||||
vec4 n = vec4(0.0);
|
||||
vec4 n4 = vec4(0.0);
|
||||
vec4 Cx = vec4(0.0);
|
||||
vec4 HPosition = vec4(0.0);
|
||||
vec4 C = vec4(0.0);
|
||||
vec4 T = vec4(0.0);
|
||||
vec4 WT = vec4(0.0);
|
||||
vec4 SincKernel = vec4(0.0);
|
||||
vec4 SincYIn1 = vec4(0.0);
|
||||
vec4 SincYIn2 = vec4(0.0);
|
||||
vec4 SincYIn3 = vec4(0.0);
|
||||
vec4 SincIIn = vec4(0.0);
|
||||
vec4 SincQIn = vec4(0.0);
|
||||
vec4 SincY1 = vec4(0.0);
|
||||
vec4 SincY2 = vec4(0.0);
|
||||
vec4 SincY3 = vec4(0.0);
|
||||
vec4 IdealY = vec4(0.0);
|
||||
vec4 IdealI = vec4(0.0);
|
||||
vec4 IdealQ = vec4(0.0);
|
||||
vec4 FilterY = vec4(0.0);
|
||||
vec4 FilterI = vec4(0.0);
|
||||
vec4 FilterQ = vec4(0.0);
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
i += 4;
|
||||
n = vec4(i, i, i, i) - vec4(32.0, 32.0, 32.0, 32.0);
|
||||
n4 = n + vec4(0.0, 1.0, 2.0, 3.0);
|
||||
|
||||
Cx = v_texcoord0.xxxx + (n4 * quarter) / u_source_dims.xxxx;
|
||||
HPosition = Cx;
|
||||
|
||||
C = texture(s_tex, vec2(Cx.x, Cy.x));
|
||||
|
||||
T = HPosition + HOffset + VPosition * VScale;
|
||||
WT = W * T + u_o_value.xxxx;
|
||||
|
||||
SincKernel.rgb = vec4(0.54, 0.54, 0.54, 0.54).rgb + vec4(0.46, 0.46, 0.46, 0.46).rgb * cos(PI2Length * n4).rgb;
|
||||
// SincKernel.a = anything nonzero, we get NaN
|
||||
|
||||
SincYIn1 = Fc_y1_pi2 * n4;
|
||||
SincYIn2 = Fc_y2_pi2 * n4;
|
||||
SincYIn3 = Fc_y3_pi2 * n4;
|
||||
SincIIn = Fc_i_pi2 * n4;
|
||||
SincQIn = Fc_q_pi2 * n4;
|
||||
|
||||
SincY1 = (SincYIn1 != zero) ? sin(SincYIn1) / SincYIn1 : one;
|
||||
SincY2 = (SincYIn2 != zero) ? sin(SincYIn2) / SincYIn2 : one;
|
||||
SincY3 = (SincYIn3 != zero) ? sin(SincYIn3) / SincYIn3 : one;
|
||||
|
||||
IdealY = (Fc_y1_2 * SincY1 - Fc_y2_2 * SincY2) + Fc_y3_2 * SincY3;
|
||||
IdealI = Fc_i_2 * (SincIIn != zero ? sin(SincIIn) / SincIIn : one);
|
||||
IdealQ = Fc_q_2 * (SincQIn != zero ? sin(SincQIn) / SincQIn : one);
|
||||
|
||||
FilterY = SincKernel * IdealY;
|
||||
FilterI = SincKernel * IdealI;
|
||||
FilterQ = SincKernel * IdealQ;
|
||||
|
||||
YAccum = YAccum + C * FilterY;
|
||||
IAccum = IAccum + C * cos(WT) * FilterI;
|
||||
QAccum = QAccum + C * sin(WT) * FilterQ;
|
||||
}
|
||||
|
||||
vec3 YIQ = vec3(
|
||||
(YAccum.r + YAccum.g + YAccum.b + YAccum.a),
|
||||
(IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0,
|
||||
(QAccum.r + QAccum.g + QAccum.b + QAccum.a) * 2.0);
|
||||
|
||||
vec3 RGB = vec3(
|
||||
dot(YIQ, vec3(1.0, 0.956, 0.621)),
|
||||
dot(YIQ, vec3(1.0, -0.272, -0.647)),
|
||||
dot(YIQ, vec3(1.0, -1.106, 1.703)));
|
||||
|
||||
// RGB obviously contains a NaN somewhere along the line! Returns black if vec4 etc. are included, white if just vec4(1.0)
|
||||
FragColor = vec4(RGB, BaseTexel.a) * v_color0;
|
||||
}
|
||||
*/
|
114
crt/shaders/mame_hlsl/shaders/mame_ntsc_encode.slang
Normal file
114
crt/shaders/mame_hlsl/shaders/mame_ntsc_encode.slang
Normal file
@ -0,0 +1,114 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// NTSC Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
vec4 u_a_value = vec4(global.avalue);
|
||||
vec4 u_b_value = vec4(global.bvalue);
|
||||
vec4 u_cc_value = vec4(global.ccvalue);
|
||||
vec4 u_p_value = vec4(global.pvalue);
|
||||
vec4 u_scan_time = vec4(global.scantime);
|
||||
vec4 u_jitter_offset = vec4(global.jitter_offset);
|
||||
|
||||
vec4 u_jitter_amount = vec4(global.jitter);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float PI = 3.1415927f;
|
||||
const float PI2 = PI * 2.0f;
|
||||
|
||||
const vec4 YDot = vec4(0.299f, 0.587f, 0.114f, 0.0f);
|
||||
const vec4 IDot = vec4(0.595716f, -0.274453f, -0.321263f, 0.0f);
|
||||
const vec4 QDot = vec4(0.211456f, -0.522591f, 0.311135f, 0.0f);
|
||||
|
||||
const vec3 RDot = vec3(1.0f, 0.956f, 0.621f);
|
||||
const vec3 GDot = vec3(1.0f, -0.272f, -0.647f);
|
||||
const vec3 BDot = vec3(1.0f, -1.106f, 1.703f);
|
||||
|
||||
const vec4 OffsetX = vec4(0.0f, 0.25f, 0.50f, 0.75f);
|
||||
const vec4 NotchOffset = vec4(0.0f, 1.0f, 2.0f, 3.0f);
|
||||
|
||||
const int SampleCount = 64;
|
||||
const int HalfSampleCount = SampleCount / 2;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define s_tex Source
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!NTSCSignal)
|
||||
{
|
||||
FragColor = texture(s_tex, v_texcoord0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec2 PValueSourceTexel = vec2(u_p_value.x, 0.0) / u_source_dims.xy;
|
||||
|
||||
vec2 C0 = v_texcoord0 + PValueSourceTexel * vec2(0.0, 0.0);
|
||||
vec2 C1 = v_texcoord0 + PValueSourceTexel * vec2(0.25, 0.0);
|
||||
vec2 C2 = v_texcoord0 + PValueSourceTexel * vec2(0.5, 0.0);
|
||||
vec2 C3 = v_texcoord0 + PValueSourceTexel * vec2(0.75, 0.0);
|
||||
vec4 Cx = vec4(C0.x, C1.x, C2.x, C3.x);
|
||||
vec4 Cy = vec4(C0.y, C1.y, C2.y, C3.y);
|
||||
vec4 Texel0 = texture(s_tex, C0);
|
||||
vec4 Texel1 = texture(s_tex, C1);
|
||||
vec4 Texel2 = texture(s_tex, C2);
|
||||
vec4 Texel3 = texture(s_tex, C3);
|
||||
|
||||
vec4 HPosition = Cx;
|
||||
vec4 VPosition = Cy;
|
||||
|
||||
const vec4 YDot = vec4(0.299, 0.587, 0.114, 0.0);
|
||||
const vec4 IDot = vec4(0.595716, -0.274453, -0.321263, 0.0);
|
||||
const vec4 QDot = vec4(0.211456, -0.522591, 0.311135, 0.0);
|
||||
vec4 Y = vec4(dot(Texel0, YDot), dot(Texel1, YDot), dot(Texel2, YDot), dot(Texel3, YDot));
|
||||
vec4 I = vec4(dot(Texel0, IDot), dot(Texel1, IDot), dot(Texel2, IDot), dot(Texel3, IDot));
|
||||
vec4 Q = vec4(dot(Texel0, QDot), dot(Texel1, QDot), dot(Texel2, QDot), dot(Texel3, QDot));
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float PI2 = 6.2831854;
|
||||
|
||||
float W = PI2 * u_cc_value.x * u_scan_time.x;
|
||||
float WoPI = W / PI;
|
||||
|
||||
float HOffset = (u_a_value.x + u_jitter_amount.x * u_jitter_offset.x) / WoPI;
|
||||
float VScale = (u_b_value.x * u_source_dims.y) / WoPI;
|
||||
|
||||
vec4 T = HPosition + vec4(HOffset, HOffset, HOffset, HOffset) + VPosition * vec4(VScale, VScale, VScale, VScale);
|
||||
vec4 TW = T * W;
|
||||
|
||||
FragColor = Y + I * cos(TW) + Q * sin(TW);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
{
|
||||
mat4 MVP;
|
||||
// effect toggles and multi
|
||||
float bloomtoggle;
|
||||
// float bloomtoggle;
|
||||
float ntscsignal;
|
||||
float scanlinetoggle;
|
||||
float chromatoggle;
|
||||
@ -15,19 +15,19 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
// bloom params
|
||||
float bloomblendmode;
|
||||
// float vectorscreen;
|
||||
float bloomscale;
|
||||
float bloomoverdrive_r;
|
||||
float bloomoverdrive_g;
|
||||
float bloomoverdrive_b;
|
||||
float level0weight;
|
||||
float level1weight;
|
||||
float level2weight;
|
||||
float level3weight;
|
||||
float level4weight;
|
||||
float level5weight;
|
||||
float level6weight;
|
||||
float level7weight;
|
||||
float level8weight;
|
||||
// float bloomscale;
|
||||
// float bloomoverdrive_r;
|
||||
// float bloomoverdrive_g;
|
||||
// float bloomoverdrive_b;
|
||||
// float level0weight;
|
||||
// float level1weight;
|
||||
// float level2weight;
|
||||
// float level3weight;
|
||||
// float level4weight;
|
||||
// float level5weight;
|
||||
// float level6weight;
|
||||
// float level7weight;
|
||||
// float level8weight;
|
||||
// post params
|
||||
float mask_width;
|
||||
float mask_height;
|
||||
@ -61,15 +61,21 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
float ovalue;
|
||||
float pvalue;
|
||||
float scantime;
|
||||
float notchhalfwidth;
|
||||
float notch_width;
|
||||
float yfreqresponse;
|
||||
float ifreqresponse;
|
||||
float qfreqresponse;
|
||||
float signaloffset;
|
||||
float jitter_offset;
|
||||
// color params
|
||||
float col_red;
|
||||
float col_grn;
|
||||
float col_blu;
|
||||
float col_rr;
|
||||
float col_rg;
|
||||
float col_rb;
|
||||
float col_gr;
|
||||
float col_gg;
|
||||
float col_gb;
|
||||
float col_br;
|
||||
float col_bg;
|
||||
float col_bb;
|
||||
float col_offset_x;
|
||||
float col_offset_y;
|
||||
float col_offset_z;
|
||||
@ -98,11 +104,12 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
float scanlineoffset;
|
||||
float scanlinebrightscale;
|
||||
float scanlinebrightoffset;
|
||||
float scanline_jitter_amount;
|
||||
// defocus params
|
||||
float defocus_x;
|
||||
float defocus_y;
|
||||
// phosphor params
|
||||
float deltatime;
|
||||
float time;
|
||||
float phosphor_r;
|
||||
float phosphor_g;
|
||||
float phosphor_b;
|
||||
@ -125,9 +132,14 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
float smooth_border_amount;
|
||||
float vignette_amount;
|
||||
float reflection_amount;
|
||||
float reflection_col_r;
|
||||
float reflection_col_g;
|
||||
float reflection_col_b;
|
||||
// float reflection_col_r;
|
||||
// float reflection_col_g;
|
||||
// float reflection_col_b;
|
||||
float jitter;
|
||||
float humbar_hertz_rate;
|
||||
float prescale;
|
||||
float scanline_crawl;
|
||||
float noise_amt;
|
||||
// vector params
|
||||
// float timeratio;
|
||||
// float timescale;
|
||||
@ -141,58 +153,61 @@ layout(std140, set = 0, binding = 0) uniform UBO
|
||||
bool NTSCSignal = bool(global.ntscsignal);
|
||||
#pragma parameter scanlinetoggle "Scanline Toggle" 1.0 0.0 1.0 1.0
|
||||
bool ScanlineToggle = bool(global.scanlinetoggle);
|
||||
#pragma parameter bloomtoggle "Bloom Enable" 0.0 0.0 1.0 1.0
|
||||
bool BloomToggle = bool(global.bloomtoggle);
|
||||
//#pragma parameter bloomtoggle "Bloom Enable" 0.0 0.0 1.0 1.0
|
||||
//bool BloomToggle = bool(global.bloomtoggle);
|
||||
#pragma parameter chromatoggle "Chromaticity Toggle" 0.0 0.0 1.0 1.0
|
||||
bool Chromaticity = bool(global.chromatoggle);
|
||||
#pragma parameter distortiontoggle "Distortion Toggle" 0.0 0.0 1.0 1.0
|
||||
bool Distortion = bool(global.distortiontoggle);
|
||||
#pragma parameter phosphortoggle "Phosphor Toggle" 0.0 0.0 1.0 1.0
|
||||
bool Passthrough = !bool(global.phosphortoggle);
|
||||
#pragma parameter screenscale_x "Screen Scale X" 1.0 0.5 3.0 0.01
|
||||
#pragma parameter screenscale_y "Screen Scale Y" 1.0 0.5 3.0 0.01
|
||||
#pragma parameter screenscale_x "Screen Scale X" 0.0 -3.0 3.0 0.005
|
||||
#pragma parameter screenscale_y "Screen Scale Y" 0.0 -3.0 3.0 0.005
|
||||
vec2 ScreenScale = vec2(global.screenscale_x, global.screenscale_y);
|
||||
//#pragma parameter vectorscreen "Vector Screen Mode" 0.0 0.0 1.0 1.0 // TODO/FIXME
|
||||
const float vectorscreen = 0.0;
|
||||
bool VectorScreen = bool(vectorscreen);
|
||||
#pragma parameter jitter "Scanline Jitter (OFF/ON/AUTO)" 0.0 0.0 2.0 1.0
|
||||
#pragma parameter scanline_crawl "Scanline Crawl" 0.0 0.0 1.0 1.0
|
||||
|
||||
#pragma parameter screenoffset_x "Screen Offset X" 0.0 -1.0 1.0 0.005
|
||||
#pragma parameter screenoffset_y "Screen Offset Y" 0.0 -1.0 1.0 0.005
|
||||
#pragma parameter screenoffset_x "Screen Offset X" 0.0 -1.0 1.0 0.001
|
||||
#pragma parameter screenoffset_y "Screen Offset Y" 0.0 -1.0 1.0 0.001
|
||||
vec2 ScreenOffset = vec2(global.screenoffset_x, global.screenoffset_y);
|
||||
#pragma parameter swapxy "Swap X and Y" 0.0 0.0 1.0 1.0
|
||||
bool SwapXY = bool(global.swapxy);
|
||||
|
||||
// Bloom Pass
|
||||
#pragma parameter bloomblendmode "Bloom Blend Mode" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter bloomscale "Bloom Scale" 0.33 0.0 1.0 0.01
|
||||
#pragma parameter bloomoverdrive_r "Bloom Overdrive R" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter bloomoverdrive_g "Bloom Overdrive G" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter bloomoverdrive_b "Bloom Overdrive B" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter level0weight "Bloom Level 0 Weight" 0.64 0.0 1.0 0.01
|
||||
#pragma parameter level1weight "Bloom Level 1 Weight" 0.64 0.0 1.0 0.01
|
||||
#pragma parameter level2weight "Bloom Level 2 Weight" 0.32 0.0 1.0 0.01
|
||||
#pragma parameter level3weight "Bloom Level 3 Weight" 0.16 0.0 1.0 0.01
|
||||
#pragma parameter level4weight "Bloom Level 4 Weight" 0.08 0.0 1.0 0.01
|
||||
#pragma parameter level5weight "Bloom Level 5 Weight" 0.06 0.0 1.0 0.01
|
||||
#pragma parameter level6weight "Bloom Level 6 Weight" 0.04 0.0 1.0 0.01
|
||||
#pragma parameter level7weight "Bloom Level 7 Weight" 0.02 0.0 1.0 0.01
|
||||
#pragma parameter level8weight "Bloom Level 8 Weight" 0.01 0.0 1.0 0.01
|
||||
//#pragma parameter bloomblendmode "Bloom Blend Mode" 0.0 0.0 1.0 1.0
|
||||
//#pragma parameter bloomscale "Bloom Scale" 0.33 0.0 1.0 0.01
|
||||
//#pragma parameter bloomoverdrive_r "Bloom Overdrive R" 1.0 0.0 2.0 0.01
|
||||
//#pragma parameter bloomoverdrive_g "Bloom Overdrive G" 1.0 0.0 2.0 0.01
|
||||
//#pragma parameter bloomoverdrive_b "Bloom Overdrive B" 1.0 0.0 2.0 0.01
|
||||
//#pragma parameter level0weight "Bloom Level 0 Weight" 0.64 0.0 1.0 0.01
|
||||
//#pragma parameter level1weight "Bloom Level 1 Weight" 0.64 0.0 1.0 0.01
|
||||
//#pragma parameter level2weight "Bloom Level 2 Weight" 0.32 0.0 1.0 0.01
|
||||
//#pragma parameter level3weight "Bloom Level 3 Weight" 0.16 0.0 1.0 0.01
|
||||
//#pragma parameter level4weight "Bloom Level 4 Weight" 0.08 0.0 1.0 0.01
|
||||
//#pragma parameter level5weight "Bloom Level 5 Weight" 0.06 0.0 1.0 0.01
|
||||
//#pragma parameter level6weight "Bloom Level 6 Weight" 0.04 0.0 1.0 0.01
|
||||
//#pragma parameter level7weight "Bloom Level 7 Weight" 0.02 0.0 1.0 0.01
|
||||
//#pragma parameter level8weight "Bloom Level 8 Weight" 0.01 0.0 1.0 0.01
|
||||
|
||||
// Post Pass
|
||||
#pragma parameter humbaralpha "Hum Bar Alpha" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter backcolor_r "Back Color R" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter backcolor_g "Back Color G" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter backcolor_b "Back Color B" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter shadowtilemode "Mask Tiling Mode" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter shadowalpha "Mask Alpha" 0.3 0.0 1.0 0.01
|
||||
#pragma parameter shadowcount_x "Mask Tile Size X" 6.0 1.0 32.0 1.0
|
||||
#pragma parameter shadowcount_y "Mask Tile Size Y" 6.0 1.0 32.0 1.0
|
||||
#pragma parameter shadowuv_x "Mask UV X" 0.25 0.0 1.0 0.01
|
||||
#pragma parameter shadowuv_y "Mask UV Y" 0.25 0.0 1.0 0.01
|
||||
#pragma parameter mask_width "Mask Texture Width" 32.0 0.0 256.0 16.0
|
||||
#pragma parameter mask_height "Mask Texture Height" 32.0 0.0 256.0 16.0
|
||||
#pragma parameter mask_offset_x "Mask Offset X" 0.0 -10.0 10.0 0.1
|
||||
#pragma parameter mask_offset_y "Mask Offset Y" 0.0 -10.0 10.0 0.1
|
||||
#pragma parameter humbaralpha "Hum Bar Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter humbar_hertz_rate "Hum Bar Frequency" 0.001 0.0 1.0 0.001
|
||||
//#pragma parameter backcolor_r "Back Color R" 0.0 0.0 1.0 0.01
|
||||
//#pragma parameter backcolor_g "Back Color G" 0.0 0.0 1.0 0.01
|
||||
//#pragma parameter backcolor_b "Back Color B" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter shadowtilemode "Shadow Mask Tile Mode" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter shadowalpha "Shadow Mask Amount" 0.5 0.0 1.0 0.01
|
||||
#pragma parameter shadowcount_x "Shadow Mask Pixel Count X" 12.0 1.0 128.0 1.0
|
||||
#pragma parameter shadowcount_y "Shadow Mask Pixel Count Y" 12.0 1.0 128.0 1.0
|
||||
#pragma parameter shadowuv_x "Shadow Mask UV Size X" 0.5 0.0 1.0 0.001
|
||||
#pragma parameter shadowuv_y "Shadow Mask UV Size Y" 0.5 0.0 1.0 0.001
|
||||
//#pragma parameter mask_width "Mask Texture Width" 32.0 0.0 256.0 16.0
|
||||
//#pragma parameter mask_height "Mask Texture Height" 32.0 0.0 256.0 16.0
|
||||
#pragma parameter mask_offset_x "Mask Offset X" 0.0 0.0 10.0 0.001
|
||||
#pragma parameter mask_offset_y "Mask Offset Y" 0.0 0.0 10.0 0.001
|
||||
#pragma parameter chromamode "Chroma Mode" 3.0 1.0 3.0 1.0
|
||||
#pragma parameter conversiongain_x "Conversion Gain X" 0.0 -5.0 5.0 0.5
|
||||
#pragma parameter conversiongain_y "Conversion Gain Y" 0.0 -5.0 5.0 0.5
|
||||
@ -203,32 +218,38 @@ bool SwapXY = bool(global.swapxy);
|
||||
#pragma parameter floor_r "Color Floor R" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter floor_g "Color Floor G" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter floor_b "Color Floor B" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter preparebloom "Prepare Bloom" 0.0 0.0 1.0 1.0
|
||||
//#pragma parameter preparebloom "Prepare Bloom" 0.0 0.0 1.0 1.0
|
||||
|
||||
// NTSC Pass
|
||||
#pragma parameter avalue "A Value" 0.5 -1.0 1.0 0.01
|
||||
#pragma parameter bvalue "B Value" 0.5 -1.0 1.0 0.01
|
||||
#pragma parameter ccvalue "CC Value" 3.5795454 0.0 6.0 0.0005
|
||||
#pragma parameter ovalue "O Value" 0.0 -3.0 3.0 0.1
|
||||
#pragma parameter pvalue "P Value" 1.0 -3.0 3.0 0.1
|
||||
#pragma parameter scantime "Scan Time" 52.6 0.0 100.0 0.1
|
||||
#pragma parameter notchhalfwidth "Notch Half Width" 1.0 0.0 6.0 0.05
|
||||
#pragma parameter yfreqresponse "Y Freq Response" 6.0 0.0 6.0 0.05
|
||||
#pragma parameter ifreqresponse "I Freq Response" 1.2 0.0 6.0 0.05
|
||||
#pragma parameter qfreqresponse "Q Freq Response" 0.6 0.0 6.0 0.05
|
||||
#pragma parameter signaloffset "Signal Offset" 1.0 0.0 1.0 0.01
|
||||
#pragma parameter avalue "NTSC A Value" 0.5 0.0 1.0 0.01
|
||||
#pragma parameter bvalue "NTSC B Value" 0.5 0.0 1.0 0.01
|
||||
#pragma parameter ccvalue "NTSC Color Carrier (Hz)" 3.5795454 3.47954 3.67954 0.00001
|
||||
#pragma parameter ovalue "NTSC Outgoing Phase Offset" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter pvalue "NTSC Incoming Phase Pixel Clock Scale" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter scantime "NTSC Scanline Duration (uSec)" 52.6 1.0 150.0 0.1
|
||||
#pragma parameter notch_width "NTSC Color Notch Filter Width" 2.0 1.0 4.0 0.01
|
||||
#pragma parameter yfreqresponse "NTSC Y Signal Bandwidth (Hz)" 6.0 0.0 21.0 0.05
|
||||
#pragma parameter ifreqresponse "NTSC I Signal Bandwidth (Hz)" 1.2 0.0 21.0 0.05
|
||||
#pragma parameter qfreqresponse "NTSC Q Signal Bandwidth (Hz)" 0.6 0.0 21.0 0.05
|
||||
#pragma parameter jitter_offset "NTSC Frame Jitter Offset" 0.0 0.0 2.0 0.01
|
||||
|
||||
// Color Pass
|
||||
#pragma parameter col_red "Red Shift" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_grn "Green Shift" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_blu "Blue Shift" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_offset_x "Offset X" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter col_offset_y "Offset Y" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter col_offset_z "Offset Z" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter col_scale_x "Scale X" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_y "Scale Y" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_z "Scale Z" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_saturation "Saturation" 1.0 0.0 5.0 0.01
|
||||
#pragma parameter col_rr "Red Shift Red" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_rg "Red Shift Green" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_rb "Red Shift Blue" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_gr "Green Shift Red" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_gg "Green Shift Green" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_gb "Green Shift Blue" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_br "Blue Shift Red" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_bg "Blue Shift Green" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_bb "Blue Shift Blue" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_offset_x "Offset X" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_offset_y "Offset Y" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_offset_z "Offset Z" 0.0 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_x "Scale X" 0.95 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_y "Scale Y" 0.95 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_z "Scale Z" 0.95 0.0 2.0 0.01
|
||||
#pragma parameter col_saturation "Color Saturation" 1.2 0.0 4.0 0.01
|
||||
|
||||
// Deconverge Pass
|
||||
#pragma parameter converge_x_r "Convergence X Red" 0.0 -10.0 10.0 0.05
|
||||
@ -237,31 +258,31 @@ bool SwapXY = bool(global.swapxy);
|
||||
#pragma parameter converge_y_r "Convergence Y Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_y_g "Convergence Y Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_y_b "Convergence Y Blue" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_r "Radial Conv X Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_g "Radial Conv X Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_b "Radial Conv X Blue" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_y_r "Radial Conv Y Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_y_g "Radial Conv Y Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_y_b "Radial Conv Y Blue" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_r "Radial Conv X Red" 0.0 -10.0 10.0 0.01
|
||||
#pragma parameter radial_conv_x_g "Radial Conv X Green" 0.0 -10.0 10.0 0.01
|
||||
#pragma parameter radial_conv_x_b "Radial Conv X Blue" 0.0 -10.0 10.0 0.01
|
||||
#pragma parameter radial_conv_y_r "Radial Conv Y Red" 0.0 -10.0 10.0 0.01
|
||||
#pragma parameter radial_conv_y_g "Radial Conv Y Green" 0.0 -10.0 10.0 0.01
|
||||
#pragma parameter radial_conv_y_b "Radial Conv Y Blue" 0.0 -10.0 10.0 0.01
|
||||
|
||||
// Scanline Pass
|
||||
#pragma parameter scanlinealpha "Scanline Alpha" 0.5 0.0 1.0 0.01
|
||||
#pragma parameter scanlinescale "Scanline Scale" 5.0 1.0 5.0 1.0
|
||||
#pragma parameter scanlineheight "Scanline Height" 1.0 0.0 2.0 0.1
|
||||
#pragma parameter scanlinevariation "Scanline Variation" 1.0 0.0 5.0 0.5
|
||||
#pragma parameter scanlineoffset "Scanline Offset" 1.0 -1.5 3.0 0.1
|
||||
#pragma parameter scanlinebrightscale "Scanline Bright Scale" 1.0 0.0 2.0 0.1
|
||||
#pragma parameter scanlinebrightoffset "Scanline Bright Offset" 1.0 -1.5 3.0 0.1
|
||||
#pragma parameter scanlinealpha "Scanline Amount" 0.35 0.0 1.0 0.01
|
||||
#pragma parameter scanlinescale "Overall Scanline Scale" 1.0 0.0 4.0 0.01
|
||||
#pragma parameter scanlineheight "Individual Scanline Scale" 1.0 0.0 4.0 0.01
|
||||
#pragma parameter scanlinevariation "Scanline Variation" 1.0 0.0 4.0 0.01
|
||||
//#pragma parameter scanlineoffset "Scanline Offset" 1.0 -1.5 3.0 0.01
|
||||
#pragma parameter scanlinebrightscale "Scanline Brightness Scale" 2.0 0.0 4.0 0.01
|
||||
#pragma parameter scanlinebrightoffset "Scanline Brightness Offset" 1.5 0.0 4.0 0.01
|
||||
#pragma parameter scanline_jitter_amount "Scanline Jitter Amount" 0.25 0.0 2.0 0.01
|
||||
|
||||
// Defocus Pass
|
||||
#pragma parameter defocus_x "Defocus X Axis" 0.0 0.0 10.0 0.1
|
||||
#pragma parameter defocus_y "Defocus Y Axis" 0.0 0.0 10.0 0.1
|
||||
|
||||
// Phosphor Pass
|
||||
#pragma parameter deltatime "Delta Time" 1.0 0.0 2.0 0.1
|
||||
#pragma parameter phosphor_r "Phosphor Red" 0.8 0.0 0.99 0.1
|
||||
#pragma parameter phosphor_g "Phosphor Green" 0.0 0.0 0.99 0.1
|
||||
#pragma parameter phosphor_b "Phosphor Blue" 0.0 0.0 0.99 0.1
|
||||
#pragma parameter phosphor_r "Phosphor Red" 0.45 0.0 0.99 0.01
|
||||
#pragma parameter phosphor_g "Phosphor Green" 0.45 0.0 0.99 0.01
|
||||
#pragma parameter phosphor_b "Phosphor Blue" 0.45 0.0 0.99 0.01
|
||||
|
||||
// Chroma Pass
|
||||
#pragma parameter ygain_r "Y Gain R Channel" 0.2126 0.0 1.0 0.01
|
||||
@ -275,16 +296,17 @@ bool SwapXY = bool(global.swapxy);
|
||||
#pragma parameter chromac_y "Chroma C Y" 0.070 0.0 1.0 0.01
|
||||
|
||||
// Distortion Pass
|
||||
#pragma parameter distortion_amount "Distortion Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter cubic_distortion_amount "Cubic Dist. Amt" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter distort_corner_amount "Corner Dist. Amt" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter round_corner_amount "Corner Rounding" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter smooth_border_amount "Border Smoothing" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter vignette_amount "Vignetting Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter reflection_amount "Reflection Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter reflection_col_r "Reflection Color R" 1.0 0.0 1.0 0.01
|
||||
#pragma parameter reflection_col_g "Reflection Color G" 0.9 0.0 1.0 0.01
|
||||
#pragma parameter reflection_col_b "Reflection Color B" 0.8 0.0 1.0 0.01
|
||||
#pragma parameter distortion_amount "Quadric Dist. Amt" 0.05 -2.0 2.0 0.01
|
||||
#pragma parameter cubic_distortion_amount "Cubic Dist. Amt" 0.0 -2.0 2.0 0.01
|
||||
#pragma parameter distort_corner_amount "Dist. Corner Amt" 0.05 0.0 2.0 0.01
|
||||
#pragma parameter round_corner_amount "Rounded Corner Amt" 0.05 0.0 2.0 0.01
|
||||
#pragma parameter smooth_border_amount "Smooth Border Amt" 0.03 0.0 2.0 0.01
|
||||
#pragma parameter vignette_amount "Vignetting Amount" 0.08 0.0 2.0 0.01
|
||||
#pragma parameter reflection_amount "Reflection Amount" 0.05 0.0 2.0 0.01
|
||||
#pragma parameter noise_amt "Noise/Grain (reduces moire)" 1.0 0.0 5.0 0.25
|
||||
//#pragma parameter reflection_col_r "Reflection Color R" 1.0 0.0 1.0 0.01
|
||||
//#pragma parameter reflection_col_g "Reflection Color G" 1.0 0.0 1.0 0.01
|
||||
//#pragma parameter reflection_col_b "Reflection Color B" 1.0 0.0 1.0 0.01
|
||||
|
||||
// Vector Pass
|
||||
//#pragma parameter timeratio "Time Ratio" 1.0 0.0 2.0 0.01
|
||||
@ -292,3 +314,17 @@ bool SwapXY = bool(global.swapxy);
|
||||
//#pragma parameter lengthratio "Length Ratio" 1.0 1.0 10.0 1.0
|
||||
//#pragma parameter lengthscale "Length Scale" 1.0 1.0 10.0 1.0
|
||||
//#pragma parameter beamsmooth "Beam Smooth Amt" 0.5 0.1 1.0 0.1
|
||||
|
||||
// Prescale Pass
|
||||
#pragma parameter prescale "PreScale Factor" 2.0 1.0 4.0 1.0
|
||||
|
||||
vec4 u_swap_xy = vec4(global.swapxy);
|
||||
vec4 u_source_dims = params.OriginalSize;
|
||||
vec4 u_target_dims = params.OutputSize;
|
||||
vec4 u_target_scale = params.OutputSize / params.SourceSize;
|
||||
vec4 u_screen_scale = vec4(1.-global.screenscale_x, 1.-global.screenscale_y, 1., 1.);
|
||||
vec4 u_screen_offset = vec4(global.screenoffset_x, global.screenoffset_y, 0.,0.);
|
||||
vec4 u_screen_count = vec4(1.);
|
||||
vec4 u_screen_dims = vec4(params.OutputSize);
|
||||
vec4 u_quad_dims = params.FinalViewportSize;
|
||||
vec4 u_time = vec4(params.FrameCount);//vec4(mod(params.FrameCount, global.time / 16.));
|
@ -12,45 +12,40 @@ layout(push_constant) uniform Push
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
float DeltaTime = global.deltatime;
|
||||
vec3 Phosphor = vec3(global.phosphor_r, global.phosphor_g, global.phosphor_b);
|
||||
|
||||
const float F = 1.0;
|
||||
vec4 u_passthrough = vec4(1.0 - global.phosphortoggle);
|
||||
vec4 u_phosphor = vec4(global.phosphor_r, global.phosphor_g, global.phosphor_b, 0.0);
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D PassFeedback6;
|
||||
layout(set = 0, binding = 3) uniform sampler2D PassFeedback8;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define PreviousSampler PassFeedback6
|
||||
#define s_tex Source
|
||||
#define s_prev PassFeedback8
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 CurrY = texture(DiffuseSampler, vTexCoord);
|
||||
vec3 PrevY = texture(PreviousSampler, vTexCoord).rgb;
|
||||
vec4 curr = texture(s_tex, v_texcoord0);
|
||||
vec3 prev = texture(s_prev, v_texcoord0).rgb * u_phosphor.rgb;
|
||||
|
||||
PrevY[0] *= (Phosphor[0] == 0.0) ? 0.0 : pow(Phosphor[0], F * DeltaTime);
|
||||
PrevY[1] *= (Phosphor[1] == 0.0) ? 0.0 : pow(Phosphor[1], F * DeltaTime);
|
||||
PrevY[2] *= (Phosphor[2] == 0.0) ? 0.0 : pow(Phosphor[2], F * DeltaTime);
|
||||
float a = max(PrevY[0], CurrY[0]);
|
||||
float b = max(PrevY[1], CurrY[1]);
|
||||
float c = max(PrevY[2], CurrY[2]);
|
||||
FragColor = Passthrough ? CurrY : vec4(a, b, c, CurrY.a);
|
||||
vec3 maxed = max(curr.rgb, prev);
|
||||
|
||||
FragColor = u_passthrough.x > 0.0 ? curr : vec4(maxed, curr.a);
|
||||
}
|
@ -2,9 +2,6 @@
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shadowmask Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
@ -12,85 +9,68 @@ layout(push_constant) uniform Push
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
#define TargetDims params.OutputSize.xy
|
||||
#define SourceDims params.OriginalSize.xy
|
||||
float TargetScale = 1.0;//max(TargetDims.x / SourceDims.x, TargetDims.y / SourceDims.y);
|
||||
|
||||
float HumBarAlpha = global.humbaralpha;
|
||||
float TimeMilliseconds = float(mod(params.FrameCount, 1000));
|
||||
vec3 BackColor = vec3(global.backcolor_r, global.backcolor_g, global.backcolor_b);
|
||||
int ShadowTileMode = int(global.shadowtilemode); // 0 based on screen (quad) dimension, 1 based on source dimension
|
||||
float ShadowAlpha = global.shadowalpha;
|
||||
vec2 ShadowCount = vec2(global.shadowcount_x, global.shadowcount_y);
|
||||
vec2 ShadowUV = vec2(global.shadowuv_x, global.shadowuv_y);
|
||||
vec2 ShadowDims = vec2(global.mask_width, global.mask_height);
|
||||
vec2 ShadowUVOffset = vec2(global.mask_offset_x, global.mask_offset_y);
|
||||
int ChromaMode = int(global.chromamode);
|
||||
vec3 ConversionGain = vec3(global.conversiongain_x, global.conversiongain_y, global.conversiongain_z);
|
||||
vec3 Power = vec3(global.power_r, global.power_g, global.power_b);
|
||||
vec3 Floor = vec3(global.floor_r, global.floor_g, global.floor_b);
|
||||
bool PrepareBloom = bool(global.preparebloom);
|
||||
|
||||
#define MONOCHROME 1
|
||||
#define DICHROME 2
|
||||
#define TRICHROME 3
|
||||
vec4 u_shadow_tile_mode = vec4(global.shadowtilemode);
|
||||
vec4 u_shadow_alpha = vec4(global.shadowalpha);
|
||||
vec4 u_shadow_count = vec4(global.shadowcount_x, global.shadowcount_y, 0., 0.);
|
||||
vec4 u_shadow_uv = vec4(global.shadowuv_x, global.shadowuv_y, 0., 0.);
|
||||
vec4 u_shadow_uv_offset = vec4(global.mask_offset_x, global.mask_offset_y, 0., 0.);
|
||||
vec4 u_humbar_hertz_rate = vec4(global.humbar_hertz_rate);
|
||||
// ^^difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
|
||||
vec4 u_humbar_alpha = vec4(global.humbaralpha);
|
||||
vec4 u_power = vec4(global.power_r, global.power_g, global.power_b, 0.);
|
||||
vec4 u_floor = vec4(global.floor_r, global.floor_g, global.floor_b, 0.);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
// Shadowmask Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float HalfPI = PI * 0.5;
|
||||
|
||||
float HumBarDesync = 60.0 / 59.94 - 1.0; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
|
||||
|
||||
vec2 GetAdjustedCoords(vec2 coord)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5;
|
||||
|
||||
// apply screen scale
|
||||
coord *= ScreenScale;
|
||||
coord *= u_screen_scale.xy;
|
||||
|
||||
// un-center coordinates
|
||||
coord += 0.5;
|
||||
|
||||
// apply screen offset
|
||||
coord += ScreenOffset;
|
||||
coord += u_screen_offset.xy;
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
vec2 GetShadowCoord(vec2 TargetCoord, vec2 SourceCoord)
|
||||
{
|
||||
// base-target dimensions (without oversampling)
|
||||
vec2 BaseTargetDims = TargetDims / TargetScale;
|
||||
BaseTargetDims = SwapXY
|
||||
// base-target dimensions (remove oversampling)
|
||||
vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy;
|
||||
BaseTargetDims = u_swap_xy.x > 0.0
|
||||
? BaseTargetDims.yx
|
||||
: BaseTargetDims.xy;
|
||||
|
||||
vec2 canvasCoord = ShadowTileMode == 0
|
||||
? TargetCoord + ShadowUVOffset / BaseTargetDims
|
||||
: SourceCoord + ShadowUVOffset / SourceDims;
|
||||
vec2 canvasTexelDims = ShadowTileMode == 0
|
||||
? 1.0 / BaseTargetDims
|
||||
: 1.0 / SourceDims;
|
||||
vec2 canvasCoord = u_shadow_tile_mode.x == 0.0
|
||||
? TargetCoord + u_shadow_uv_offset.xy / BaseTargetDims
|
||||
: SourceCoord + u_shadow_uv_offset.xy / u_source_dims.xy;
|
||||
vec2 canvasTexelDims = u_shadow_tile_mode.x == 0.0
|
||||
? vec2(1.0, 1.0) / BaseTargetDims
|
||||
: vec2(1.0, 1.0) / u_source_dims.xy;
|
||||
|
||||
vec2 shadowDims = ShadowDims;
|
||||
vec2 shadowUV = ShadowUV;
|
||||
vec2 shadowCount = ShadowCount;
|
||||
vec2 shadowUV = u_shadow_uv.xy;
|
||||
vec2 shadowCount = u_shadow_count.xy;
|
||||
|
||||
// swap x/y in screen mode (not source mode)
|
||||
canvasCoord = ShadowTileMode == 0 && SwapXY
|
||||
canvasCoord = u_shadow_tile_mode.x == 0.0 && u_swap_xy.x > 0.0
|
||||
? canvasCoord.yx
|
||||
: canvasCoord.xy;
|
||||
|
||||
// swap x/y in screen mode (not source mode)
|
||||
shadowCount = ShadowTileMode == 0 && SwapXY
|
||||
shadowCount = u_shadow_tile_mode.x == 0.0 && u_swap_xy.x > 0.0
|
||||
? shadowCount.yx
|
||||
: shadowCount.xy;
|
||||
|
||||
@ -99,14 +79,11 @@ vec2 GetShadowCoord(vec2 TargetCoord, vec2 SourceCoord)
|
||||
vec2 shadowFrac = fract(canvasCoord / shadowTile);
|
||||
|
||||
// swap x/y in screen mode (not source mode)
|
||||
shadowFrac = ShadowTileMode == 0 && SwapXY
|
||||
shadowFrac = u_shadow_tile_mode.x == 0.0 && u_swap_xy.x > 0.0
|
||||
? shadowFrac.yx
|
||||
: shadowFrac.xy;
|
||||
|
||||
vec2 shadowCoord = (shadowFrac * shadowUV);
|
||||
shadowCoord += ShadowTileMode == 0
|
||||
? vec2(0.5) * (vec2(1.0) / shadowDims) // fix half texel offset (DX9)
|
||||
: vec2(0.0);
|
||||
|
||||
return shadowCoord;
|
||||
}
|
||||
@ -114,84 +91,74 @@ vec2 GetShadowCoord(vec2 TargetCoord, vec2 SourceCoord)
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D MaskTexture;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define ShadowSampler MaskTexture
|
||||
#define s_tex Source
|
||||
#define s_shadow MaskTexture
|
||||
//#define ScreenCoord vTexCoord
|
||||
#define v_color0 vec4(1.,1.,1.,1.)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 ScreenCoord = vTexCoord;
|
||||
vec2 BaseCoord = GetAdjustedCoords(ScreenCoord);
|
||||
vec2 BaseCoord = GetAdjustedCoords(v_texcoord0);
|
||||
|
||||
// Color
|
||||
vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
|
||||
BaseColor.a = 1.0;
|
||||
/*
|
||||
// clip border
|
||||
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 ||
|
||||
BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
|
||||
vec4 BaseColor = texture(s_tex, BaseCoord);
|
||||
|
||||
// Clamp
|
||||
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 || BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
|
||||
{
|
||||
// we don't use the clip function, because we don't clear the render target before
|
||||
return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
*/
|
||||
// Color Compression (may not affect bloom)
|
||||
if (!PrepareBloom)
|
||||
else
|
||||
{
|
||||
// Mask Simulation
|
||||
if (u_shadow_alpha.x > 0.0)
|
||||
{
|
||||
vec2 ShadowCoord = GetShadowCoord(v_texcoord0.xy, BaseCoord.xy);
|
||||
|
||||
vec4 ShadowColor = texture(s_shadow, ShadowCoord);
|
||||
vec3 ShadowMaskColor = mix(vec3(1.0, 1.0, 1.0), ShadowColor.rgb, u_shadow_alpha.xxx);
|
||||
|
||||
// apply shadow mask color
|
||||
BaseColor.rgb *= ShadowMaskColor;
|
||||
|
||||
// // TODO
|
||||
// vec3 ShadowMaskClear = (1.0f - ShadowColor.a) * u_shadow_alpha.xxx;
|
||||
|
||||
// // clear shadow mask by background color
|
||||
// BaseColor.rgb = mix(BaseColor.rgb, u_back_color.rgb, ShadowMaskClear);
|
||||
}
|
||||
|
||||
// Color Compression
|
||||
// increasing the floor of the signal without affecting the ceiling
|
||||
BaseColor.rgb = Floor + (1.0f - Floor) * BaseColor.rgb;
|
||||
BaseColor.rgb = u_floor.rgb + (vec3(1.0, 1.0, 1.0) - u_floor.rgb) * BaseColor.rgb;
|
||||
|
||||
// Color Power
|
||||
BaseColor.r = pow(BaseColor.r, u_power.r);
|
||||
BaseColor.g = pow(BaseColor.g, u_power.g);
|
||||
BaseColor.b = pow(BaseColor.b, u_power.b);
|
||||
|
||||
// Hum Bar Simulation
|
||||
if (u_humbar_alpha.x > 0.0f)
|
||||
{
|
||||
float HumTimeStep = fract(u_time.x * u_humbar_hertz_rate.x);
|
||||
float HumBrightness = 1.0 - fract(BaseCoord.y + HumTimeStep) * u_humbar_alpha.x;
|
||||
BaseColor.rgb *= HumBrightness;
|
||||
}
|
||||
|
||||
FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a);
|
||||
}
|
||||
|
||||
// Color Power (may affect bloom)
|
||||
BaseColor.r = pow(BaseColor.r, Power.r);
|
||||
BaseColor.g = pow(BaseColor.g, Power.g);
|
||||
BaseColor.b = pow(BaseColor.b, Power.b);
|
||||
|
||||
// Hum Bar Simulation (may not affect vector screen)
|
||||
if (!PrepareBloom && !VectorScreen && HumBarAlpha > 0.0)
|
||||
{
|
||||
float HumBarStep = fract(TimeMilliseconds * HumBarDesync);
|
||||
float HumBarBrightness = 1.0 - fract(BaseCoord.y + HumBarStep) * HumBarAlpha;
|
||||
BaseColor.rgb *= HumBarBrightness;
|
||||
}
|
||||
|
||||
// Mask Simulation (may not affect bloom)
|
||||
if (!PrepareBloom && ShadowAlpha > 0.0)
|
||||
{
|
||||
vec2 ShadowCoord = GetShadowCoord(ScreenCoord, BaseCoord);
|
||||
|
||||
vec4 ShadowColor = texture(ShadowSampler, ShadowCoord);
|
||||
vec3 ShadowMaskColor = mix(vec3(1.0), ShadowColor.rgb, ShadowAlpha);
|
||||
float ShadowMaskClear = (1.0 - ShadowColor.a) * ShadowAlpha;
|
||||
|
||||
// apply shadow mask color
|
||||
BaseColor.rgb *= ShadowMaskColor;
|
||||
// clear shadow mask by background color
|
||||
BaseColor.rgb = mix(BaseColor.rgb, BackColor, ShadowMaskClear);
|
||||
}
|
||||
|
||||
// Preparation for phosphor color conversion
|
||||
if (ChromaMode == MONOCHROME) {
|
||||
BaseColor.r = dot(ConversionGain, BaseColor.rgb);
|
||||
BaseColor.gb = vec2(BaseColor.r, BaseColor.r);
|
||||
} else if (ChromaMode == DICHROME) {
|
||||
BaseColor.r = dot(ConversionGain.rg, BaseColor.rg);
|
||||
BaseColor.g = BaseColor.r;
|
||||
}
|
||||
|
||||
FragColor = BaseColor;
|
||||
}
|
51
crt/shaders/mame_hlsl/shaders/mame_prescale.slang
Normal file
51
crt/shaders/mame_hlsl/shaders/mame_prescale.slang
Normal file
@ -0,0 +1,51 @@
|
||||
#version 450
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
vec4 u_tex_size0 = params.SourceSize;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define s_tex Source
|
||||
#define v_color0 vec4(1.,1.,1.,1.)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 Scale = (global.prescale * u_tex_size0.xy) / u_source_dims.xy;
|
||||
|
||||
vec2 TexelDims = v_texcoord0.xy * u_source_dims.xy;
|
||||
vec2 i = floor(TexelDims);
|
||||
vec2 s = fract(TexelDims);
|
||||
|
||||
// Figure out where in the texel to sample to get the correct pre-scaled bilinear.
|
||||
vec2 CenterDistance = s - 0.5;
|
||||
vec2 RegionRange = 0.5 - 0.5 / Scale;
|
||||
vec2 f = (CenterDistance - clamp(CenterDistance, -RegionRange, RegionRange)) * Scale + 0.5;
|
||||
|
||||
vec2 TexCoord = (i + f) / u_source_dims.xy;
|
||||
|
||||
FragColor = texture(s_tex, TexCoord.xy) * v_color0;
|
||||
}
|
@ -17,41 +17,33 @@ layout(push_constant) uniform Push
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
vec4 u_scanline_alpha = vec4(global.scanlinealpha);
|
||||
vec4 u_scanline_scale = vec4(global.scanlinescale);
|
||||
vec4 u_scanline_bright_scale = vec4(global.scanlinebrightscale);
|
||||
vec4 u_scanline_bright_offset = vec4(global.scanlinebrightoffset);
|
||||
vec4 u_scanline_jitter = vec4((global.jitter != 0.0) ? (params.OriginalSize.y > 400.0 || global.jitter == 1.0) ? (mod(params.FrameCount, 2.0)) : 0.0 : 0.0);
|
||||
vec4 u_scanline_height = vec4(global.scanlineheight);
|
||||
vec4 u_scanline_variation = vec4(global.scanlinevariation);
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float HalfPI = PI * 0.5;
|
||||
vec4 u_jitter_amount = vec4(global.scanline_jitter_amount);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scanline Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
float ScanlineAlpha = global.scanlinealpha;
|
||||
float ScanlineScale = global.scanlinescale;
|
||||
float ScanlineHeight = global.scanlineheight;
|
||||
float ScanlineVariation = global.scanlinevariation;
|
||||
float ScanlineOffset = global.scanlineoffset;
|
||||
float ScanlineBrightScale = global.scanlinebrightscale;
|
||||
float ScanlineBrightOffset = global.scanlinebrightoffset;
|
||||
|
||||
vec2 QuadDims = params.FinalViewportSize.xy;
|
||||
vec2 SourceDims = params.OriginalSize.xy;
|
||||
|
||||
vec2 GetAdjustedCoords(vec2 coord)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5;
|
||||
|
||||
// apply screen scale
|
||||
coord *= ScreenScale;
|
||||
coord *= u_screen_scale.xy;
|
||||
|
||||
// un-center coordinates
|
||||
coord += 0.5;
|
||||
|
||||
// apply screen offset
|
||||
coord += ScreenOffset;
|
||||
coord += u_screen_offset.xy;
|
||||
|
||||
return coord;
|
||||
}
|
||||
@ -59,67 +51,67 @@ vec2 GetAdjustedCoords(vec2 coord)
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
layout(location = 0) out vec2 v_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
v_texcoord0 = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) in vec2 v_texcoord0;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D MaskTexture;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define s_tex Source
|
||||
#define s_shadow MaskTexture
|
||||
#define v_color0 vec4(1.,1.,1.,1.)
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!ScanlineToggle)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec2 BaseCoord = GetAdjustedCoords(vTexCoord);
|
||||
vec2 BaseCoord = GetAdjustedCoords(v_texcoord0);
|
||||
|
||||
// Color
|
||||
vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
|
||||
BaseColor.a = 1.0;
|
||||
/*
|
||||
// clip border
|
||||
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 ||
|
||||
BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
|
||||
{
|
||||
// we don't use the clip function, because we don't clear the render target before
|
||||
return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
*/
|
||||
float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha);
|
||||
float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0 - ScanlineAlpha);
|
||||
// Color
|
||||
vec4 BaseColor = texture(s_tex, BaseCoord);
|
||||
|
||||
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
|
||||
// Clamp
|
||||
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 || BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
|
||||
{
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scanline Simulation
|
||||
if (ScanlineToggle)
|
||||
{
|
||||
float BrightnessOffset = (u_scanline_bright_offset.x * u_scanline_alpha.x);
|
||||
float BrightnessScale = (u_scanline_bright_scale.x * u_scanline_alpha.x) + (1.0 - u_scanline_alpha.x);
|
||||
|
||||
float ScanlineCoord = BaseCoord.y;
|
||||
ScanlineCoord += (SwapXY)
|
||||
? QuadDims.x <= SourceDims.x * 2.0
|
||||
? 0.5 / QuadDims.x // uncenter scanlines if the quad is less than twice the size of the source
|
||||
: 0.0
|
||||
: QuadDims.y <= SourceDims.y * 2.0
|
||||
? 0.5 / QuadDims.y // uncenter scanlines if the quad is less than twice the size of the source
|
||||
: 0.0;
|
||||
ScanlineCoord *= SourceDims.y * ScanlineScale * PI;
|
||||
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
|
||||
|
||||
float ScanlineCoordJitter = ScanlineOffset * HalfPI;
|
||||
float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter);
|
||||
float ScanlineWide = ScanlineHeight + ScanlineVariation * max(1.0f, ScanlineHeight) * (1.0 - ColorBrightness);
|
||||
float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide);
|
||||
float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale;
|
||||
float ScanCoord = BaseCoord.y;
|
||||
ScanCoord += (global.scanline_crawl > 0.0) ? -1.* u_time.x * params.OutputSize.w * u_jitter_amount.x : 0.0;
|
||||
ScanCoord += u_swap_xy.x > 0.0
|
||||
? u_quad_dims.x <= u_source_dims.x * 2.0
|
||||
? 0.5 / u_quad_dims.x // uncenter scanlines if the quad is less than twice the size of the source
|
||||
: 0.0
|
||||
: u_quad_dims.y <= u_source_dims.y * 2.0
|
||||
? 0.5 / u_quad_dims.y // uncenter scanlines if the quad is less than twice the size of the source
|
||||
: 0.0;
|
||||
|
||||
BaseColor.rgb *= mix(1.0, ScanlineBrightness, ScanlineAlpha);
|
||||
ScanCoord *= u_source_dims.y * u_scanline_scale.x * 3.1415927; // PI
|
||||
|
||||
FragColor = BaseColor;
|
||||
}
|
||||
float ScanCoordJitter = u_scanline_jitter.x * 1.5707963; // half PI
|
||||
float ScanSine = sin(ScanCoord + ScanCoordJitter);
|
||||
float ScanlineWide = u_scanline_height.x + u_scanline_variation.x * max(1.0, u_scanline_height.x) * (1.0 - ColorBrightness);
|
||||
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineWide);
|
||||
float ScanBrightness = ScanSineScaled * BrightnessScale + BrightnessOffset * BrightnessScale;
|
||||
|
||||
BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
|
||||
}
|
||||
|
||||
FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a);
|
||||
}
|
||||
}
|
85
crt/shaders/mame_hlsl/shaders/old/mame_hlsl.slangp
Normal file
85
crt/shaders/mame_hlsl/shaders/old/mame_hlsl.slangp
Normal file
@ -0,0 +1,85 @@
|
||||
# info on how the passes come together can be found in mame/src/osd/modules/render/d3d/d3dhlsl.cpp
|
||||
shaders = 12
|
||||
|
||||
shader0 = shaders/mame_hlsl/shaders/mame_ntsc.slang
|
||||
filter_linear0 = true
|
||||
alias0 = NTSCPass
|
||||
scale_type0 = source
|
||||
scale0 = 1.0
|
||||
|
||||
shader1 = shaders/mame_hlsl/shaders/mame_color.slang
|
||||
alias1 = ColorPass
|
||||
scale_type1 = source
|
||||
scale1 = 1.0
|
||||
filter_linear1 = true
|
||||
|
||||
shader2 = ../interpolation/shaders/sharp-bilinear.slang
|
||||
alias2 = PrescalePass
|
||||
scale_type2 = source
|
||||
filter_linear2 = true
|
||||
scale2 = 4.0
|
||||
|
||||
shader3 = shaders/mame_hlsl/shaders/mame_deconverge.slang
|
||||
alias3 = DeconvergePass
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale3 = 0.5
|
||||
|
||||
shader4 = shaders/mame_hlsl/shaders/mame_scanline.slang
|
||||
alias4 = ScanlinePass
|
||||
filter_linear4 = true
|
||||
scale_type4 = source
|
||||
scale4 = 2.0
|
||||
|
||||
shader5 = shaders/mame_hlsl/shaders/mame_focus.slang
|
||||
alias5 = FocusPass
|
||||
filter_linear5 = true
|
||||
|
||||
shader6 = shaders/mame_hlsl/shaders/mame_phosphor.slang
|
||||
alias6 = PhosphorPass
|
||||
filter_linear6 = true
|
||||
|
||||
shader7 = shaders/mame_hlsl/shaders/mame_post.slang
|
||||
alias7 = PostPass
|
||||
filter_linear7 = true
|
||||
scale_type7 = viewport
|
||||
|
||||
shader8 = shaders/mame_hlsl/shaders/mame_chroma.slang
|
||||
alias8 = ChromaPass
|
||||
filter_linear8 = true
|
||||
scale_type8 = viewport
|
||||
|
||||
shader9 = shaders/mame_hlsl/shaders/mame_downsample.slang
|
||||
alias9 = DownsamplePass
|
||||
filter_linear9 = true
|
||||
|
||||
shader10 = shaders/mame_hlsl/shaders/mame_bloom.slang
|
||||
alias10 = BloomPass
|
||||
filter_linear10 = true
|
||||
mipmap_input10 = true
|
||||
scale_type10 = source
|
||||
|
||||
shader11 = shaders/mame_hlsl/shaders/mame_distortion.slang
|
||||
alias11 = DistortionPass
|
||||
filter_linear11 = true
|
||||
|
||||
# doesn't work, so commenting
|
||||
# shader12 = shaders/mame_hlsl/shaders/mame_vector.slang
|
||||
# alias12 = VectorPass
|
||||
# filter_linear12 = true
|
||||
|
||||
# mame's textures are available here: https://github.com/mamedev/mame/tree/master/artwork
|
||||
textures = "MaskTexture"
|
||||
MaskTexture = shaders/mame_hlsl/resources/aperture-grille.png
|
||||
|
||||
parameters = "AUTO_PRESCALE;chromaa_x;chromaa_y;chromab_x;chromab_y;chromac_x;chromac_y;ygain_r;ygain_g;ygain_b"
|
||||
chromaa_x = "0.630"
|
||||
chromaa_y = "0.340"
|
||||
chromab_x = "0.310"
|
||||
chromab_y = "0.595"
|
||||
chromac_x = "0.155"
|
||||
chromac_y = "0.070"
|
||||
ygain_r = "0.1875"
|
||||
ygain_g = "0.6940"
|
||||
ygain_b = "0.1185"
|
||||
AUTO_PRESCALE = "0.0"
|
@ -0,0 +1,231 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Bloom Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OutputSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
float Level0Weight = global.level0weight;
|
||||
float Level1Weight = global.level1weight;
|
||||
float Level2Weight = global.level2weight;
|
||||
float Level3Weight = global.level3weight;
|
||||
float Level4Weight = global.level4weight;
|
||||
float Level5Weight = global.level5weight;
|
||||
float Level6Weight = global.level6weight;
|
||||
float Level7Weight = global.level7weight;
|
||||
float Level8Weight = global.level8weight;
|
||||
|
||||
int BloomBlendMode = int(global.bloomblendmode); // 0 brighten, 1 darken
|
||||
float BloomScale = global.bloomscale;
|
||||
vec3 BloomOverdrive = vec3(global.bloomoverdrive_r, global.bloomoverdrive_g, global.bloomoverdrive_b);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float E = 2.7182817f;
|
||||
const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
|
||||
const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
|
||||
float random(vec2 seed)
|
||||
{
|
||||
// irrationals for pseudo randomness
|
||||
vec2 i = vec2(Gelfond, GelfondSchneider);
|
||||
|
||||
return fract(cos(dot(seed, i)) * 123456.0f);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Bloom Vertex Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#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 BloomCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
BloomCoord = vTexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 1) in vec2 BloomCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
#define BloomSamplerA Source
|
||||
#define BloomSamplerB Source
|
||||
#define BloomSamplerC Source
|
||||
#define BloomSamplerD Source
|
||||
#define BloomSamplerE Source
|
||||
#define BloomSamplerF Source
|
||||
#define BloomSamplerG Source
|
||||
#define BloomSamplerH Source
|
||||
|
||||
// vector screen uses twice -1 as many bloom levels
|
||||
#define BloomSamplerI Source
|
||||
#define BloomSamplerJ Source
|
||||
#define BloomSamplerK Source
|
||||
#define BloomSamplerL Source
|
||||
#define BloomSamplerM Source
|
||||
#define BloomSamplerN Source
|
||||
#define BloomSamplerO Source
|
||||
|
||||
vec3 GetNoiseFactor(vec3 n, float random)
|
||||
{
|
||||
// smaller n become more noisy
|
||||
vec3 NoiseFactor;
|
||||
NoiseFactor.x = 1.0 + random * max(0.0, 0.25 * pow(E, -8. * n.x));
|
||||
NoiseFactor.y = 1.0 + random * max(0.0, 0.25 * pow(E, -8. * n.y));
|
||||
NoiseFactor.z = 1.0 + random * max(0.0, 0.25 * pow(E, -8. * n.z));
|
||||
return NoiseFactor;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!BloomToggle)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 texel = texture(DiffuseSampler, vTexCoord).rgb;
|
||||
|
||||
vec3 texelA = texture(BloomSamplerA, BloomCoord.xy).rgb;
|
||||
vec3 texelB = texture(BloomSamplerB, BloomCoord.xy).rgb;
|
||||
vec3 texelC = texture(BloomSamplerC, BloomCoord.xy).rgb;
|
||||
vec3 texelD = texture(BloomSamplerD, BloomCoord.xy).rgb;
|
||||
vec3 texelE = texture(BloomSamplerE, BloomCoord.xy).rgb;
|
||||
vec3 texelF = texture(BloomSamplerF, BloomCoord.xy).rgb;
|
||||
vec3 texelG = texture(BloomSamplerG, BloomCoord.xy).rgb;
|
||||
vec3 texelH = texture(BloomSamplerH, BloomCoord.xy).rgb;
|
||||
|
||||
vec3 texelI = vec3(0.0, 0.0, 0.0);
|
||||
vec3 texelJ = vec3(0.0, 0.0, 0.0);
|
||||
vec3 texelK = vec3(0.0, 0.0, 0.0);
|
||||
vec3 texelL = vec3(0.0, 0.0, 0.0);
|
||||
vec3 texelM = vec3(0.0, 0.0, 0.0);
|
||||
vec3 texelN = vec3(0.0, 0.0, 0.0);
|
||||
vec3 texelO = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
|
||||
// vector screen uses twice -1 as many bloom levels
|
||||
if (VectorScreen)
|
||||
{
|
||||
texelI = texture(BloomSamplerI, BloomCoord.xy).rgb;
|
||||
texelJ = texture(BloomSamplerJ, BloomCoord.xy).rgb;
|
||||
texelK = texture(BloomSamplerK, BloomCoord.xy).rgb;
|
||||
texelL = texture(BloomSamplerL, BloomCoord.xy).rgb;
|
||||
texelM = texture(BloomSamplerM, BloomCoord.xy).rgb;
|
||||
texelN = texture(BloomSamplerN, BloomCoord.xy).rgb;
|
||||
texelO = texture(BloomSamplerO, BloomCoord.xy).rgb;
|
||||
}
|
||||
|
||||
vec3 blend;
|
||||
|
||||
// brighten
|
||||
if (BloomBlendMode < 0.5)
|
||||
{
|
||||
vec3 bloom = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
texel *= Level0Weight;
|
||||
|
||||
if (VectorScreen)
|
||||
{
|
||||
bloom += texelA * Level1Weight;
|
||||
bloom += texelB * Level2Weight;
|
||||
bloom += texelC * Level3Weight;
|
||||
bloom += texelD * Level4Weight;
|
||||
bloom += texelE * Level5Weight;
|
||||
bloom += texelF * Level6Weight;
|
||||
bloom += texelG * Level7Weight;
|
||||
bloom += texelH * Level8Weight;
|
||||
}
|
||||
// vector screen uses twice -1 as many bloom levels
|
||||
else
|
||||
{
|
||||
bloom += texelA * (Level1Weight);
|
||||
bloom += texelB * (Level1Weight + Level2Weight) * 0.5;
|
||||
bloom += texelC * (Level2Weight);
|
||||
bloom += texelD * (Level2Weight + Level3Weight) * 0.5;
|
||||
bloom += texelE * (Level3Weight);
|
||||
bloom += texelF * (Level3Weight + Level4Weight) * 0.5;
|
||||
bloom += texelG * (Level4Weight);
|
||||
bloom += texelH * (Level4Weight + Level5Weight) * 0.5;
|
||||
bloom += texelI * (Level5Weight);
|
||||
bloom += texelJ * (Level5Weight + Level6Weight) * 0.5;
|
||||
bloom += texelK * (Level6Weight);
|
||||
bloom += texelL * (Level6Weight + Level7Weight) * 0.5;
|
||||
bloom += texelM * (Level7Weight);
|
||||
bloom += texelN * (Level7Weight + Level8Weight) * 0.5;
|
||||
bloom += texelO * (Level8Weight);
|
||||
}
|
||||
|
||||
bloom *= BloomScale;
|
||||
|
||||
vec3 bloomOverdrive;
|
||||
bloomOverdrive.r = max(0.0, texel.r + bloom.r - 1.0) * BloomOverdrive.r;
|
||||
bloomOverdrive.g = max(0.0, texel.g + bloom.g - 1.0) * BloomOverdrive.g;
|
||||
bloomOverdrive.b = max(0.0, texel.b + bloom.b - 1.0) * BloomOverdrive.b;
|
||||
|
||||
bloom.r += bloomOverdrive.g * 0.5;
|
||||
bloom.r += bloomOverdrive.b * 0.5;
|
||||
bloom.g += bloomOverdrive.r * 0.5;
|
||||
bloom.g += bloomOverdrive.b * 0.5;
|
||||
bloom.b += bloomOverdrive.r * 0.5;
|
||||
bloom.b += bloomOverdrive.g * 0.5;
|
||||
|
||||
vec2 NoiseCoord = vTexCoord;
|
||||
vec3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord));
|
||||
|
||||
blend = texel + bloom * NoiseFactor;
|
||||
}
|
||||
|
||||
// darken
|
||||
else
|
||||
{
|
||||
texelA = min(texel, texelA);
|
||||
texelB = min(texel, texelB);
|
||||
texelC = min(texel, texelC);
|
||||
texelD = min(texel, texelD);
|
||||
texelE = min(texel, texelE);
|
||||
texelF = min(texel, texelF);
|
||||
texelG = min(texel, texelG);
|
||||
texelH = min(texel, texelH);
|
||||
|
||||
blend = texel * Level0Weight;
|
||||
blend = mix(blend, texelA, Level1Weight * BloomScale);
|
||||
blend = mix(blend, texelB, Level2Weight * BloomScale);
|
||||
blend = mix(blend, texelC, Level3Weight * BloomScale);
|
||||
blend = mix(blend, texelD, Level4Weight * BloomScale);
|
||||
blend = mix(blend, texelE, Level5Weight * BloomScale);
|
||||
blend = mix(blend, texelF, Level6Weight * BloomScale);
|
||||
blend = mix(blend, texelG, Level7Weight * BloomScale);
|
||||
blend = mix(blend, texelH, Level8Weight * BloomScale);
|
||||
}
|
||||
|
||||
FragColor = vec4(blend, 1.0);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:W. M. Martinez
|
||||
//-----------------------------------------------------------------------------
|
||||
// Phosphor Chromaticity to sRGB Transform Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.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;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define mul(a,b) (b*a)
|
||||
|
||||
vec3 YGain = vec3(global.ygain_r, global.ygain_g, global.ygain_b);
|
||||
vec2 ChromaA = vec2(global.chromaa_x, global.chromaa_y);
|
||||
vec2 ChromaB = vec2(global.chromab_x, global.chromab_y);
|
||||
vec2 ChromaC = vec2(global.chromac_x, global.chromac_y);
|
||||
|
||||
const mat3 XYZ_TO_sRGB = mat3(
|
||||
3.2406, -1.5372, -0.4986,
|
||||
-0.9689, 1.8758, 0.0415,
|
||||
0.0557, -0.2040, 1.0570);
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!Chromaticity)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 cin = texture(DiffuseSampler, vTexCoord);
|
||||
vec4 cout = vec4(0.0, 0.0, 0.0, cin.a);
|
||||
mat3x2 xy = { ChromaA, ChromaB, ChromaC };
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
float Y = YGain[i] * cin[i];
|
||||
float X = xy[i].x * (Y / xy[i].y);
|
||||
float Z = (1.0 - xy[i].x - xy[i].y) * (Y / xy[i].y);
|
||||
cout.rgb += mul(XYZ_TO_sRGB, vec3(X, Y, Z));
|
||||
}
|
||||
FragColor = cout;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
//-----------------------------------------------------------------------------
|
||||
// Color-Convolution Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.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;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
vec3 RedRatios = vec3(global.col_red, 0.0, 0.0);
|
||||
vec3 GrnRatios = vec3(0.0, global.col_grn, 0.0);
|
||||
vec3 BluRatios = vec3(0.0, 0.0, global.col_blu);
|
||||
vec3 Offset = vec3(global.col_offset_x, global.col_offset_y, global.col_offset_z);
|
||||
vec3 Scale = vec3(global.col_scale_x, global.col_scale_y, global.col_scale_z);
|
||||
float Saturation = global.col_saturation;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 BaseTexel = texture(DiffuseSampler, vTexCoord);
|
||||
|
||||
vec3 OutRGB = BaseTexel.rgb;
|
||||
|
||||
// RGB Tint & Shift
|
||||
float ShiftedRed = dot(OutRGB, RedRatios);
|
||||
float ShiftedGrn = dot(OutRGB, GrnRatios);
|
||||
float ShiftedBlu = dot(OutRGB, BluRatios);
|
||||
|
||||
// RGB Scale & Offset
|
||||
vec3 OutTexel = vec3(ShiftedRed, ShiftedGrn, ShiftedBlu) * Scale + Offset;
|
||||
|
||||
// Saturation
|
||||
vec3 Grayscale = vec3(0.299f, 0.587f, 0.114f);
|
||||
float OutLuma = dot(OutTexel, Grayscale);
|
||||
vec3 OutChroma = OutTexel - OutLuma;
|
||||
vec3 Saturated = OutLuma + OutChroma * Saturation;
|
||||
|
||||
FragColor = vec4(Saturated, BaseTexel.a);
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deconvergence Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
vec3 ConvergeX = vec3(global.converge_x_r, global.converge_x_g, global.converge_x_b);
|
||||
vec3 ConvergeY = vec3(global.converge_y_r, global.converge_y_g, global.converge_y_b);
|
||||
vec3 RadialConvergeX = vec3(global.radial_conv_x_r, global.radial_conv_x_g, global.radial_conv_x_b);
|
||||
vec3 RadialConvergeY = vec3(global.radial_conv_y_r, global.radial_conv_y_g, global.radial_conv_y_b);
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec3 TexCoordX;
|
||||
layout(location = 1) out vec3 TexCoordY;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
|
||||
// imaginary texel dimensions independed from screen dimension, but ratio
|
||||
vec2 TexelDims = vec2(1.0 / 1024.);
|
||||
|
||||
TexCoordX = TexCoord.xxx;
|
||||
TexCoordY = TexCoord.yyy;
|
||||
|
||||
// center coordinates
|
||||
TexCoordX -= 0.5;
|
||||
TexCoordY -= 0.5;
|
||||
|
||||
// radial converge offset to "translate" the most outer pixel as thay would be translated by the linar converge with the same amount
|
||||
vec2 radialConvergeOffset = vec2(2.0);
|
||||
|
||||
// radial converge
|
||||
TexCoordX *= 1.0 + RadialConvergeX * TexelDims.xxx * radialConvergeOffset.xxx;
|
||||
TexCoordY *= 1.0 + RadialConvergeY * TexelDims.yyy * radialConvergeOffset.yyy;
|
||||
|
||||
// un-center coordinates
|
||||
TexCoordX += 0.5;
|
||||
TexCoordY += 0.5;
|
||||
|
||||
// linear converge
|
||||
TexCoordX += ConvergeX * TexelDims.xxx;
|
||||
TexCoordY += ConvergeY * TexelDims.yyy;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec3 TexCoordX;
|
||||
layout(location = 1) in vec3 TexCoordY;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
void main()
|
||||
{
|
||||
float r = texture(DiffuseSampler, vec2(TexCoordX.x, TexCoordY.x)).r;
|
||||
float g = texture(DiffuseSampler, vec2(TexCoordX.y, TexCoordY.y)).g;
|
||||
float b = texture(DiffuseSampler, vec2(TexCoordX.z, TexCoordY.z)).b;
|
||||
|
||||
FragColor = vec4(r, g, b, 1.0);
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Distortion Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
#define saturate(c) clamp(c, 0.0, 1.0)
|
||||
#define mul(a,b) (b*a)
|
||||
const int ScreenCount = 1;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float Epsilon = 1.0e-7;
|
||||
const float PI = 3.1415927;
|
||||
const float E = 2.7182817;
|
||||
const float Gelfond = 23.140692; // e^pi (Gelfond constant)
|
||||
const float GelfondSchneider = 2.6651442; // 2^sqrt(2) (Gelfond-Schneider constant)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
|
||||
float random(vec2 seed)
|
||||
{
|
||||
// irrationals for pseudo randomness
|
||||
vec2 i = vec2(Gelfond, GelfondSchneider);
|
||||
|
||||
return fract(cos(dot(seed, i)) * 123456.0);
|
||||
}
|
||||
|
||||
// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
|
||||
float normalizedSigmoid(float n, float k)
|
||||
{
|
||||
// valid for n and k in range of -1.0 and 1.0
|
||||
return (n - n * k) / (k - abs(n) * 2.0 * k + 1);
|
||||
}
|
||||
|
||||
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
float roundBox(vec2 p, vec2 b, float r)
|
||||
{
|
||||
return length(max(abs(p) - b + r, 0.0)) - r;
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
float DistortionAmount = global.distortion_amount; // k - quartic distortion coefficient
|
||||
float CubicDistortionAmount = global.cubic_distortion_amount; // kcube - cubic distortion modifier
|
||||
float DistortCornerAmount = global.distort_corner_amount;
|
||||
float RoundCornerAmount = global.round_corner_amount;
|
||||
float SmoothBorderAmount = global.smooth_border_amount;
|
||||
float VignettingAmount = global.vignette_amount;
|
||||
float ReflectionAmount = global.reflection_amount;
|
||||
vec3 LightReflectionColor = vec3(global.reflection_col_r, global.reflection_col_g, global.reflection_col_b); // color temperature 5.000 Kelvin
|
||||
|
||||
vec2 QuadDims = params.OutputSize.xy;
|
||||
vec2 TargetDims = params.FinalViewportSize.xy;
|
||||
float TargetScale = 1.0;
|
||||
|
||||
float GetNoiseFactor(vec3 n, float random)
|
||||
{
|
||||
// smaller n become more noisy
|
||||
return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n.x));
|
||||
}
|
||||
|
||||
float GetVignetteFactor(vec2 coord, float amount)
|
||||
{
|
||||
vec2 VignetteCoord = coord;
|
||||
|
||||
float VignetteLength = length(VignetteCoord);
|
||||
float VignetteBlur = (amount * 0.75f) + 0.25;
|
||||
|
||||
// 0.5 full screen fitting circle
|
||||
float VignetteRadius = 1.0f - (amount * 0.25f);
|
||||
float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength);
|
||||
|
||||
return saturate(Vignette);
|
||||
}
|
||||
|
||||
float GetSpotAddend(vec2 coord, float amount)
|
||||
{
|
||||
vec2 SpotCoord = coord;
|
||||
|
||||
// upper right quadrant
|
||||
vec2 spotOffset = vec2(-0.25f, 0.25f);
|
||||
|
||||
// normalized screen canvas ratio
|
||||
vec2 CanvasRatio = SwapXY
|
||||
? vec2(1.0f, QuadDims.x / QuadDims.y)
|
||||
: vec2(1.0f, QuadDims.y / QuadDims.x);
|
||||
|
||||
SpotCoord += spotOffset;
|
||||
SpotCoord *= CanvasRatio;
|
||||
|
||||
float SpotBlur = amount;
|
||||
|
||||
// 0.5 full screen fitting circle
|
||||
float SpotRadius = amount * 0.75f;
|
||||
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
|
||||
|
||||
float SigmoidSpot = amount * normalizedSigmoid(Spot, 0.75);
|
||||
|
||||
// increase strength by 100%
|
||||
SigmoidSpot = SigmoidSpot * 2.0f;
|
||||
|
||||
return saturate(SigmoidSpot);
|
||||
}
|
||||
|
||||
float GetBoundsFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount)
|
||||
{
|
||||
// reduce smooth amount down to radius amount
|
||||
smoothAmount = min(smoothAmount, radiusAmount);
|
||||
|
||||
float range = min(bounds.x, bounds.y);
|
||||
float amountMinimum = 1.0f / range;
|
||||
float radius = range * max(radiusAmount, amountMinimum);
|
||||
float smooth_ = 1.0f / (range * max(smoothAmount, amountMinimum * 2.0f));
|
||||
|
||||
// compute box
|
||||
float box = roundBox(bounds * (coord * 2.0f), bounds, radius);
|
||||
|
||||
// apply smooth
|
||||
box *= smooth_;
|
||||
box += 1.0f - pow(smooth_ * 0.5f, 0.5f);
|
||||
|
||||
float border = smoothstep(1.0f, 0.0f, box);
|
||||
|
||||
return saturate(border);
|
||||
}
|
||||
|
||||
// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/
|
||||
vec2 GetDistortedCoords(vec2 centerCoord, float amount, float amountCube)
|
||||
{
|
||||
// lens distortion coefficient
|
||||
float k = amount;
|
||||
|
||||
// cubic distortion value
|
||||
float kcube = amountCube;
|
||||
|
||||
// compute cubic distortion factor
|
||||
float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y;
|
||||
float f = kcube == 0.0f
|
||||
? 1.0f + r2 * k
|
||||
: 1.0f + r2 * (k + kcube * sqrt(r2));
|
||||
|
||||
// fit screen bounds
|
||||
f /= 1.0f + amount * 0.25f + amountCube * 0.125f;
|
||||
|
||||
// apply cubic distortion factor
|
||||
centerCoord *= f;
|
||||
|
||||
return centerCoord;
|
||||
}
|
||||
|
||||
vec2 GetTextureCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5f;
|
||||
|
||||
// distort coordinates
|
||||
coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount);
|
||||
|
||||
// un-center coordinates
|
||||
coord += 0.5f;
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
vec2 GetQuadCoords(vec2 coord, vec2 scale, float distortionAmount, float cubicDistortionAmount)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5f;
|
||||
|
||||
// apply scale
|
||||
coord *= scale;
|
||||
|
||||
// distort coordinates
|
||||
coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount);
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!Distortion)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// image distortion
|
||||
float distortionAmount = DistortionAmount;
|
||||
float cubicDistortionAmount = CubicDistortionAmount > 0.0f
|
||||
? CubicDistortionAmount * 1.1f // cubic distortion need to be a little higher to compensate the quartic distortion
|
||||
: CubicDistortionAmount * 1.2f; // negativ values even more
|
||||
|
||||
// corner distortion at least by the amount of the image distorition
|
||||
float distortCornerAmount = max(DistortCornerAmount, DistortionAmount + CubicDistortionAmount);
|
||||
|
||||
float roundCornerAmount = RoundCornerAmount * 0.5f;
|
||||
float smoothBorderAmount = SmoothBorderAmount * 0.5f;
|
||||
|
||||
vec2 TexelDims = 1.0f / TargetDims;
|
||||
|
||||
// base-target dimensions (without oversampling)
|
||||
vec2 BaseTargetDims = TargetDims / TargetScale;
|
||||
BaseTargetDims = SwapXY
|
||||
? BaseTargetDims.yx
|
||||
: BaseTargetDims.xy;
|
||||
|
||||
// base-target/quad difference scale
|
||||
vec2 BaseTargetQuadScale = (ScreenCount == 1)
|
||||
? BaseTargetDims / QuadDims // keeps the coords inside of the quad bounds of a single screen
|
||||
: vec2(1.0);
|
||||
|
||||
// Screen Texture Curvature
|
||||
vec2 BaseCoord = GetTextureCoords(vTexCoord, distortionAmount, cubicDistortionAmount);
|
||||
|
||||
// Screen Quad Curvature
|
||||
vec2 QuadCoord = GetQuadCoords(vTexCoord, BaseTargetQuadScale, distortCornerAmount, 0.0f);
|
||||
/*
|
||||
// clip border
|
||||
if (BaseCoord.x < 0.0f - TexelDims.x || BaseCoord.y < 0.0f - TexelDims.y ||
|
||||
BaseCoord.x > 1.0f + TexelDims.x || BaseCoord.y > 1.0f + TexelDims.y)
|
||||
{
|
||||
// we don't use the clip function, because we don't clear the render target before
|
||||
return vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
*/
|
||||
|
||||
// Color
|
||||
vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
|
||||
BaseColor.a = 1.0f;
|
||||
|
||||
// Vignetting Simulation
|
||||
vec2 VignetteCoord = QuadCoord;
|
||||
|
||||
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
|
||||
BaseColor.rgb *= VignetteFactor;
|
||||
|
||||
// Light Reflection Simulation
|
||||
vec2 SpotCoord = QuadCoord;
|
||||
|
||||
vec3 SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount) * LightReflectionColor;
|
||||
BaseColor.rgb += SpotAddend * GetNoiseFactor(SpotAddend, random(SpotCoord));
|
||||
|
||||
// Round Corners Simulation
|
||||
vec2 RoundCornerCoord = QuadCoord;
|
||||
vec2 RoundCornerBounds = (ScreenCount == 1)
|
||||
? QuadDims // align corners to quad bounds of a single screen
|
||||
: BaseTargetDims; // align corners to target bounds of multiple screens
|
||||
RoundCornerBounds = SwapXY
|
||||
? RoundCornerBounds.yx
|
||||
: RoundCornerBounds.xy;
|
||||
|
||||
float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount);
|
||||
BaseColor.rgb *= roundCornerFactor;
|
||||
|
||||
FragColor = BaseColor;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Downsample Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
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 vec4 TexCoord01;
|
||||
layout(location = 1) out vec4 TexCoord23;
|
||||
|
||||
const vec2 Coord0Offset = vec2(-0.5, -0.5);
|
||||
const vec2 Coord1Offset = vec2( 0.5, -0.5);
|
||||
const vec2 Coord2Offset = vec2(-0.5, 0.5);
|
||||
const vec2 Coord3Offset = vec2( 0.5, 0.5);
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
|
||||
vec2 HalfTargetTexelDims = 0.5 * params.SourceSize.zw;
|
||||
|
||||
TexCoord01.xy = TexCoord + Coord0Offset * HalfTargetTexelDims;
|
||||
TexCoord01.zw = TexCoord + Coord1Offset * HalfTargetTexelDims;
|
||||
TexCoord23.xy = TexCoord + Coord2Offset * HalfTargetTexelDims;
|
||||
TexCoord23.zw = TexCoord + Coord3Offset * HalfTargetTexelDims;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec4 TexCoord01;
|
||||
layout(location = 1) in vec4 TexCoord23;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 texel0 = texture(DiffuseSampler, TexCoord01.xy).rgb;
|
||||
vec3 texel1 = texture(DiffuseSampler, TexCoord01.zw).rgb;
|
||||
vec3 texel2 = texture(DiffuseSampler, TexCoord23.xy).rgb;
|
||||
vec3 texel3 = texture(DiffuseSampler, TexCoord23.zw).rgb;
|
||||
|
||||
vec3 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0;
|
||||
|
||||
FragColor = vec4(outTexel, 1.0);
|
||||
}
|
@ -0,0 +1,294 @@
|
||||
layout(std140, set = 0, binding = 0) uniform UBO
|
||||
{
|
||||
mat4 MVP;
|
||||
// effect toggles and multi
|
||||
float bloomtoggle;
|
||||
float ntscsignal;
|
||||
float scanlinetoggle;
|
||||
float chromatoggle;
|
||||
float distortiontoggle;
|
||||
float screenscale_x;
|
||||
float screenscale_y;
|
||||
float screenoffset_x;
|
||||
float screenoffset_y;
|
||||
float swapxy;
|
||||
// bloom params
|
||||
float bloomblendmode;
|
||||
// float vectorscreen;
|
||||
float bloomscale;
|
||||
float bloomoverdrive_r;
|
||||
float bloomoverdrive_g;
|
||||
float bloomoverdrive_b;
|
||||
float level0weight;
|
||||
float level1weight;
|
||||
float level2weight;
|
||||
float level3weight;
|
||||
float level4weight;
|
||||
float level5weight;
|
||||
float level6weight;
|
||||
float level7weight;
|
||||
float level8weight;
|
||||
// post params
|
||||
float mask_width;
|
||||
float mask_height;
|
||||
float mask_offset_x;
|
||||
float mask_offset_y;
|
||||
float preparebloom;
|
||||
float shadowtilemode;
|
||||
float power_r;
|
||||
float power_g;
|
||||
float power_b;
|
||||
float floor_r;
|
||||
float floor_g;
|
||||
float floor_b;
|
||||
float chromamode;
|
||||
float conversiongain_x;
|
||||
float conversiongain_y;
|
||||
float conversiongain_z;
|
||||
float humbaralpha;
|
||||
float backcolor_r;
|
||||
float backcolor_g;
|
||||
float backcolor_b;
|
||||
float shadowalpha;
|
||||
float shadowcount_x;
|
||||
float shadowcount_y;
|
||||
float shadowuv_x;
|
||||
float shadowuv_y;
|
||||
// ntsc params
|
||||
float avalue;
|
||||
float bvalue;
|
||||
float ccvalue;
|
||||
float ovalue;
|
||||
float pvalue;
|
||||
float scantime;
|
||||
float notchhalfwidth;
|
||||
float yfreqresponse;
|
||||
float ifreqresponse;
|
||||
float qfreqresponse;
|
||||
float signaloffset;
|
||||
// color params
|
||||
float col_red;
|
||||
float col_grn;
|
||||
float col_blu;
|
||||
float col_offset_x;
|
||||
float col_offset_y;
|
||||
float col_offset_z;
|
||||
float col_scale_x;
|
||||
float col_scale_y;
|
||||
float col_scale_z;
|
||||
float col_saturation;
|
||||
// deconverge params
|
||||
float converge_x_r;
|
||||
float converge_x_g;
|
||||
float converge_x_b;
|
||||
float converge_y_r;
|
||||
float converge_y_g;
|
||||
float converge_y_b;
|
||||
float radial_conv_x_r;
|
||||
float radial_conv_x_g;
|
||||
float radial_conv_x_b;
|
||||
float radial_conv_y_r;
|
||||
float radial_conv_y_g;
|
||||
float radial_conv_y_b;
|
||||
// scanline params
|
||||
float scanlinealpha;
|
||||
float scanlinescale;
|
||||
float scanlineheight;
|
||||
float scanlinevariation;
|
||||
float scanlineoffset;
|
||||
float scanlinebrightscale;
|
||||
float scanlinebrightoffset;
|
||||
// defocus params
|
||||
float defocus_x;
|
||||
float defocus_y;
|
||||
// phosphor params
|
||||
float deltatime;
|
||||
float phosphor_r;
|
||||
float phosphor_g;
|
||||
float phosphor_b;
|
||||
float phosphortoggle;
|
||||
// chroma params
|
||||
float ygain_r;
|
||||
float ygain_g;
|
||||
float ygain_b;
|
||||
float chromaa_x;
|
||||
float chromaa_y;
|
||||
float chromab_x;
|
||||
float chromab_y;
|
||||
float chromac_x;
|
||||
float chromac_y;
|
||||
// distortion params
|
||||
float distortion_amount;
|
||||
float cubic_distortion_amount;
|
||||
float distort_corner_amount;
|
||||
float round_corner_amount;
|
||||
float smooth_border_amount;
|
||||
float vignette_amount;
|
||||
float reflection_amount;
|
||||
float reflection_col_r;
|
||||
float reflection_col_g;
|
||||
float reflection_col_b;
|
||||
// vector params
|
||||
// float timeratio;
|
||||
// float timescale;
|
||||
// float lengthratio;
|
||||
// float lengthscale;
|
||||
// float beamsmooth;
|
||||
} global;
|
||||
|
||||
// Effect Toggles and Settings Used In Multiple Passes
|
||||
#pragma parameter ntscsignal "NTSC Signal Mode" 0.0 0.0 1.0 1.01.0
|
||||
bool NTSCSignal = bool(global.ntscsignal);
|
||||
#pragma parameter scanlinetoggle "Scanline Toggle" 1.0 0.0 1.0 1.0
|
||||
bool ScanlineToggle = bool(global.scanlinetoggle);
|
||||
#pragma parameter bloomtoggle "Bloom Enable" 0.0 0.0 1.0 1.0
|
||||
bool BloomToggle = bool(global.bloomtoggle);
|
||||
#pragma parameter chromatoggle "Chromaticity Toggle" 0.0 0.0 1.0 1.0
|
||||
bool Chromaticity = bool(global.chromatoggle);
|
||||
#pragma parameter distortiontoggle "Distortion Toggle" 0.0 0.0 1.0 1.0
|
||||
bool Distortion = bool(global.distortiontoggle);
|
||||
#pragma parameter phosphortoggle "Phosphor Toggle" 0.0 0.0 1.0 1.0
|
||||
bool Passthrough = !bool(global.phosphortoggle);
|
||||
#pragma parameter screenscale_x "Screen Scale X" 1.0 0.5 3.0 0.01
|
||||
#pragma parameter screenscale_y "Screen Scale Y" 1.0 0.5 3.0 0.01
|
||||
vec2 ScreenScale = vec2(global.screenscale_x, global.screenscale_y);
|
||||
//#pragma parameter vectorscreen "Vector Screen Mode" 0.0 0.0 1.0 1.0 // TODO/FIXME
|
||||
const float vectorscreen = 0.0;
|
||||
bool VectorScreen = bool(vectorscreen);
|
||||
|
||||
#pragma parameter screenoffset_x "Screen Offset X" 0.0 -1.0 1.0 0.005
|
||||
#pragma parameter screenoffset_y "Screen Offset Y" 0.0 -1.0 1.0 0.005
|
||||
vec2 ScreenOffset = vec2(global.screenoffset_x, global.screenoffset_y);
|
||||
#pragma parameter swapxy "Swap X and Y" 0.0 0.0 1.0 1.0
|
||||
bool SwapXY = bool(global.swapxy);
|
||||
|
||||
// Bloom Pass
|
||||
#pragma parameter bloomblendmode "Bloom Blend Mode" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter bloomscale "Bloom Scale" 0.33 0.0 1.0 0.01
|
||||
#pragma parameter bloomoverdrive_r "Bloom Overdrive R" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter bloomoverdrive_g "Bloom Overdrive G" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter bloomoverdrive_b "Bloom Overdrive B" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter level0weight "Bloom Level 0 Weight" 0.64 0.0 1.0 0.01
|
||||
#pragma parameter level1weight "Bloom Level 1 Weight" 0.64 0.0 1.0 0.01
|
||||
#pragma parameter level2weight "Bloom Level 2 Weight" 0.32 0.0 1.0 0.01
|
||||
#pragma parameter level3weight "Bloom Level 3 Weight" 0.16 0.0 1.0 0.01
|
||||
#pragma parameter level4weight "Bloom Level 4 Weight" 0.08 0.0 1.0 0.01
|
||||
#pragma parameter level5weight "Bloom Level 5 Weight" 0.06 0.0 1.0 0.01
|
||||
#pragma parameter level6weight "Bloom Level 6 Weight" 0.04 0.0 1.0 0.01
|
||||
#pragma parameter level7weight "Bloom Level 7 Weight" 0.02 0.0 1.0 0.01
|
||||
#pragma parameter level8weight "Bloom Level 8 Weight" 0.01 0.0 1.0 0.01
|
||||
|
||||
// Post Pass
|
||||
#pragma parameter humbaralpha "Hum Bar Alpha" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter backcolor_r "Back Color R" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter backcolor_g "Back Color G" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter backcolor_b "Back Color B" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter shadowtilemode "Mask Tiling Mode" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter shadowalpha "Mask Alpha" 0.3 0.0 1.0 0.01
|
||||
#pragma parameter shadowcount_x "Mask Tile Size X" 6.0 1.0 32.0 1.0
|
||||
#pragma parameter shadowcount_y "Mask Tile Size Y" 6.0 1.0 32.0 1.0
|
||||
#pragma parameter shadowuv_x "Mask UV X" 0.25 0.0 1.0 0.01
|
||||
#pragma parameter shadowuv_y "Mask UV Y" 0.25 0.0 1.0 0.01
|
||||
#pragma parameter mask_width "Mask Texture Width" 32.0 0.0 256.0 16.0
|
||||
#pragma parameter mask_height "Mask Texture Height" 32.0 0.0 256.0 16.0
|
||||
#pragma parameter mask_offset_x "Mask Offset X" 0.0 -10.0 10.0 0.1
|
||||
#pragma parameter mask_offset_y "Mask Offset Y" 0.0 -10.0 10.0 0.1
|
||||
#pragma parameter chromamode "Chroma Mode" 3.0 1.0 3.0 1.0
|
||||
#pragma parameter conversiongain_x "Conversion Gain X" 0.0 -5.0 5.0 0.5
|
||||
#pragma parameter conversiongain_y "Conversion Gain Y" 0.0 -5.0 5.0 0.5
|
||||
#pragma parameter conversiongain_z "Conversion Gain Z" 0.0 -5.0 5.0 0.5
|
||||
#pragma parameter power_r "Color Power R" 1.0 1.0 10.0 1.0
|
||||
#pragma parameter power_g "Color Power G" 1.0 1.0 10.0 1.0
|
||||
#pragma parameter power_b "Color Power B" 1.0 1.0 10.0 1.0
|
||||
#pragma parameter floor_r "Color Floor R" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter floor_g "Color Floor G" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter floor_b "Color Floor B" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter preparebloom "Prepare Bloom" 0.0 0.0 1.0 1.0
|
||||
|
||||
// NTSC Pass
|
||||
#pragma parameter avalue "A Value" 0.5 -1.0 1.0 0.01
|
||||
#pragma parameter bvalue "B Value" 0.5 -1.0 1.0 0.01
|
||||
#pragma parameter ccvalue "CC Value" 3.5795454 0.0 6.0 0.0005
|
||||
#pragma parameter ovalue "O Value" 0.0 -3.0 3.0 0.1
|
||||
#pragma parameter pvalue "P Value" 1.0 -3.0 3.0 0.1
|
||||
#pragma parameter scantime "Scan Time" 52.6 0.0 100.0 0.1
|
||||
#pragma parameter notchhalfwidth "Notch Half Width" 1.0 0.0 6.0 0.05
|
||||
#pragma parameter yfreqresponse "Y Freq Response" 6.0 0.0 6.0 0.05
|
||||
#pragma parameter ifreqresponse "I Freq Response" 1.2 0.0 6.0 0.05
|
||||
#pragma parameter qfreqresponse "Q Freq Response" 0.6 0.0 6.0 0.05
|
||||
#pragma parameter signaloffset "Signal Offset" 1.0 0.0 1.0 0.01
|
||||
|
||||
// Color Pass
|
||||
#pragma parameter col_red "Red Shift" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_grn "Green Shift" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_blu "Blue Shift" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_offset_x "Offset X" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter col_offset_y "Offset Y" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter col_offset_z "Offset Z" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter col_scale_x "Scale X" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_y "Scale Y" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_scale_z "Scale Z" 1.0 0.0 2.0 0.01
|
||||
#pragma parameter col_saturation "Saturation" 1.0 0.0 5.0 0.01
|
||||
|
||||
// Deconverge Pass
|
||||
#pragma parameter converge_x_r "Convergence X Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_x_g "Convergence X Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_x_b "Convergence X Blue" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_y_r "Convergence Y Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_y_g "Convergence Y Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter converge_y_b "Convergence Y Blue" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_r "Radial Conv X Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_g "Radial Conv X Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_x_b "Radial Conv X Blue" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_y_r "Radial Conv Y Red" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_y_g "Radial Conv Y Green" 0.0 -10.0 10.0 0.05
|
||||
#pragma parameter radial_conv_y_b "Radial Conv Y Blue" 0.0 -10.0 10.0 0.05
|
||||
|
||||
// Scanline Pass
|
||||
#pragma parameter scanlinealpha "Scanline Alpha" 0.5 0.0 1.0 0.01
|
||||
#pragma parameter scanlinescale "Scanline Scale" 5.0 1.0 5.0 1.0
|
||||
#pragma parameter scanlineheight "Scanline Height" 1.0 0.0 2.0 0.1
|
||||
#pragma parameter scanlinevariation "Scanline Variation" 1.0 0.0 5.0 0.5
|
||||
#pragma parameter scanlineoffset "Scanline Offset" 1.0 -1.5 3.0 0.1
|
||||
#pragma parameter scanlinebrightscale "Scanline Bright Scale" 1.0 0.0 2.0 0.1
|
||||
#pragma parameter scanlinebrightoffset "Scanline Bright Offset" 1.0 -1.5 3.0 0.1
|
||||
|
||||
// Defocus Pass
|
||||
#pragma parameter defocus_x "Defocus X Axis" 0.0 0.0 10.0 0.1
|
||||
#pragma parameter defocus_y "Defocus Y Axis" 0.0 0.0 10.0 0.1
|
||||
|
||||
// Phosphor Pass
|
||||
#pragma parameter deltatime "Delta Time" 1.0 0.0 2.0 0.1
|
||||
#pragma parameter phosphor_r "Phosphor Red" 0.8 0.0 0.99 0.1
|
||||
#pragma parameter phosphor_g "Phosphor Green" 0.0 0.0 0.99 0.1
|
||||
#pragma parameter phosphor_b "Phosphor Blue" 0.0 0.0 0.99 0.1
|
||||
|
||||
// Chroma Pass
|
||||
#pragma parameter ygain_r "Y Gain R Channel" 0.2126 0.0 1.0 0.01
|
||||
#pragma parameter ygain_g "Y Gain G Channel" 0.7152 0.0 1.0 0.01
|
||||
#pragma parameter ygain_b "Y Gain B Channel" 0.0722 0.0 1.0 0.01
|
||||
#pragma parameter chromaa_x "Chroma A X" 0.630 0.0 1.0 0.01
|
||||
#pragma parameter chromaa_y "Chroma A Y" 0.340 0.0 1.0 0.01
|
||||
#pragma parameter chromab_x "Chroma B X" 0.310 0.0 1.0 0.01
|
||||
#pragma parameter chromab_y "Chroma B Y" 0.595 0.0 1.0 0.01
|
||||
#pragma parameter chromac_x "Chroma C X" 0.155 0.0 1.0 0.01
|
||||
#pragma parameter chromac_y "Chroma C Y" 0.070 0.0 1.0 0.01
|
||||
|
||||
// Distortion Pass
|
||||
#pragma parameter distortion_amount "Distortion Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter cubic_distortion_amount "Cubic Dist. Amt" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter distort_corner_amount "Corner Dist. Amt" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter round_corner_amount "Corner Rounding" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter smooth_border_amount "Border Smoothing" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter vignette_amount "Vignetting Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter reflection_amount "Reflection Amount" 0.0 0.0 1.0 0.01
|
||||
#pragma parameter reflection_col_r "Reflection Color R" 1.0 0.0 1.0 0.01
|
||||
#pragma parameter reflection_col_g "Reflection Color G" 0.9 0.0 1.0 0.01
|
||||
#pragma parameter reflection_col_b "Reflection Color B" 0.8 0.0 1.0 0.01
|
||||
|
||||
// Vector Pass
|
||||
//#pragma parameter timeratio "Time Ratio" 1.0 0.0 2.0 0.01
|
||||
//#pragma parameter timescale "Time Scale" 1.0 1.0 10.0 1.0
|
||||
//#pragma parameter lengthratio "Length Ratio" 1.0 1.0 10.0 1.0
|
||||
//#pragma parameter lengthscale "Length Scale" 1.0 1.0 10.0 1.0
|
||||
//#pragma parameter beamsmooth "Beam Smooth Amt" 0.5 0.1 1.0 0.1
|
@ -0,0 +1,56 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
//-----------------------------------------------------------------------------
|
||||
// Phosphor Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
float DeltaTime = global.deltatime;
|
||||
vec3 Phosphor = vec3(global.phosphor_r, global.phosphor_g, global.phosphor_b);
|
||||
|
||||
const float F = 1.0;
|
||||
|
||||
#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 PassFeedback6;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define PreviousSampler PassFeedback6
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 CurrY = texture(DiffuseSampler, vTexCoord);
|
||||
vec3 PrevY = texture(PreviousSampler, vTexCoord).rgb;
|
||||
|
||||
PrevY[0] *= (Phosphor[0] == 0.0) ? 0.0 : pow(Phosphor[0], F * DeltaTime);
|
||||
PrevY[1] *= (Phosphor[1] == 0.0) ? 0.0 : pow(Phosphor[1], F * DeltaTime);
|
||||
PrevY[2] *= (Phosphor[2] == 0.0) ? 0.0 : pow(Phosphor[2], F * DeltaTime);
|
||||
float a = max(PrevY[0], CurrY[0]);
|
||||
float b = max(PrevY[1], CurrY[1]);
|
||||
float c = max(PrevY[2], CurrY[2]);
|
||||
FragColor = Passthrough ? CurrY : vec4(a, b, c, CurrY.a);
|
||||
}
|
@ -0,0 +1,197 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shadowmask Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
#define TargetDims params.OutputSize.xy
|
||||
#define SourceDims params.OriginalSize.xy
|
||||
float TargetScale = 1.0;//max(TargetDims.x / SourceDims.x, TargetDims.y / SourceDims.y);
|
||||
|
||||
float HumBarAlpha = global.humbaralpha;
|
||||
float TimeMilliseconds = float(mod(params.FrameCount, 1000));
|
||||
vec3 BackColor = vec3(global.backcolor_r, global.backcolor_g, global.backcolor_b);
|
||||
int ShadowTileMode = int(global.shadowtilemode); // 0 based on screen (quad) dimension, 1 based on source dimension
|
||||
float ShadowAlpha = global.shadowalpha;
|
||||
vec2 ShadowCount = vec2(global.shadowcount_x, global.shadowcount_y);
|
||||
vec2 ShadowUV = vec2(global.shadowuv_x, global.shadowuv_y);
|
||||
vec2 ShadowDims = vec2(global.mask_width, global.mask_height);
|
||||
vec2 ShadowUVOffset = vec2(global.mask_offset_x, global.mask_offset_y);
|
||||
int ChromaMode = int(global.chromamode);
|
||||
vec3 ConversionGain = vec3(global.conversiongain_x, global.conversiongain_y, global.conversiongain_z);
|
||||
vec3 Power = vec3(global.power_r, global.power_g, global.power_b);
|
||||
vec3 Floor = vec3(global.floor_r, global.floor_g, global.floor_b);
|
||||
bool PrepareBloom = bool(global.preparebloom);
|
||||
|
||||
#define MONOCHROME 1
|
||||
#define DICHROME 2
|
||||
#define TRICHROME 3
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float HalfPI = PI * 0.5;
|
||||
|
||||
float HumBarDesync = 60.0 / 59.94 - 1.0; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
|
||||
|
||||
vec2 GetAdjustedCoords(vec2 coord)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5;
|
||||
|
||||
// apply screen scale
|
||||
coord *= ScreenScale;
|
||||
|
||||
// un-center coordinates
|
||||
coord += 0.5;
|
||||
|
||||
// apply screen offset
|
||||
coord += ScreenOffset;
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
vec2 GetShadowCoord(vec2 TargetCoord, vec2 SourceCoord)
|
||||
{
|
||||
// base-target dimensions (without oversampling)
|
||||
vec2 BaseTargetDims = TargetDims / TargetScale;
|
||||
BaseTargetDims = SwapXY
|
||||
? BaseTargetDims.yx
|
||||
: BaseTargetDims.xy;
|
||||
|
||||
vec2 canvasCoord = ShadowTileMode == 0
|
||||
? TargetCoord + ShadowUVOffset / BaseTargetDims
|
||||
: SourceCoord + ShadowUVOffset / SourceDims;
|
||||
vec2 canvasTexelDims = ShadowTileMode == 0
|
||||
? 1.0 / BaseTargetDims
|
||||
: 1.0 / SourceDims;
|
||||
|
||||
vec2 shadowDims = ShadowDims;
|
||||
vec2 shadowUV = ShadowUV;
|
||||
vec2 shadowCount = ShadowCount;
|
||||
|
||||
// swap x/y in screen mode (not source mode)
|
||||
canvasCoord = ShadowTileMode == 0 && SwapXY
|
||||
? canvasCoord.yx
|
||||
: canvasCoord.xy;
|
||||
|
||||
// swap x/y in screen mode (not source mode)
|
||||
shadowCount = ShadowTileMode == 0 && SwapXY
|
||||
? shadowCount.yx
|
||||
: shadowCount.xy;
|
||||
|
||||
vec2 shadowTile = canvasTexelDims * shadowCount;
|
||||
|
||||
vec2 shadowFrac = fract(canvasCoord / shadowTile);
|
||||
|
||||
// swap x/y in screen mode (not source mode)
|
||||
shadowFrac = ShadowTileMode == 0 && SwapXY
|
||||
? shadowFrac.yx
|
||||
: shadowFrac.xy;
|
||||
|
||||
vec2 shadowCoord = (shadowFrac * shadowUV);
|
||||
shadowCoord += ShadowTileMode == 0
|
||||
? vec2(0.5) * (vec2(1.0) / shadowDims) // fix half texel offset (DX9)
|
||||
: vec2(0.0);
|
||||
|
||||
return shadowCoord;
|
||||
}
|
||||
|
||||
#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 MaskTexture;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define ShadowSampler MaskTexture
|
||||
//#define ScreenCoord vTexCoord
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 ScreenCoord = vTexCoord;
|
||||
vec2 BaseCoord = GetAdjustedCoords(ScreenCoord);
|
||||
|
||||
// Color
|
||||
vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
|
||||
BaseColor.a = 1.0;
|
||||
/*
|
||||
// clip border
|
||||
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 ||
|
||||
BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
|
||||
{
|
||||
// we don't use the clip function, because we don't clear the render target before
|
||||
return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
*/
|
||||
// Color Compression (may not affect bloom)
|
||||
if (!PrepareBloom)
|
||||
{
|
||||
// increasing the floor of the signal without affecting the ceiling
|
||||
BaseColor.rgb = Floor + (1.0f - Floor) * BaseColor.rgb;
|
||||
}
|
||||
|
||||
// Color Power (may affect bloom)
|
||||
BaseColor.r = pow(BaseColor.r, Power.r);
|
||||
BaseColor.g = pow(BaseColor.g, Power.g);
|
||||
BaseColor.b = pow(BaseColor.b, Power.b);
|
||||
|
||||
// Hum Bar Simulation (may not affect vector screen)
|
||||
if (!PrepareBloom && !VectorScreen && HumBarAlpha > 0.0)
|
||||
{
|
||||
float HumBarStep = fract(TimeMilliseconds * HumBarDesync);
|
||||
float HumBarBrightness = 1.0 - fract(BaseCoord.y + HumBarStep) * HumBarAlpha;
|
||||
BaseColor.rgb *= HumBarBrightness;
|
||||
}
|
||||
|
||||
// Mask Simulation (may not affect bloom)
|
||||
if (!PrepareBloom && ShadowAlpha > 0.0)
|
||||
{
|
||||
vec2 ShadowCoord = GetShadowCoord(ScreenCoord, BaseCoord);
|
||||
|
||||
vec4 ShadowColor = texture(ShadowSampler, ShadowCoord);
|
||||
vec3 ShadowMaskColor = mix(vec3(1.0), ShadowColor.rgb, ShadowAlpha);
|
||||
float ShadowMaskClear = (1.0 - ShadowColor.a) * ShadowAlpha;
|
||||
|
||||
// apply shadow mask color
|
||||
BaseColor.rgb *= ShadowMaskColor;
|
||||
// clear shadow mask by background color
|
||||
BaseColor.rgb = mix(BaseColor.rgb, BackColor, ShadowMaskClear);
|
||||
}
|
||||
|
||||
// Preparation for phosphor color conversion
|
||||
if (ChromaMode == MONOCHROME) {
|
||||
BaseColor.r = dot(ConversionGain, BaseColor.rgb);
|
||||
BaseColor.gb = vec2(BaseColor.r, BaseColor.r);
|
||||
} else if (ChromaMode == DICHROME) {
|
||||
BaseColor.r = dot(ConversionGain.rg, BaseColor.rg);
|
||||
BaseColor.g = BaseColor.r;
|
||||
}
|
||||
|
||||
FragColor = BaseColor;
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scanline Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
vec4 FinalViewportSize;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float HalfPI = PI * 0.5;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scanline Pixel Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
float ScanlineAlpha = global.scanlinealpha;
|
||||
float ScanlineScale = global.scanlinescale;
|
||||
float ScanlineHeight = global.scanlineheight;
|
||||
float ScanlineVariation = global.scanlinevariation;
|
||||
float ScanlineOffset = global.scanlineoffset;
|
||||
float ScanlineBrightScale = global.scanlinebrightscale;
|
||||
float ScanlineBrightOffset = global.scanlinebrightoffset;
|
||||
|
||||
vec2 QuadDims = params.FinalViewportSize.xy;
|
||||
vec2 SourceDims = params.OriginalSize.xy;
|
||||
|
||||
vec2 GetAdjustedCoords(vec2 coord)
|
||||
{
|
||||
// center coordinates
|
||||
coord -= 0.5;
|
||||
|
||||
// apply screen scale
|
||||
coord *= ScreenScale;
|
||||
|
||||
// un-center coordinates
|
||||
coord += 0.5;
|
||||
|
||||
// apply screen offset
|
||||
coord += ScreenOffset;
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!ScanlineToggle)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec2 BaseCoord = GetAdjustedCoords(vTexCoord);
|
||||
|
||||
// Color
|
||||
vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
|
||||
BaseColor.a = 1.0;
|
||||
/*
|
||||
// clip border
|
||||
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 ||
|
||||
BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
|
||||
{
|
||||
// we don't use the clip function, because we don't clear the render target before
|
||||
return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
*/
|
||||
float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha);
|
||||
float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0 - ScanlineAlpha);
|
||||
|
||||
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
|
||||
|
||||
float ScanlineCoord = BaseCoord.y;
|
||||
ScanlineCoord += (SwapXY)
|
||||
? QuadDims.x <= SourceDims.x * 2.0
|
||||
? 0.5 / QuadDims.x // uncenter scanlines if the quad is less than twice the size of the source
|
||||
: 0.0
|
||||
: QuadDims.y <= SourceDims.y * 2.0
|
||||
? 0.5 / QuadDims.y // uncenter scanlines if the quad is less than twice the size of the source
|
||||
: 0.0;
|
||||
ScanlineCoord *= SourceDims.y * ScanlineScale * PI;
|
||||
|
||||
float ScanlineCoordJitter = ScanlineOffset * HalfPI;
|
||||
float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter);
|
||||
float ScanlineWide = ScanlineHeight + ScanlineVariation * max(1.0f, ScanlineHeight) * (1.0 - ColorBrightness);
|
||||
float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide);
|
||||
float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale;
|
||||
|
||||
BaseColor.rgb *= mix(1.0, ScanlineBrightness, ScanlineAlpha);
|
||||
|
||||
FragColor = BaseColor;
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
#version 450
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
#include "mame_parameters.inc"
|
||||
|
||||
#define saturate(c) clamp(c, 0.0, 1.0)
|
||||
#define TargetDims params.OutputSize.xy
|
||||
#define DiffuseSampler Source
|
||||
|
||||
float TimeRatio = global.timeratio; // Frame time of the vector (not set)
|
||||
float TimeScale = global.timescale; // How much frame time affects the vector's fade (not set)
|
||||
float LengthRatio = global.lengthratio; // Size at which fade is maximum
|
||||
float LengthScale = global.lengthscale; // How much length affects the vector's fade
|
||||
float BeamSmooth = global.beamsmooth;
|
||||
// vec2 SizeInfo;
|
||||
// vec4 Color;
|
||||
|
||||
const vec2 SizeInfo = vec2(1.0);
|
||||
const vec4 Color = vec4(1.0);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
||||
float roundBox(vec2 p, vec2 b, float r)
|
||||
{
|
||||
return length(max(abs(p) - b + r, 0.0f)) - r;
|
||||
}
|
||||
|
||||
float GetBoundsFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount)
|
||||
{
|
||||
// reduce smooth amount down to radius amount
|
||||
smoothAmount = min(smoothAmount, radiusAmount);
|
||||
|
||||
float range = min(bounds.x, bounds.y);
|
||||
float amountMinimum = 1.0f / range;
|
||||
float radius = range * max(radiusAmount, amountMinimum);
|
||||
float smooth_ = 1.0f / (range * max(smoothAmount, amountMinimum * 2.0f));
|
||||
|
||||
// compute box
|
||||
float box = roundBox(bounds * (coord * 2.0f), bounds, radius);
|
||||
|
||||
// apply smooth_
|
||||
box *= smooth_;
|
||||
box += 1.0f - pow(smooth_ * 0.5f, 0.5f);
|
||||
|
||||
float border = smoothstep(1.0f, 0.0f, box);
|
||||
|
||||
return saturate(border);
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!VectorScreen)
|
||||
{
|
||||
FragColor = texture(Source, vTexCoord);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec2 lineSize = SizeInfo / max(TargetDims.x, TargetDims.y); // normalize
|
||||
|
||||
float lineLength = lineSize.x;
|
||||
float lineLengthRatio = params.LengthRatio;
|
||||
float lineLengthScale = params.LengthScale;
|
||||
|
||||
float timeModulate = mix(1.0f, params.TimeRatio, params.TimeScale);
|
||||
float lengthModulate = 1.0f - clamp(lineLength / lineLengthRatio, 0.0f, 1.0f);
|
||||
float timeLengthModulate = mix(1.0f, timeModulate * lengthModulate, params.LengthScale);
|
||||
|
||||
vec4 outColor = vec4(timeLengthModulate, timeLengthModulate, timeLengthModulate, 1.0f);
|
||||
outColor *= Color;
|
||||
|
||||
float RoundCornerFactor = GetBoundsFactor(vTexCoord - 0.5f, SizeInfo, 1.0f, params.BeamSmooth);
|
||||
outColor.rgb *= RoundCornerFactor;
|
||||
FragColor = outColor;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
#version 450
|
||||
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz, W. M. Martinez
|
||||
//-----------------------------------------------------------------------------
|
||||
// Primary Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO
|
||||
{
|
||||
mat4 MVP;
|
||||
} global;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macros
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define LUT_TEXTURE_WIDTH 4096.0f
|
||||
#define LUT_SIZE 64.0f
|
||||
#define LUT_SCALE vec2(1.0f / LUT_TEXTURE_WIDTH, 1.0f / LUT_SIZE)
|
||||
|
||||
#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 MaskTexture;
|
||||
|
||||
#define DiffuseSampler Source
|
||||
#define LutSampler MaskTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utilities
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
vec3 apply_lut(vec3 color)
|
||||
{
|
||||
// NOTE: Do not change the order of parameters here.
|
||||
vec3 lutcoord = vec3((color.rg * (LUT_SIZE - 1.0f) + 0.5f) *
|
||||
LUT_SCALE, color.b * (LUT_SIZE - 1.0f));
|
||||
float shift = floor(lutcoord.z);
|
||||
|
||||
lutcoord.x += shift * LUT_SCALE.y;
|
||||
color.rgb = mix(texture(LutSampler, lutcoord.xy).rgb, texture(LutSampler,
|
||||
float2(lutcoord.x + LUT_SCALE.y, lutcoord.y)).rgb,
|
||||
lutcoord.z - shift);
|
||||
return color;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||
}
|
35
crt/shaders/mame_hlsl/shaders/stock.slang
Normal file
35
crt/shaders/mame_hlsl/shaders/stock.slang
Normal file
@ -0,0 +1,35 @@
|
||||
#version 450
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
} params;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(texture(Source, vTexCoord).rgb, 1.0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user