From bd0ea94fc8abe6dd1ab1eef8928239fe00803398 Mon Sep 17 00:00:00 2001 From: hunterk Date: Mon, 9 Sep 2024 11:57:19 -0500 Subject: [PATCH] fix/update glow-trails shaders and presets (#634) * Update glow-trails0.slang to use aliased feedback * fix choppy glow on vector-glow-alt-render.slangp * fix vector-glow.slangp * fix crt-lottes-multipass-interlaced-glow to work with aliased feedback * Update glow_trails for aliased feedback * Create annotated_passthru.slang --- annotated_passthru.slang | 159 ++++++++++++++++++ crt/glow_trails.slangp | 1 + crt/shaders/glow-trails/glow-trails0.slang | 4 +- crt/vector-glow-alt-render.slangp | 14 +- crt/vector-glow.slangp | 51 +++--- ...rt-lottes-multipass-interlaced-glow.slangp | 1 + 6 files changed, 200 insertions(+), 30 deletions(-) create mode 100644 annotated_passthru.slang diff --git a/annotated_passthru.slang b/annotated_passthru.slang new file mode 100644 index 00000000..1bc3cf21 --- /dev/null +++ b/annotated_passthru.slang @@ -0,0 +1,159 @@ +#version 450 + +/* + Annotated Passthru slang shader + by hunterk + license: public domain +*/ + +/* This is a good spot for license blocks and other misc information */ + +/*-------------------- Pass Characteristics --------------------*/ +/* + Most of the pass characteristics/metadata is controlled by shader presets, but we can set a few things directly here via pragmas. + The 'format' pragma sets the output format for the framebuffer. These are the most common. 8-bit UNORM is the default + but integer and float formats can be useful for calculating values in one pass and then using the results in another +*/ +#pragma format R8G8B8A8_UNORM +/* + 8-bit + R8G8B8A8_UNORM + R8G8B8A8_UINT + R8G8B8A8_SINT + R8G8B8A8_SRGB + 10-bit + A2B10G10R10_UNORM_PACK32 + A2B10G10R10_UINT_PACK32 + 16-bit + R16G16B16A16_UINT + R16G16B16A16_SINT + R16G16B16A16_SFLOAT + 32-bit + R32G32B32A32_UINT + R32G32B32A32_SINT + R32G32B32A32_SFLOAT +*/ +/* See the spec document for any additional, more esoteric formats. */ + +/* We can use the 'name' pragma to declare a name (called an 'alias' in the presets) for the pass, which can make it easier for other shaders to reference it. + The alias/name can be used to refer to this pass specifically in other passes--FooSize, texture(Foo, coord), etc.--regardless of position/order. */ +#pragma name Foo + +/*------------- Parameters and Variable Structs --------------*/ +/* + This "push_constant" struct contains fast-access uniform data, which may provide better performance vs regular UBOs. + It has a max capacity of 192 bytes, which equates to 48 single-component vectors of float. + We usually use them for runtime parameters, hence the struct name, but you can change that if you like. +*/ +layout(push_constant) uniform Push +{ + float runtime_parameter, user_toggle_parameter, red, green, blue; +} params; + +/* + We can use a pragma to call out "parameters", which are exposed in RetroArch's shader menu for users to modify values on-the-fly without touching code directly. + These parameters are adjustable at runtime. The values are: default, minimum, maximum and step. +*/ +#pragma parameter runtime_parameter "Human-readable Parameter Name" 0.0 -10.0 10.0 0.01 +/* Some authors like to macro the struct name for easier code compatibility with other shader formats (i.e., so you don't need to prepend the struct name on each use): */ +#define runtime_parameter params.runtime_parameter + +/* Sometimes a basic float isn't what your code calls for, so you may want to cast parameters like this: */ +#pragma parameter user_toggle_parameter "A Simple Toggle" 0.0 0.0 1.0 1.0 +bool user_toggle = bool(params.user_toggle_parameter); + +/* or combine parameters like this into a multi-parameter vector of float: */ +#pragma parameter red "Red Channel Intensity" 1.0 0.0 2.0 0.01 +#pragma parameter green "Green Channel Intensity" 1.0 0.0 2.0 0.01 +#pragma parameter blue "Blue Channel Intensity" 1.0 0.0 2.0 0.01 +vec3 colorChannels = vec3(params.red, params.green, params.blue); + +/*-------------------- Include Statements --------------------*/ +/* + You can use include statements, which will copy the contents of the included file directly into this one at compile time. + If there's a possibility of recursive include statements, it's a good idea to wrap that code in an 'ifndef/define' block. +*/ +//#include "shared_parameters.inc" + +/*-------------------- Built-in Uniforms --------------------*/ +/* This "global" struct has no size limit, so if you run out of space in the push_constants struct, you can move things here. We also typically store our built-in uniforms here. */ +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +/* + A NOTE ABOUT 'FooSize': + The size of a built-in or aliased texture (e.g., Source, Original or, in this + case, Foo) can be accessed as a 4-parameter vector of float that includes the + width, height and the reciprocal of the width and height. Ideally, you can also + access the size of a LUT texture that has an alias set in the preset file, but + not all video drivers in RetroArch play nicely with this, so it's safer--but + slower--to use TextureSize() for that. +*/ +/* The size of the input framebuffer as presented to this stage in the shader pipeline */ + vec4 SourceSize; +/* The size of the raw input framebuffer as presented to the shader pipeline */ + vec4 OriginalSize; +/* The size of the outgoing framebuffer of the current pass */ + vec4 OutputSize; +/* The size of the outgoing framebuffer of the final shader pass, which should always be the size of the user's viewport. */ + vec4 FinalViewportSize; +/* The number of frames generated by the core. Used for animated effects. */ + uint FrameCount; +/* Which way the FrameCount is currently going. A negative value means the content is being "rewound". This is usually used for VCR or "Braid"-like effects. */ + uint FrameDirection; +/* If RetroArch's "subframe" feature is enabled, this ticks up on each subframe and resets on the next full frame. FrameCount is not affected by subframes. */ + uint CurrentSubFrame; +/* The total number of subframes. This number should stay consistent. The ratio of CurrentSubFrame / TotalSubFrames is frequently used. */ + uint TotalSubFrames; +/* The rotation status of the framebuffer. This is used to determine whether content is currently being rotated by the frontend for "TATE" mode (e.g., many arcade games, especially shmups) */ + uint Rotation; +} global; + +/* This is a good spot for common functions that may be used by both the vertex and fragment, since it is accessible in both stages. */ + +/*------------------------- Vertex Shader -------------------------*/ +/* We use pragmas to separate the stages of the shader into vertex and fragment in the same file: */ +#pragma stage vertex +/*--------------------- Vertex Inputs/Outputs ---------------------*/ +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out float calc_val; + +/* This is a good spot for vertex-specific functions. */ + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord; +/* + It's usually best to conduct expensive calculations in the vertex stage, where it's only performed once per vertex vs per-pixel in the fragment stage, + and then pass that value to the fragment, though this isn't possible with all calculations: +*/ + calc_val = (user_toggle) ? min(colorChannels.x, min(colorChannels.y, colorChannels.z)) : max(colorChannels.x, max(colorChannels.y, colorChannels.z)); +} + +/*--------------------- Fragment/Pixel Shader ---------------------*/ +#pragma stage fragment +/*-------------------- Fragment Inputs/Outputs --------------------*/ +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in float calc_val; +layout(location = 0) out vec4 FragColor; +/*------------------------ Texture Binding ------------------------*/ +/* Source is a built-in alias for the input framebuffer as presented to this stage in the shader pipeline. */ +layout(set = 0, binding = 2) uniform sampler2D Source; +/* PassFeedback* is a built-in alias for the shaded output of the selected pass; used for FIR effects. This can also be aliased, e.g., FooFeedback */ +layout(set = 0, binding = 3) uniform sampler2D PassFeedback0; +/* Original is a built-in alias for the raw input framebuffer as presented to the shader pipeline. */ +layout(set = 0, binding = 4) uniform sampler2D Original; +/* OriginalHistory* is a built-in alias for the input framebuffer from previous frames, working backward. */ +layout(set = 0, binding = 5) uniform sampler2D OriginalHistory1; + +/* This is a good spot for fragment-specific functions. */ + +void main() +{ + vec3 img = texture(Source, vTexCoord).rgb; + img *= colorChannels; + FragColor = vec4(img, 1.0); +} diff --git a/crt/glow_trails.slangp b/crt/glow_trails.slangp index c7d636df..1193f7cf 100644 --- a/crt/glow_trails.slangp +++ b/crt/glow_trails.slangp @@ -7,6 +7,7 @@ shader1 = ../crt/shaders/glow-trails/glow-trails0.slang filter_linear1 = false scale_type1 = source scale1 = 1.0 +alias1 = Trails0 # replace the blur passes with stock for sharp trails shader2 = "../blurs/shaders/royale/blur9fast-vertical.slang" diff --git a/crt/shaders/glow-trails/glow-trails0.slang b/crt/shaders/glow-trails/glow-trails0.slang index 3953ad4d..ff5c1d74 100644 --- a/crt/shaders/glow-trails/glow-trails0.slang +++ b/crt/shaders/glow-trails/glow-trails0.slang @@ -51,14 +51,14 @@ void main() 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 PassFeedback1; +layout(set = 0, binding = 3) uniform sampler2D Trails0Feedback; void main() { vec3 frame = texture(Source, vTexCoord).rgb; float luma = (frame.rrr * yiq_mat).r; float trails = clamp(luma - params.threshold, 0.0, 1.0); - vec4 fdback = pow(texture(PassFeedback1, vTexCoord), vec4(2.2)); + vec4 fdback = pow(texture(Trails0Feedback, vTexCoord), vec4(2.2)); vec4 mixed = clamp((1.0 - params.mixfactor) * vec4(trails) - params.mixfactor * fdback, 0.0, 1.0) + params.mixfactor * fdback; // vec4 current = pow(texture(Source, vTexCoord), vec4(2.2)); diff --git a/crt/vector-glow-alt-render.slangp b/crt/vector-glow-alt-render.slangp index 1cf01c5f..9d9b72a6 100644 --- a/crt/vector-glow-alt-render.slangp +++ b/crt/vector-glow-alt-render.slangp @@ -2,22 +2,24 @@ shaders = 4 shader0 = "../misc/shaders/image-adjustment.slang" alias0 = PASS1 +wrap_mode0 = mirrored_repeat -shader1 = "../blurs/shaders/royale/blur11fast-vertical.slang" +shader1 = "../blurs/shaders/royale/blur43fast-vertical.slang" filter_linear1 = "true" scale_type1 = "source" -scale1 = "0.5" -mipmap_input1 = "true" +scale1 = "1.0" +wrap_mode1 = mirrored_repeat -shader2 = "../blurs/shaders/royale/blur11fast-horizontal.slang" +shader2 = "../blurs/shaders/royale/blur43fast-horizontal.slang" filter_linear2 = "true" scale_type2 = "source" -scale2 = "0.5" -mipmap_input2 = "true" +scale2 = "1.0" +wrap_mode2 = mirrored_repeat shader3 = "shaders/glow-trails/combine.slang" scale_type3 = "viewport" scale3 = 1.0 +wrap_mode3 = mirrored_repeat parameters = "mixfactor;threshold;trail_bright;glowFactor;haze_strength;luminance;screen_combine" mixfactor = "0.18" diff --git a/crt/vector-glow.slangp b/crt/vector-glow.slangp index 1a0cdcff..dc4c9dfb 100644 --- a/crt/vector-glow.slangp +++ b/crt/vector-glow.slangp @@ -1,44 +1,51 @@ -shaders = 9 +shaders = 10 -shader0 = shaders/glow-trails/glow-trails0.slang -filter_linear0 = false +shader0 = ../../stock.slang scale_type0 = source scale0 = 1.0 +filter_linear0 = false +alias0 = glow_trails_refpass -shader1 = "../blurs/shaders/royale/blur9fast-vertical.slang" -filter_linear1 = "true" -scale_type1 = "source" -scale1 = "1.0" -srgb_framebuffer1 = "true" +shader1 = shaders/glow-trails/glow-trails0.slang +filter_linear1 = false +scale_type1 = source +scale1 = 1.0 +alias1 = Trails0 -shader2 = "../blurs/shaders/royale/blur9fast-horizontal.slang" -alias2 = "TRAIL_BLUR" +shader2 = "../blurs/shaders/royale/blur9fast-vertical.slang" filter_linear2 = "true" scale_type2 = "source" scale2 = "1.0" srgb_framebuffer2 = "true" -shader3 = shaders/glow-trails/glow-trails1.slang +shader3 = "../blurs/shaders/royale/blur9fast-horizontal.slang" +alias3 = "TRAIL_BLUR" +filter_linear3 = "true" +scale_type3 = "source" +scale3 = "1.0" +srgb_framebuffer3 = "true" -shader4 = "../anti-aliasing/shaders/advanced-aa.slang" -alias4 = PASS1 +shader4 = shaders/glow-trails/glow-trails1.slang -shader5 = "../blurs/shaders/royale/blur9fast-vertical.slang" -filter_linear5 = "true" -scale_type5 = "source" -scale5 = "1.0" -srgb_framebuffer5 = "true" +shader5 = "../anti-aliasing/shaders/advanced-aa.slang" +alias5 = PASS1 -shader6 = "../blurs/shaders/royale/blur9fast-horizontal.slang" +shader6 = "../blurs/shaders/royale/blur9fast-vertical.slang" filter_linear6 = "true" scale_type6 = "source" scale6 = "1.0" srgb_framebuffer6 = "true" -shader7 = "shaders/glow-trails/combine.slang" +shader7 = "../blurs/shaders/royale/blur9fast-horizontal.slang" +filter_linear7 = "true" +scale_type7 = "source" +scale7 = "1.0" +srgb_framebuffer7 = "true" -shader8 = "../misc/shaders/image-adjustment.slang" -scale_type8 = viewport +shader8 = "shaders/glow-trails/combine.slang" + +shader9 = "../misc/shaders/image-adjustment.slang" +scale_type9 = viewport parameters = "mixfactor;threshold;trail_bright;glowFactor;haze_strength;luminance;bright" mixfactor = "0.18" diff --git a/presets/crt-lottes-multipass-interlaced-glow.slangp b/presets/crt-lottes-multipass-interlaced-glow.slangp index 5e26167f..14f50d26 100644 --- a/presets/crt-lottes-multipass-interlaced-glow.slangp +++ b/presets/crt-lottes-multipass-interlaced-glow.slangp @@ -7,6 +7,7 @@ shader1 = ../crt/shaders/glow-trails/glow-trails0.slang filter_linear1 = false scale_type1 = source scale1 = 1.0 +alias1 = Trails0 shader2 = "../blurs/shaders/royale/blur9fast-vertical.slang" filter_linear2 = "true"