more work on mame hlsl port

This commit is contained in:
hunterk 2019-03-27 16:28:59 -05:00
parent afb1312303
commit c13d0fda06
20 changed files with 1805 additions and 330 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -10,44 +10,23 @@ layout(push_constant) uniform Push
{ {
vec4 SourceSize; vec4 SourceSize;
vec4 OutputSize; vec4 OutputSize;
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;
} params; } params;
#pragma parameter BloomBlendMode "Bloom Blend Mode" 0.0 0.0 1.0 1.0 #include "mame_parameters.inc"
#pragma parameter VectorScreen "Vector Screen Mode" 0.0 0.0 1.0 1.0
#pragma parameter BloomScale "Bloom Scale" 1.0 0.0 4.0 0.1
#pragma parameter BloomOverdrive_r "Bloom Overdrive R" 1.0 0.0 1.0 0.01
#pragma parameter BloomOverdrive_g "Bloom Overdrive G" 1.0 0.0 1.0 0.01
#pragma parameter BloomOverdrive_b "Bloom Overdrive B" 1.0 0.0 1.0 0.01
#pragma parameter Level0Weight "Bloom Level 0 Weight" 1.0 0.0 1.0 0.01 float Level0Weight = global.level0weight;
#pragma parameter Level1Weight "Bloom Level 1 Weight" 0.64 0.0 1.0 0.01 float Level1Weight = global.level1weight;
#pragma parameter Level2Weight "Bloom Level 2 Weight" 0.32 0.0 1.0 0.01 float Level2Weight = global.level2weight;
#pragma parameter Level3Weight "Bloom Level 3 Weight" 0.16 0.0 1.0 0.01 float Level3Weight = global.level3weight;
#pragma parameter Level4Weight "Bloom Level 4 Weight" 0.08 0.0 1.0 0.01 float Level4Weight = global.level4weight;
#pragma parameter Level5Weight "Bloom Level 5 Weight" 0.06 0.0 1.0 0.01 float Level5Weight = global.level5weight;
#pragma parameter Level6Weight "Bloom Level 6 Weight" 0.04 0.0 1.0 0.01 float Level6Weight = global.level6weight;
#pragma parameter Level7Weight "Bloom Level 7 Weight" 0.02 0.0 1.0 0.01 float Level7Weight = global.level7weight;
#pragma parameter Level8Weight "Bloom Level 8 Weight" 0.01 0.0 1.0 0.01 float Level8Weight = global.level8weight;
layout(std140, set = 0, binding = 0) uniform UBO int BloomBlendMode = int(global.bloomblendmode); // 0 brighten, 1 darken
{ float BloomScale = global.bloomscale;
mat4 MVP; vec3 BloomOverdrive = vec3(global.bloomoverdrive_r, global.bloomoverdrive_g, global.bloomoverdrive_b);
} global;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Constants // Constants
@ -58,7 +37,7 @@ const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant) const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Funcions // Functions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/ // www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
@ -82,16 +61,9 @@ layout(location = 1) out vec2 BloomCoord;
void main() void main()
{ {
vec4 bloomPos = vec4(Position.xyz, 1.0); gl_Position = global.MVP * Position;
// bloomPos.xy *= params.OutputSize.zw;
// bloomPos.y = 1.0 - bloomPos.y; // flip y
// bloomPos.xy -= 0.5f; // center
// bloomPos.xy *= 2.0f; // zoom
gl_Position = global.MVP * bloomPos; // using bloomPos just makes a black screen /shrug
vTexCoord = TexCoord; vTexCoord = TexCoord;
// vTexCoord += 0.5f * params.OutputSize.zw; // half texel offset correction (DX9)
BloomCoord = vTexCoord; BloomCoord = vTexCoord;
BloomCoord += 0.5f * params.SourceSize.zw;
} }
#pragma stage fragment #pragma stage fragment
@ -132,16 +104,23 @@ vec3 GetNoiseFactor(vec3 n, float random)
void main() void main()
{ {
vec3 texel = texture(DiffuseSampler, vTexCoord).rgb; if(!BloomToggle)
{
FragColor = texture(Source, vTexCoord);
return;
}
else
{
vec3 texel = textureLod(DiffuseSampler, vTexCoord, 0.0).rgb;
vec3 texelA = texture(BloomSamplerA, BloomCoord.xy).rgb; vec3 texelA = textureLod(BloomSamplerA, BloomCoord.xy, 1.0).rgb;
vec3 texelB = texture(BloomSamplerB, BloomCoord.xy).rgb; vec3 texelB = textureLod(BloomSamplerB, BloomCoord.xy, 2.0).rgb;
vec3 texelC = texture(BloomSamplerC, BloomCoord.xy).rgb; vec3 texelC = textureLod(BloomSamplerC, BloomCoord.xy, 3.0).rgb;
vec3 texelD = texture(BloomSamplerD, BloomCoord.xy).rgb; vec3 texelD = textureLod(BloomSamplerD, BloomCoord.xy, 4.0).rgb;
vec3 texelE = texture(BloomSamplerE, BloomCoord.xy).rgb; vec3 texelE = textureLod(BloomSamplerE, BloomCoord.xy, 5.0).rgb;
vec3 texelF = texture(BloomSamplerF, BloomCoord.xy).rgb; vec3 texelF = textureLod(BloomSamplerF, BloomCoord.xy, 6.0).rgb;
vec3 texelG = texture(BloomSamplerG, BloomCoord.xy).rgb; vec3 texelG = textureLod(BloomSamplerG, BloomCoord.xy, 7.0).rgb;
vec3 texelH = texture(BloomSamplerH, BloomCoord.xy).rgb; vec3 texelH = textureLod(BloomSamplerH, BloomCoord.xy, 8.0).rgb;
vec3 texelI = vec3(0.0f, 0.0f, 0.0f); vec3 texelI = vec3(0.0f, 0.0f, 0.0f);
vec3 texelJ = vec3(0.0f, 0.0f, 0.0f); vec3 texelJ = vec3(0.0f, 0.0f, 0.0f);
@ -153,63 +132,63 @@ void main()
// vector screen uses twice -1 as many bloom levels // vector screen uses twice -1 as many bloom levels
if (params.VectorScreen > 0.5) if (VectorScreen)
{ {
texelI = texture(BloomSamplerI, BloomCoord.xy).rgb; texelI = textureLod(BloomSamplerI, BloomCoord.xy, 1.0).rgb;
texelJ = texture(BloomSamplerJ, BloomCoord.xy).rgb; texelJ = textureLod(BloomSamplerJ, BloomCoord.xy, 1.0).rgb;
texelK = texture(BloomSamplerK, BloomCoord.xy).rgb; texelK = textureLod(BloomSamplerK, BloomCoord.xy, 1.0).rgb;
texelL = texture(BloomSamplerL, BloomCoord.xy).rgb; texelL = textureLod(BloomSamplerL, BloomCoord.xy, 1.0).rgb;
texelM = texture(BloomSamplerM, BloomCoord.xy).rgb; texelM = textureLod(BloomSamplerM, BloomCoord.xy, 1.0).rgb;
texelN = texture(BloomSamplerN, BloomCoord.xy).rgb; texelN = textureLod(BloomSamplerN, BloomCoord.xy, 1.0).rgb;
texelO = texture(BloomSamplerO, BloomCoord.xy).rgb; texelO = textureLod(BloomSamplerO, BloomCoord.xy, 1.0).rgb;
} }
vec3 blend; vec3 blend;
// brighten // brighten
if (params.BloomBlendMode < 0.5) if (BloomBlendMode < 0.5)
{ {
vec3 bloom = vec3(0.0f, 0.0f, 0.0f); vec3 bloom = vec3(0.0f, 0.0f, 0.0f);
texel *= params.Level0Weight; texel *= Level0Weight;
if (params.VectorScreen < 0.5) if (VectorScreen)
{ {
bloom += texelA * params.Level1Weight; bloom += texelA * Level1Weight;
bloom += texelB * params.Level2Weight; bloom += texelB * Level2Weight;
bloom += texelC * params.Level3Weight; bloom += texelC * Level3Weight;
bloom += texelD * params.Level4Weight; bloom += texelD * Level4Weight;
bloom += texelE * params.Level5Weight; bloom += texelE * Level5Weight;
bloom += texelF * params.Level6Weight; bloom += texelF * Level6Weight;
bloom += texelG * params.Level7Weight; bloom += texelG * Level7Weight;
bloom += texelH * params.Level8Weight; bloom += texelH * Level8Weight;
} }
// vector screen uses twice -1 as many bloom levels // vector screen uses twice -1 as many bloom levels
else else
{ {
bloom += texelA * (params.Level1Weight); bloom += texelA * (Level1Weight);
bloom += texelB * (params.Level1Weight + params.Level2Weight) * 0.5f; bloom += texelB * (Level1Weight + Level2Weight) * 0.5f;
bloom += texelC * (params.Level2Weight); bloom += texelC * (Level2Weight);
bloom += texelD * (params.Level2Weight + params.Level3Weight) * 0.5f; bloom += texelD * (Level2Weight + Level3Weight) * 0.5f;
bloom += texelE * (params.Level3Weight); bloom += texelE * (Level3Weight);
bloom += texelF * (params.Level3Weight + params.Level4Weight) * 0.5f; bloom += texelF * (Level3Weight + Level4Weight) * 0.5f;
bloom += texelG * (params.Level4Weight); bloom += texelG * (Level4Weight);
bloom += texelH * (params.Level4Weight + params.Level5Weight) * 0.5f; bloom += texelH * (Level4Weight + Level5Weight) * 0.5f;
bloom += texelI * (params.Level5Weight); bloom += texelI * (Level5Weight);
bloom += texelJ * (params.Level5Weight + params.Level6Weight) * 0.5f; bloom += texelJ * (Level5Weight + Level6Weight) * 0.5f;
bloom += texelK * (params.Level6Weight); bloom += texelK * (Level6Weight);
bloom += texelL * (params.Level6Weight + params.Level7Weight) * 0.5f; bloom += texelL * (Level6Weight + Level7Weight) * 0.5f;
bloom += texelM * (params.Level7Weight); bloom += texelM * (Level7Weight);
bloom += texelN * (params.Level7Weight + params.Level8Weight) * 0.5f; bloom += texelN * (Level7Weight + Level8Weight) * 0.5f;
bloom += texelO * (params.Level8Weight); bloom += texelO * (Level8Weight);
} }
bloom *= params.BloomScale; bloom *= BloomScale;
vec3 bloomOverdrive; vec3 bloomOverdrive;
bloomOverdrive.r = max(0.0f, texel.r + bloom.r - 1.0f) * params.BloomOverdrive_r; bloomOverdrive.r = max(0.0f, texel.r + bloom.r - 1.0f) * BloomOverdrive.r;
bloomOverdrive.g = max(0.0f, texel.g + bloom.g - 1.0f) * params.BloomOverdrive_g; bloomOverdrive.g = max(0.0f, texel.g + bloom.g - 1.0f) * BloomOverdrive.g;
bloomOverdrive.b = max(0.0f, texel.b + bloom.b - 1.0f) * params.BloomOverdrive_b; bloomOverdrive.b = max(0.0f, texel.b + bloom.b - 1.0f) * BloomOverdrive.b;
bloom.r += bloomOverdrive.g * 0.5f; bloom.r += bloomOverdrive.g * 0.5f;
bloom.r += bloomOverdrive.b * 0.5f; bloom.r += bloomOverdrive.b * 0.5f;
@ -236,16 +215,17 @@ void main()
texelG = min(texel, texelG); texelG = min(texel, texelG);
texelH = min(texel, texelH); texelH = min(texel, texelH);
blend = texel * params.Level0Weight; blend = texel * Level0Weight;
blend = mix(blend, texelA, params.Level1Weight * params.BloomScale); blend = mix(blend, texelA, Level1Weight * BloomScale);
blend = mix(blend, texelB, params.Level2Weight * params.BloomScale); blend = mix(blend, texelB, Level2Weight * BloomScale);
blend = mix(blend, texelC, params.Level3Weight * params.BloomScale); blend = mix(blend, texelC, Level3Weight * BloomScale);
blend = mix(blend, texelD, params.Level4Weight * params.BloomScale); blend = mix(blend, texelD, Level4Weight * BloomScale);
blend = mix(blend, texelE, params.Level5Weight * params.BloomScale); blend = mix(blend, texelE, Level5Weight * BloomScale);
blend = mix(blend, texelF, params.Level6Weight * params.BloomScale); blend = mix(blend, texelF, Level6Weight * BloomScale);
blend = mix(blend, texelG, params.Level7Weight * params.BloomScale); blend = mix(blend, texelG, Level7Weight * BloomScale);
blend = mix(blend, texelH, params.Level8Weight * params.BloomScale); blend = mix(blend, texelH, Level8Weight * BloomScale);
} }
FragColor = vec4(blend, 1.0); FragColor = vec4(blend, 1.0);
}
} }

