mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-23 16:11:31 +11:00
141 lines
5.2 KiB
C++
141 lines
5.2 KiB
C++
/*
|
|
Mega Bezel - Creates a graphic treatment for the game play area to give a retro feel
|
|
Copyright (C) 2019-2022 HyperspaceMadness - HyperspaceMadness@outlook.com
|
|
|
|
Incorporates much great feedback from the libretro forum, and thanks
|
|
to Hunterk who helped me get started
|
|
|
|
See more at the libretro forum
|
|
https://forums.libretro.com/t/hsm-mega-bezel-reflection-shader-feedback-and-updates
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see [http://www.gnu.org/licenses/].
|
|
*/
|
|
|
|
#include "common/globals-and-reflection-params.inc"
|
|
#include "common/common-functions-bezel.inc"
|
|
|
|
#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 VIEWPORT_COORD;
|
|
|
|
void main()
|
|
{
|
|
gl_Position = global.MVP * Position;
|
|
vTexCoord = TexCoord * 1.0001;
|
|
VIEWPORT_COORD = vTexCoord;
|
|
}
|
|
|
|
#pragma stage fragment
|
|
layout(location = 0) in vec2 vTexCoord;
|
|
layout(location = 1) in vec2 VIEWPORT_COORD;
|
|
|
|
layout(location = 0) out vec4 FragColor;
|
|
|
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
|
layout(set = 0, binding = 3) uniform sampler2D BR_MirrorLowResPass;
|
|
|
|
layout(set = 0, binding = 4) uniform sampler2D InfoCachePass;
|
|
layout(set = 0, binding = 5) uniform sampler2D InfoCachePassFeedback;
|
|
|
|
float clamp_0_1(float in_value)
|
|
{
|
|
return clamp(in_value, 0, 1);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
if (HSM_REFLECT_BLUR_NUM_SAMPLES > 0)
|
|
{
|
|
vec2 viewportCoordTransformed = HSM_GetViewportCoordWithZoomAndPan(vTexCoord);
|
|
HSM_UpdateGlobalScreenValuesFromCache(InfoCachePass, InfoCachePassFeedback, vTexCoord);
|
|
|
|
vec2 tube_curved_coord_ctr = HSM_GetTubeCurvedCoord(TUBE_DIFFUSE_COORD, 1, TUBE_DIFFUSE_SCALE, TUBE_SCALE, TUBE_DIFFUSE_ASPECT, 1) - 0.5;
|
|
|
|
//----------------------------------------------------
|
|
// Calculate Outside mapping Coords
|
|
//----------------------------------------------------
|
|
|
|
/* This first big chunk is to get a mapping of the space outside of the screen which is continuous
|
|
This is more complicated than you would expect because since we are using curved coordinates
|
|
there are discontinuities outside the normal screen corners, e.g. where x > 1 and y > 1
|
|
So instead of trying to use the coordinates from the screen/tube we use a larger space
|
|
and subtract the screen space to see how far we are outside of the sreen
|
|
*/
|
|
|
|
// Additional scale to be applied to the tube scale to create an expanded mapping area
|
|
vec2 outermap_scale = vec2(1, 1) * (1.3 + 1);
|
|
|
|
// Get a range width from the outer tube edge to the outer edge of the outermap
|
|
float outermap_range = 0.5 * (outermap_scale.y) * 0.7;
|
|
vec2 outermap_warped_coord_ctr = tube_curved_coord_ctr;
|
|
vec2 outermap_warped_outside_screen_vector = outermap_warped_coord_ctr - clamp(outermap_warped_coord_ctr, -0.490, 0.490);
|
|
float outside_ratio_warped = clamp(length(outermap_warped_outside_screen_vector) / outermap_range, 0, 1);
|
|
|
|
float hbl_sharpness_falloff_distance = 7 * HSM_REFLECT_BLUR_FALLOFF_DISTANCE;
|
|
if (HSM_GLASS_BORDER_ON == 1)
|
|
hbl_sharpness_falloff_distance = 20;
|
|
|
|
float blur_ratio = clamp_0_1(outside_ratio_warped / (hbl_sharpness_falloff_distance / 100));
|
|
float blur_midpoint = 0.12;
|
|
float hbl_sharpness_falloff_speed = 1;
|
|
blur_ratio = HHLP_QuadraticBezier (clamp_0_1(blur_ratio - blur_midpoint), vec2(0.05, hbl_sharpness_falloff_speed));
|
|
|
|
|
|
blur_ratio = HSM_REFLECT_BLUR_MIN + blur_ratio * (HSM_REFLECT_BLUR_MAX - HSM_REFLECT_BLUR_MIN);
|
|
|
|
vec3 col = vec3(0.0);
|
|
|
|
#ifdef VERTICAL_BLUR
|
|
float dx = 0;
|
|
float dy = global.SourceSize.w;
|
|
#else
|
|
float dx = global.SourceSize.z;
|
|
float dy = 0;
|
|
#endif
|
|
|
|
// This bizarre bit is to try to take the non linear nature of the blur falloff value and make it into a more linear behavior
|
|
float last_blur_ratio_blend_point = 0.6;
|
|
|
|
float max_blur_range = 7;
|
|
float min_blur_range = 10;
|
|
float blur_falloff = ( 0.5 +
|
|
max_blur_range * smoothstep(1, last_blur_ratio_blend_point, blur_ratio) +
|
|
min_blur_range * smoothstep(last_blur_ratio_blend_point, 0, blur_ratio)
|
|
) / 100;
|
|
|
|
float blend_with_unblurred = smoothstep(-0.3, 0.3, HHLP_QuadraticBezier(blur_ratio, vec2(0.5, 0.5)));
|
|
|
|
float k_total = 0.;
|
|
for (float i = -HSM_REFLECT_BLUR_NUM_SAMPLES; i <= HSM_REFLECT_BLUR_NUM_SAMPLES; i++)
|
|
{
|
|
float k = exp(-blur_falloff * (i) * (i));
|
|
k_total += k;
|
|
|
|
vec2 sample_coord = vTexCoord + vec2(float(i) * dx, float(i) * dy);
|
|
vec4 sampled_color = texture(Source, sample_coord);
|
|
|
|
col += k * sampled_color.rgb;
|
|
}
|
|
vec4 blurred_color = vec4(col / k_total, 1.0);
|
|
|
|
vec4 unblurred_color = texture(BR_MirrorLowResPass, vTexCoord);
|
|
FragColor = mix(unblurred_color, blurred_color, blend_with_unblurred);
|
|
}
|
|
else
|
|
{
|
|
FragColor = texture(Source, vTexCoord);
|
|
}
|
|
} |