View file

@ -14,10 +14,7 @@ layout(push_constant) uniform Push
uint FrameCount; uint FrameCount;
} params; } params;
layout(std140, set = 0, binding = 0) uniform UBO #include "mame_parameters.inc"
{
mat4 MVP;
} global;
#pragma stage vertex #pragma stage vertex
layout(location = 0) in vec4 Position; layout(location = 0) in vec4 Position;
@ -38,10 +35,10 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
#define DiffuseSampler Source #define DiffuseSampler Source
#define mul(a,b) (b*a) #define mul(a,b) (b*a)
const vec3 YGain = vec3(0.2126, 0.7152, 0.0722); vec3 YGain = vec3(global.ygain_r, global.ygain_g, global.ygain_b);
const vec2 ChromaA = vec2(0.630, 0.340); vec2 ChromaA = vec2(global.chromaa_x, global.chromaa_y);
const vec2 ChromaB = vec2(0.310, 0.595); vec2 ChromaB = vec2(global.chromab_x, global.chromab_y);
const vec2 ChromaC = vec2(0.155, 0.070); vec2 ChromaC = vec2(global.chromac_x, global.chromac_y);
const mat3 XYZ_TO_sRGB = mat3( const mat3 XYZ_TO_sRGB = mat3(
3.2406, -1.5372, -0.4986, 3.2406, -1.5372, -0.4986,
@ -50,6 +47,13 @@ const mat3 XYZ_TO_sRGB = mat3(
void main() void main()
{ {
if(!Chromaticity)
{
FragColor = texture(Source, vTexCoord);
return;
}
else
{
vec4 cin = texture(DiffuseSampler, vTexCoord); vec4 cin = texture(DiffuseSampler, vTexCoord);
vec4 cout = vec4(0.0, 0.0, 0.0, cin.a); vec4 cout = vec4(0.0, 0.0, 0.0, cin.a);
mat3x2 xy = { ChromaA, ChromaB, ChromaC }; mat3x2 xy = { ChromaA, ChromaB, ChromaC };
@ -61,4 +65,5 @@ void main()
cout.rgb += mul(XYZ_TO_sRGB, vec3(X, Y, Z)); cout.rgb += mul(XYZ_TO_sRGB, vec3(X, Y, Z));
} }
FragColor = cout; FragColor = cout;
}
} }

View file

@ -12,33 +12,9 @@ layout(push_constant) uniform Push
vec4 OriginalSize; vec4 OriginalSize;
vec4 OutputSize; vec4 OutputSize;
uint FrameCount; uint FrameCount;
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;
} params; } params;
#pragma parameter col_red "Red Shift" 1.0 0.0 1.0 0.01 #include "mame_parameters.inc"
#pragma parameter col_grn "Green Shift" 1.0 0.0 1.0 0.01
#pragma parameter col_blu "Blue Shift" 1.0 0.0 1.0 0.01
#pragma parameter col_offset_x "Offset X" 0.0 0.0 1.0 0.01
#pragma parameter col_offset_y "Offset Y" 0.0 0.0 1.0 0.01
#pragma parameter col_offset_z "Offset Z" 0.0 0.0 1.0 0.01
#pragma parameter col_scale_x "Scale X" 1.0 0.0 1.0 0.01
#pragma parameter col_scale_y "Scale Y" 1.0 0.0 1.0 0.01
#pragma parameter col_scale_z "Scale Z" 1.0 0.0 1.0 0.01
#pragma parameter col_saturation "Saturation" 1.0 0.0 0.01
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex #pragma stage vertex
layout(location = 0) in vec4 Position; layout(location = 0) in vec4 Position;
@ -58,12 +34,12 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
#define DiffuseSampler Source #define DiffuseSampler Source
vec3 RedRatios = vec3(params.col_red, 0.0f, 0.0f); vec3 RedRatios = vec3(global.col_red, 0.0f, 0.0f);
vec3 GrnRatios = vec3(0.0f, params.col_grn, 0.0f); vec3 GrnRatios = vec3(0.0f, global.col_grn, 0.0f);
vec3 BluRatios = vec3(0.0f, 0.0f, params.col_blu); vec3 BluRatios = vec3(0.0f, 0.0f, global.col_blu);
vec3 Offset = vec3(params.col_offset_x, params.col_offset_y, params.col_offset_z); vec3 Offset = vec3(global.col_offset_x, global.col_offset_y, global.col_offset_z);
vec3 Scale = vec3(params.col_scale_x, params.col_scale_y, params.col_scale_z); vec3 Scale = vec3(global.col_scale_x, global.col_scale_y, global.col_scale_z);
float Saturation = params.col_saturation; float Saturation = global.col_saturation;
void main() void main()
{ {

View file

@ -12,42 +12,15 @@ layout(push_constant) uniform Push
vec4 OriginalSize; vec4 OriginalSize;
vec4 OutputSize; vec4 OutputSize;
uint FrameCount; uint FrameCount;
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;
} params; } params;
#pragma parameter converge_x_r "Convergence X Red" 0.0 -100.0 100.0 0.5 #include "mame_parameters.inc"
#pragma parameter converge_x_g "Convergence X Green" 0.0 -100.0 100.0 0.5
#pragma parameter converge_x_b "Convergence X Blue" 0.0 -100.0 100.0 0.5
#pragma parameter converge_y_r "Convergence Y Red" 0.0 -100.0 100.0 0.5
#pragma parameter converge_y_g "Convergence Y Green" 0.0 -100.0 100.0 0.5
#pragma parameter converge_y_b "Convergence Y Blue" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_x_r "Radial Conv X Red" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_x_g "Radial Conv X Green" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_x_b "Radial Conv X Blue" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_y_r "Radial Conv Y Red" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_y_g "Radial Conv Y Green" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_y_b "Radial Conv Y Blue" 0.0 -100.0 100.0 0.5
layout(std140, set = 0, binding = 0) uniform UBO 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);
mat4 MVP; vec3 RadialConvergeX = vec3(global.radial_conv_x_r, global.radial_conv_x_g, global.radial_conv_x_b);
} global; vec3 RadialConvergeY = vec3(global.radial_conv_y_r, global.radial_conv_y_g, global.radial_conv_y_b);
vec3 ConvergeX = vec3(params.converge_x_r, params.converge_x_g, params.converge_x_b);
vec3 ConvergeY = vec3(params.converge_y_r, params.converge_y_g, params.converge_y_b);
vec3 RadialConvergeX = vec3(params.radial_conv_x_r, params.radial_conv_x_g, params.radial_conv_x_b);
vec3 RadialConvergeY = vec3(params.radial_conv_y_r, params.radial_conv_y_g, params.radial_conv_y_b);
#pragma stage vertex #pragma stage vertex
layout(location = 0) in vec4 Position; layout(location = 0) in vec4 Position;

View file

@ -12,43 +12,14 @@ layout(push_constant) uniform Push
vec4 OriginalSize; vec4 OriginalSize;
vec4 OutputSize; vec4 OutputSize;
uint FrameCount; uint FrameCount;
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;
float swapxy;
float target_scale;
} params; } params;
#pragma parameter distortion_amount "Distortion Amount" 0.0 0.0 1.0 0.01 #include "mame_parameters.inc"
#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 swapxy "Swap X and Y" 0.0 0.0 1.0 1.0
#pragma parameter target_scale "Target Scale" 1.0 1.0 10.0 1.0
#define saturate(c) clamp(c, 0.0, 1.0) #define saturate(c) clamp(c, 0.0, 1.0)
#define mul(a,b) (b*a) #define mul(a,b) (b*a)
const int ScreenCount = 1; const int ScreenCount = 1;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Constants // Constants
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -103,19 +74,18 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
#define DiffuseSampler Source #define DiffuseSampler Source
float DistortionAmount = params.distortion_amount; // k - quartic distortion coefficient float DistortionAmount = global.distortion_amount; // k - quartic distortion coefficient
float CubicDistortionAmount = params.cubic_distortion_amount; // kcube - cubic distortion modifier float CubicDistortionAmount = global.cubic_distortion_amount; // kcube - cubic distortion modifier
float DistortCornerAmount = params.distort_corner_amount; float DistortCornerAmount = global.distort_corner_amount;
float RoundCornerAmount = params.round_corner_amount; float RoundCornerAmount = global.round_corner_amount;
float SmoothBorderAmount = params.smooth_border_amount; float SmoothBorderAmount = global.smooth_border_amount;
float VignettingAmount = params.vignette_amount; float VignettingAmount = global.vignette_amount;
float ReflectionAmount = params.reflection_amount; float ReflectionAmount = global.reflection_amount;
vec3 LightReflectionColor = vec3(params.reflection_col_r, params.reflection_col_g, params.reflection_col_b); // color temperature 5.000 Kelvin vec3 LightReflectionColor = vec3(global.reflection_col_r, global.reflection_col_g, global.reflection_col_b); // color temperature 5.000 Kelvin
bool SwapXY = bool(params.swapxy);
vec2 QuadDims = params.SourceSize.xy; vec2 QuadDims = params.SourceSize.xy;
vec2 TargetDims = params.SourceSize.xy; vec2 TargetDims = params.OutputSize.xy;
float TargetScale = params.target_scale; float TargetScale = 1.0;
float GetNoiseFactor(vec3 n, float random) float GetNoiseFactor(vec3 n, float random)
{ {
@ -242,6 +212,13 @@ vec2 GetQuadCoords(vec2 coord, vec2 scale, float distortionAmount, float cubicDi
void main() void main()
{ {
if(!Distortion)
{
FragColor = texture(Source, vTexCoord);
return;
}
else
{
// image distortion // image distortion
float distortionAmount = DistortionAmount; float distortionAmount = DistortionAmount;
float cubicDistortionAmount = CubicDistortionAmount > 0.0f float cubicDistortionAmount = CubicDistortionAmount > 0.0f
@ -272,7 +249,7 @@ void main()
// Screen Quad Curvature // Screen Quad Curvature
vec2 QuadCoord = GetQuadCoords(vTexCoord, BaseTargetQuadScale, distortCornerAmount, 0.0f); vec2 QuadCoord = GetQuadCoords(vTexCoord, BaseTargetQuadScale, distortCornerAmount, 0.0f);
/* /*
// clip border // clip border
if (BaseCoord.x < 0.0f - TexelDims.x || BaseCoord.y < 0.0f - TexelDims.y || 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) BaseCoord.x > 1.0f + TexelDims.x || BaseCoord.y > 1.0f + TexelDims.y)
@ -280,7 +257,7 @@ void main()
// we don't use the clip function, because we don't clear the render target before // 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); return vec4(0.0f, 0.0f, 0.0f, 1.0f);
} }
*/ */
// Color // Color
vec4 BaseColor = texture(DiffuseSampler, BaseCoord); vec4 BaseColor = texture(DiffuseSampler, BaseCoord);
@ -311,4 +288,5 @@ void main()
BaseColor.rgb *= roundCornerFactor; BaseColor.rgb *= roundCornerFactor;
FragColor = BaseColor; FragColor = BaseColor;
}
} }

View file

@ -12,17 +12,9 @@ layout(push_constant) uniform Push
vec4 OriginalSize; vec4 OriginalSize;
vec4 OutputSize; vec4 OutputSize;
uint FrameCount; uint FrameCount;
float defocus_x;
float defocus_y;
} params; } params;
#pragma parameter defocus_x "Defocus X Axis" 0.0 0.0 10.0 0.1 #include "mame_parameters.inc"
#pragma parameter defocus_y "Defocus Y Axis" 0.0 0.0 10.0 0.1
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex #pragma stage vertex
layout(location = 0) in vec4 Position; layout(location = 0) in vec4 Position;
@ -42,7 +34,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
#define DiffuseSampler Source #define DiffuseSampler Source
vec2 Defocus = vec2(params.defocus_x, params.defocus_y); vec2 Defocus = vec2(global.defocus_x, global.defocus_y);
// previously this pass was applied two times with offsets of 0.25, 0.5, 0.75, 1.0 // 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 // 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

View file

@ -0,0 +1,66 @@
# info on how the passes come together can be found in mame/src/osd/modules/render/d3d/d3dhlsl.cpp
shaders = 12
shader0 = mame_ntsc.slang
filter_linear0 = true
alias0 = NTSCPass
scale_type0 = source
scale0 = 1.0
shader1 = mame_color.slang
alias1 = ColorPass
scale_type1 = source
scale1 = 1.0
filter_linear1 = true
shader2 = ../../../../retro/shaders/sharp-bilinear.slang
alias2 = PrescalePass
scale_type2 = source
filter_linear2 = true
shader3 = mame_deconverge.slang
alias3 = DeconvergePass
filter_linear3 = true
shader4 = mame_scanline.slang
alias4 = ScanlinePass
filter_linear4 = true
scale_type4 = source
scale4 = 4.0
shader5 = mame_focus.slang
alias5 = FocusPass
filter_linear5 = true
shader6 = mame_phosphor.slang
alias6 = PhosphorPass
filter_linear6 = true
shader7 = mame_post.slang
alias7 = PostPass
filter_linear7 = true
shader8 = mame_chroma.slang
alias8 = ChromaPass
filter_linear8 = true
shader9 = mame_downsample.slang
alias9 = DownsamplePass
filter_linear9 = true
mipmap_input9 = true
shader10 = mame_bloom.slang
alias10 = BloomPass
filter_linear10 = true
shader11 = mame_distortion.slang
alias11 = DistortionPass
filter_linear11 = true
shader12 = 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 = slot-mask.png

View file

@ -0,0 +1,221 @@
#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;
} params;
#include "mame_parameters.inc"
//-----------------------------------------------------------------------------
// 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 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 SourceDims params.SourceSize.xy
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.notchhalfwidth;
float YFreqResponse = global.yfreqresponse;
float IFreqResponse = global.ifreqresponse;
float QFreqResponse = global.qfreqresponse;
float SignalOffset = global.signaloffset;
vec4 GetCompositeYIQ(vec2 coord)
{
vec2 PValueSourceTexel = vec2(PValue / SourceDims.x, 0.0f);
vec2 C0 = coord + PValueSourceTexel * OffsetX.x;
vec2 C1 = coord + PValueSourceTexel * OffsetX.y;
vec2 C2 = coord + PValueSourceTexel * OffsetX.z;
vec2 C3 = coord + PValueSourceTexel * OffsetX.w;
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(DiffuseSampler, C0);
vec4 Texel1 = texture(DiffuseSampler, C1);
vec4 Texel2 = texture(DiffuseSampler, C2);
vec4 Texel3 = texture(DiffuseSampler, C3);
vec4 HPosition = Cx;
vec4 VPosition = Cy;
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));
float W = PI2 * CCValue * ScanTime;
float WoPI = W / PI;
float HOffset = (BValue + SignalOffset) / WoPI;
float VScale = (AValue * SourceDims.y) / WoPI;
vec4 T = HPosition + HOffset + VPosition * VScale;
vec4 TW = T * W;
vec4 CompositeYIQ = Y + I * cos(TW) + Q * sin(TW);
return CompositeYIQ;
}
void main()
{
if(!NTSCSignal)
{
FragColor = texture(DiffuseSampler, vTexCoord);
return;
}
else
{
vec4 BaseTexel = texture(DiffuseSampler, vTexCoord);
float TimePerSample = ScanTime / (SourceDims.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 * SourceDims.y) / WoPI;
vec4 YAccum = vec4(0.0);
vec4 IAccum = vec4(0.0);
vec4 QAccum = vec4(0.0);
vec4 Cy = vTexCoord.yyyy;
vec4 VPosition = Cy;
for (float i = 0; i < SampleCount; i += 4.0f)
{
float n = i - HalfSampleCount;
vec4 n4 = n + NotchOffset;
vec4 Cx = vTexCoord.x + (n4 * 0.25f) / SourceDims.x;
vec4 HPosition = Cx;
vec4 C = GetCompositeYIQ(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);
}
}

View file

@ -0,0 +1,379 @@
cbuffer global : register(b0)
{
row_major float4x4 global_MVP : packoffset(c0);
};
cbuffer params : register(b1)
{
float4 params_SourceSize : packoffset(c0);
float4 params_OriginalSize : packoffset(c1);
float4 params_OutputSize : packoffset(c2);
uint params_FrameCount : packoffset(c3);
float params_avalue : packoffset(c3.y);
float params_bvalue : packoffset(c3.z);
float params_ccvalue : packoffset(c3.w);
float params_ovalue : packoffset(c4);
float params_pvalue : packoffset(c4.y);
float params_scantime : packoffset(c4.z);
float params_notchhalfwidth : packoffset(c4.w);
float params_yfreqresponse : packoffset(c5);
float params_ifreqresponse : packoffset(c5.y);
float params_qfreqresponse : packoffset(c5.z);
float params_signaloffset : packoffset(c5.w);
float params_ntscsignal : packoffset(c6);
};
Texture2D<float4> Source : register(t2);
SamplerState _Source_sampler : register(s2);
static float4 FragColor;
static float2 vTexCoord;
struct SPIRV_Cross_Input
{
float2 vTexCoord : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
static bool NTSCSignal;
static float AValue;
static float BValue;
static float CCValue;
static float OValue;
static float PValue;
static float ScanTime;
static float NotchHalfWidth;
static float YFreqResponse;
static float IFreqResponse;
static float QFreqResponse;
static float SignalOffset;
float4 GetCompositeYIQ(float2 coord)
{
float2 PValueSourceTexel = float2(PValue / params_SourceSize.x, 0.0f);
float2 C0 = coord + (PValueSourceTexel * 0.0f);
float2 C1 = coord + (PValueSourceTexel * 0.25f);
float2 C2 = coord + (PValueSourceTexel * 0.5f);
float2 C3 = coord + (PValueSourceTexel * 0.75f);
float4 Cx = float4(C0.x, C1.x, C2.x, C3.x);
float4 Cy = float4(C0.y, C1.y, C2.y, C3.y);
float4 Texel0 = Source.Sample(_Source_sampler, C0);
float4 Texel1 = Source.Sample(_Source_sampler, C1);
float4 Texel2 = Source.Sample(_Source_sampler, C2);
float4 Texel3 = Source.Sample(_Source_sampler, C3);
float4 HPosition = Cx;
float4 VPosition = Cy;
float4 Y = float4(dot(Texel0, float4(0.2989999949932098388671875f, 0.58700001239776611328125f, 0.114000000059604644775390625f, 0.0f)), dot(Texel1, float4(0.2989999949932098388671875f, 0.58700001239776611328125f, 0.114000000059604644775390625f, 0.0f)), dot(Texel2, float4(0.2989999949932098388671875f, 0.58700001239776611328125f, 0.114000000059604644775390625f, 0.0f)), dot(Texel3, float4(0.2989999949932098388671875f, 0.58700001239776611328125f, 0.114000000059604644775390625f, 0.0f)));
float4 I = float4(dot(Texel0, float4(0.595715999603271484375f, -0.2744530141353607177734375f, -0.3212629854679107666015625f, 0.0f)), dot(Texel1, float4(0.595715999603271484375f, -0.2744530141353607177734375f, -0.3212629854679107666015625f, 0.0f)), dot(Texel2, float4(0.595715999603271484375f, -0.2744530141353607177734375f, -0.3212629854679107666015625f, 0.0f)), dot(Texel3, float4(0.595715999603271484375f, -0.2744530141353607177734375f, -0.3212629854679107666015625f, 0.0f)));
float4 Q = float4(dot(Texel0, float4(0.211456000804901123046875f, -0.52259099483489990234375f, 0.311134994029998779296875f, 0.0f)), dot(Texel1, float4(0.211456000804901123046875f, -0.52259099483489990234375f, 0.311134994029998779296875f, 0.0f)), dot(Texel2, float4(0.211456000804901123046875f, -0.52259099483489990234375f, 0.311134994029998779296875f, 0.0f)), dot(Texel3, float4(0.211456000804901123046875f, -0.52259099483489990234375f, 0.311134994029998779296875f, 0.0f)));
float W = (6.283185482025146484375f * CCValue) * ScanTime;
float WoPI = W / 3.1415927410125732421875f;
float HOffset = (BValue + SignalOffset) / WoPI;
float VScale = (AValue * params_SourceSize.y) / WoPI;
float4 T = (HPosition + HOffset.xxxx) + (VPosition * VScale);
float4 TW = T * W;
float4 CompositeYIQ = (Y + (I * cos(TW))) + (Q * sin(TW));
return CompositeYIQ;
}
void frag_main()
{
NTSCSignal = params_ntscsignal != 0.0f;
AValue = params_avalue;
BValue = params_bvalue;
CCValue = params_ccvalue;
OValue = params_ovalue;
PValue = params_pvalue;
ScanTime = params_scantime;
NotchHalfWidth = params_notchhalfwidth;
YFreqResponse = params_yfreqresponse;
IFreqResponse = params_ifreqresponse;
QFreqResponse = params_qfreqresponse;
SignalOffset = params_signaloffset;
if (!NTSCSignal)
{
FragColor = Source.Sample(_Source_sampler, vTexCoord);
return;
}
else
{
float4 BaseTexel = Source.Sample(_Source_sampler, vTexCoord);
float TimePerSample = ScanTime / (params_SourceSize.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 * 6.283185482025146484375f;
float Fc_q_pi2 = Fc_q * 6.283185482025146484375f;
float Fc_y1_pi2 = Fc_y1 * 6.283185482025146484375f;
float Fc_y2_pi2 = Fc_y2 * 6.283185482025146484375f;
float Fc_y3_pi2 = Fc_y3 * 6.283185482025146484375f;
float PI2Length = 0.098174773156642913818359375f;
float W = (6.283185482025146484375f * CCValue) * ScanTime;
float WoPI = W / 3.1415927410125732421875f;
float HOffset = (BValue + SignalOffset) / WoPI;
float VScale = (AValue * params_SourceSize.y) / WoPI;
float4 YAccum = 0.0f.xxxx;
float4 IAccum = 0.0f.xxxx;
float4 QAccum = 0.0f.xxxx;
float4 Cy = vTexCoord.yyyy;
float4 VPosition = Cy;
for (float i = 0.0f; i < 64.0f; i += 4.0f)
{
float n = i - 32.0f;
float4 n4 = n.xxxx + float4(0.0f, 1.0f, 2.0f, 3.0f);
float4 Cx = vTexCoord.x.xxxx + ((n4 * 0.25f) / params_SourceSize.x.xxxx);
float4 HPosition = Cx;
float2 param = float2(Cx.x, Cy.x);
float4 C = GetCompositeYIQ(param);
float4 T = (HPosition + HOffset.xxxx) + (VPosition * VScale);
float4 WT = (T * W) + OValue.xxxx;
float4 SincKernel = 0.540000021457672119140625f.xxxx + (cos(n4 * PI2Length) * 0.4600000083446502685546875f);
float4 SincYIn1 = n4 * Fc_y1_pi2;
float4 SincYIn2 = n4 * Fc_y2_pi2;
float4 SincYIn3 = n4 * Fc_y3_pi2;
float4 SincIIn = n4 * Fc_i_pi2;
float4 SincQIn = n4 * Fc_q_pi2;
float _447;
if (SincYIn1.x != 0.0f)
{
_447 = sin(SincYIn1.x) / SincYIn1.x;
}
else
{
_447 = 1.0f;
}
float4 SincY1;
SincY1.x = _447;
float _462;
if (SincYIn1.y != 0.0f)
{
_462 = sin(SincYIn1.y) / SincYIn1.y;
}
else
{
_462 = 1.0f;
}
SincY1.y = _462;
float _478;
if (SincYIn1.z != 0.0f)
{
_478 = sin(SincYIn1.z) / SincYIn1.z;
}
else
{
_478 = 1.0f;
}
SincY1.z = _478;
float _494;
if (SincYIn1.w != 0.0f)
{
_494 = sin(SincYIn1.w) / SincYIn1.w;
}
else
{
_494 = 1.0f;
}
SincY1.w = _494;
float _510;
if (SincYIn2.x != 0.0f)
{
_510 = sin(SincYIn2.x) / SincYIn2.x;
}
else
{
_510 = 1.0f;
}
float4 SincY2;
SincY2.x = _510;
float _525;
if (SincYIn2.y != 0.0f)
{
_525 = sin(SincYIn2.y) / SincYIn2.y;
}
else
{
_525 = 1.0f;
}
SincY2.y = _525;
float _540;
if (SincYIn2.z != 0.0f)
{
_540 = sin(SincYIn2.z) / SincYIn2.z;
}
else
{
_540 = 1.0f;
}
SincY2.z = _540;
float _555;
if (SincYIn2.w != 0.0f)
{
_555 = sin(SincYIn2.w) / SincYIn2.w;
}
else
{
_555 = 1.0f;
}
SincY2.w = _555;
float _571;
if (SincYIn3.x != 0.0f)
{
_571 = sin(SincYIn3.x) / SincYIn3.x;
}
else
{
_571 = 1.0f;
}
float4 SincY3;
SincY3.x = _571;
float _586;
if (SincYIn3.y != 0.0f)
{
_586 = sin(SincYIn3.y) / SincYIn3.y;
}
else
{
_586 = 1.0f;
}
SincY3.y = _586;
float _601;
if (SincYIn3.z != 0.0f)
{
_601 = sin(SincYIn3.z) / SincYIn3.z;
}
else
{
_601 = 1.0f;
}
SincY3.z = _601;
float _616;
if (SincYIn3.w != 0.0f)
{
_616 = sin(SincYIn3.w) / SincYIn3.w;
}
else
{
_616 = 1.0f;
}
SincY3.w = _616;
float4 IdealY = ((SincY1 * Fc_y1_2) - (SincY2 * Fc_y2_2)) + (SincY3 * Fc_y3_2);
float _641 = Fc_i_2;
float _645;
if (SincIIn.x != 0.0f)
{
_645 = sin(SincIIn.x) / SincIIn.x;
}
else
{
_645 = 1.0f;
}
float4 IdealI;
IdealI.x = _641 * _645;
float _658 = Fc_i_2;
float _662;
if (SincIIn.y != 0.0f)
{
_662 = sin(SincIIn.y) / SincIIn.y;
}
else
{
_662 = 1.0f;
}
IdealI.y = _658 * _662;
float _675 = Fc_i_2;
float _679;
if (SincIIn.z != 0.0f)
{
_679 = sin(SincIIn.z) / SincIIn.z;
}
else
{
_679 = 1.0f;
}
IdealI.z = _675 * _679;
float _692 = Fc_i_2;
float _696;
if (SincIIn.w != 0.0f)
{
_696 = sin(SincIIn.w) / SincIIn.w;
}
else
{
_696 = 1.0f;
}
IdealI.w = _692 * _696;
float _710 = Fc_q_2;
float _714;
if (SincQIn.x != 0.0f)
{
_714 = sin(SincQIn.x) / SincQIn.x;
}
else
{
_714 = 1.0f;
}
float4 IdealQ;
IdealQ.x = _710 * _714;
float _727 = Fc_q_2;
float _731;
if (SincQIn.y != 0.0f)
{
_731 = sin(SincQIn.y) / SincQIn.y;
}
else
{
_731 = 1.0f;
}
IdealQ.y = _727 * _731;
float _744 = Fc_q_2;
float _748;
if (SincQIn.z != 0.0f)
{
_748 = sin(SincQIn.z) / SincQIn.z;
}
else
{
_748 = 1.0f;
}
IdealQ.z = _744 * _748;
float _761 = Fc_q_2;
float _765;
if (SincQIn.w != 0.0f)
{
_765 = sin(SincQIn.w) / SincQIn.w;
}
else
{
_765 = 1.0f;
}
IdealQ.w = _761 * _765;
float4 FilterY = SincKernel * IdealY;
float4 FilterI = SincKernel * IdealI;
float4 FilterQ = SincKernel * IdealQ;
YAccum += (C * FilterY);
IAccum += ((C * cos(WT)) * FilterI);
QAccum += ((C * sin(WT)) * FilterQ);
}
float3 YIQ = float3(((YAccum.x + YAccum.y) + YAccum.z) + YAccum.w, (((IAccum.x + IAccum.y) + IAccum.z) + IAccum.w) * 2.0f, (((QAccum.x + QAccum.y) + QAccum.z) + QAccum.w) * 2.0f);
float3 RGB = float3(dot(YIQ, float3(1.0f, 0.95599997043609619140625f, 0.620999991893768310546875f)), dot(YIQ, float3(1.0f, -0.272000014781951904296875f, -0.647000014781951904296875f)), dot(YIQ, float3(1.0f, -1.10599994659423828125f, 1.70299994945526123046875f)));
FragColor = float4(RGB, BaseTexel.w);
}
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vTexCoord = stage_input.vTexCoord;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View file

@ -0,0 +1,60 @@
cbuffer global : register(b0)
{
row_major float4x4 global_MVP : packoffset(c0);
};
cbuffer params : register(b1)
{
float4 params_SourceSize : packoffset(c0);
float4 params_OriginalSize : packoffset(c1);
float4 params_OutputSize : packoffset(c2);
uint params_FrameCount : packoffset(c3);
float params_avalue : packoffset(c3.y);
float params_bvalue : packoffset(c3.z);
float params_ccvalue : packoffset(c3.w);
float params_ovalue : packoffset(c4);
float params_pvalue : packoffset(c4.y);
float params_scantime : packoffset(c4.z);
float params_notchhalfwidth : packoffset(c4.w);
float params_yfreqresponse : packoffset(c5);
float params_ifreqresponse : packoffset(c5.y);
float params_qfreqresponse : packoffset(c5.z);
float params_signaloffset : packoffset(c5.w);
float params_ntscsignal : packoffset(c6);
};
static float4 gl_Position;
static float4 Position;
static float2 vTexCoord;
static float2 TexCoord;
struct SPIRV_Cross_Input
{
float4 Position : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
};
struct SPIRV_Cross_Output
{
float2 vTexCoord : TEXCOORD0;
float4 gl_Position : SV_Position;
};
static bool NTSCSignal;
void vert_main()
{
NTSCSignal = params_ntscsignal != 0.0f;
gl_Position = mul(Position, global_MVP);
vTexCoord = TexCoord;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
Position = stage_input.Position;
TexCoord = stage_input.TexCoord;
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.vTexCoord = vTexCoord;
return stage_output;
}

View file

@ -0,0 +1,295 @@
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 bloomtoggle "Bloom Enable" 0.0 0.0 1.0 1.0
#pragma parameter bloomblendmode "Bloom Blend Mode" 0.0 0.0 1.0 1.0
#pragma parameter bloomscale "Bloom Scale" 0.06 0.0 1.0 0.01
#pragma parameter bloomoverdrive_r "Bloom Overdrive R" 1.0 0.0 1.0 0.01
#pragma parameter bloomoverdrive_g "Bloom Overdrive G" 1.0 0.0 1.0 0.01
#pragma parameter bloomoverdrive_b "Bloom Overdrive B" 1.0 0.0 1.0 0.01
#pragma parameter level0weight "Bloom Level 0 Weight" 1.0 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 0.0 1.0 0.01
#pragma parameter bvalue "B Value" 0.5 0.0 1.0 0.01
#pragma parameter ccvalue "CC Value" 3.5795454 0.0 5.0 0.1
#pragma parameter ovalue "O Value" 0.0 -2.0 2.0 0.1
#pragma parameter pvalue "P Value" 1.0 -2.0 3.0 0.1
#pragma parameter scantime "Scan Time" 52.6 0.0 100.0 1.0
#pragma parameter notchhalfwidth "Notch Half Width" 1.0 0.0 5.0 0.5
#pragma parameter yfreqresponse "Y Freq Response" 6.0 0.0 10.0 0.1
#pragma parameter ifreqresponse "I Freq Response" 1.2 0.0 10.0 0.1
#pragma parameter qfreqresponse "Q Freq Response" 0.6 0.0 10.0 0.1
#pragma parameter signaloffset "Signal Offset" 0.0 -5.0 5.0 0.01
// Color Pass
#pragma parameter col_red "Red Shift" 1.0 0.0 1.0 0.01
#pragma parameter col_grn "Green Shift" 1.0 0.0 1.0 0.01
#pragma parameter col_blu "Blue Shift" 1.0 0.0 1.0 0.01
#pragma parameter col_offset_x "Offset X" 0.0 0.0 1.0 0.01
#pragma parameter col_offset_y "Offset Y" 0.0 0.0 1.0 0.01
#pragma parameter col_offset_z "Offset Z" 0.0 0.0 1.0 0.01
#pragma parameter col_scale_x "Scale X" 1.0 0.0 1.0 0.01
#pragma parameter col_scale_y "Scale Y" 1.0 0.0 1.0 0.01
#pragma parameter col_scale_z "Scale Z" 1.0 0.0 1.0 0.01
#pragma parameter col_saturation "Saturation" 1.0 0.0 0.01
// Deconverge Pass
#pragma parameter converge_x_r "Convergence X Red" 0.0 -100.0 100.0 0.5
#pragma parameter converge_x_g "Convergence X Green" 0.0 -100.0 100.0 0.5
#pragma parameter converge_x_b "Convergence X Blue" 0.0 -100.0 100.0 0.5
#pragma parameter converge_y_r "Convergence Y Red" 0.0 -100.0 100.0 0.5
#pragma parameter converge_y_g "Convergence Y Green" 0.0 -100.0 100.0 0.5
#pragma parameter converge_y_b "Convergence Y Blue" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_x_r "Radial Conv X Red" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_x_g "Radial Conv X Green" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_x_b "Radial Conv X Blue" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_y_r "Radial Conv Y Red" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_y_g "Radial Conv Y Green" 0.0 -100.0 100.0 0.5
#pragma parameter radial_conv_y_b "Radial Conv Y Blue" 0.0 -100.0 100.0 0.5
// Scanline Pass
#pragma parameter scanlinealpha "Scanline Alpha" 0.5 0.0 1.0 0.01
#pragma parameter scanlinescale "Scanline Scale" 1.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

View file

@ -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);
}

View file

@ -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;
}

View file

@ -0,0 +1,124 @@
#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;
} params;
#include "mame_parameters.inc"
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
const float PI = 3.1415927f;
const float HalfPI = PI * 0.5f;
//-----------------------------------------------------------------------------
// 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.SourceSize.xy;
vec2 SourceDims = params.SourceSize.xy;
vec2 GetAdjustedCoords(vec2 coord)
{
// center coordinates
coord -= 0.5f;
// apply screen scale
coord *= ScreenScale;
// un-center coordinates
coord += 0.5f;
// 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.0f;
/*
// clip border
if (BaseCoord.x < 0.0f || BaseCoord.y < 0.0f ||
BaseCoord.x > 1.0f || BaseCoord.y > 1.0f)
{
// 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);
}
*/
float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha);
float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0f - ScanlineAlpha);
float ColorBrightness = 0.299f * BaseColor.r + 0.587f * BaseColor.g + 0.114 * BaseColor.b;
float ScanlineCoord = BaseCoord.y;
ScanlineCoord += SwapXY
? QuadDims.x <= SourceDims.x * 2.0f
? 0.5f / QuadDims.x // uncenter scanlines if the quad is less than twice the size of the source
: 0.0f
: QuadDims.y <= SourceDims.y * 2.0f
? 0.5f / QuadDims.y // uncenter scanlines if the quad is less than twice the size of the source
: 0.0f;
ScanlineCoord *= SourceDims.y * ScanlineScale * PI;
float ScanlineCoordJitter = ScanlineOffset * HalfPI;
float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter);
float ScanlineWide = ScanlineHeight + ScanlineVariation * max(1.0f, ScanlineHeight) * (1.0f - ColorBrightness);
float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide);
float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= mix(1.0f, ScanlineBrightness, ScanlineAlpha);
FragColor = BaseColor;
}
}

View file

@ -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;
}
}

View file

@ -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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB