slang-shaders/bezel/koko-aio/shaders/ambi_pre_pass.slang

130 lines
4.8 KiB
Plaintext
Raw Normal View History

2022-12-06 11:48:10 +11:00
#version 450
/* This pass simulates the presence of a led strip placed on the back of the virtual screen */
#include "config.inc"
#define internalness 0.07 //The distance between the screen border and the led strip
#define leds_per_strip 8 //How many leds per border
#define radius 0.001 //The base radius of the emitted light (tuned by user parameter later)
#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 float border_min;
layout(location = 2) out float border_max;
layout(location = 3) out float fstep;
layout(location = 4) out float lod;
void main() {
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
border_min=internalness ;
border_max=1.0-internalness ;
fstep = (border_max - border_min) / (leds_per_strip-1);
//Calc a lod for a texture sized led_strip x led_strip
lod = log2(params.SourceSize.y / leds_per_strip);
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 1) in float border_min;
layout(location = 2) in float border_max;
layout(location = 3) in float fstep;
layout(location = 4) in float lod;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D isrotated_passFeedback;
layout(set = 0, binding = 4) uniform sampler2D ambi_pre_pass1Feedback;
#include "includes/functions.include.slang"
vec3 circle_smooth(vec2 coords, vec2 middle, float f_radius, float FALLOFF, float f_lod) {
float fdistance=distance(middle, vec2(coords.x, coords.y));
float circle = (1-smoothstep(f_radius-FALLOFF, f_radius+FALLOFF, fdistance));
vec3 circle_color = textureLod(Source, middle, f_lod).rgb * circle;
return circle_color;
}
#define tol_start 0.06 //skip tolerance
#define tol_end 0.94 //1-tol_start
/*
To spare gpu cycles, completely skip the pass
by the following factor and return instead the previous
(temporal) frame. The trick works because the pass is
temporal smoothed later on.
The only downside is that the leds will have less reaction time.
Esample:
a FRAME_DIVIDER = 3 over a 60hz content will give
a minimum reaction time of 60/3=20Hz=50msecs.
*/
#define FRAME_DIVIDER 3
void main() {
if (DO_AMBILIGHT != 1.0) return;
if ( mod(params.FrameCount, FRAME_DIVIDER) != 0.0) {
FragColor = texture(ambi_pre_pass1Feedback, vTexCoord);
return;
}
bool is_rotated = texture(isrotated_passFeedback, vec2(0.5, 0.5)).r > 0.5;
//Scale to the original aspect
vec2 coords = get_scaled_coords(vTexCoord, global.FinalViewportSize, is_rotated);
if (DO_BEZEL==1.0) coords = zoomout_coords(coords, -BEZEL_INNER_ZOOM , 1.0);
//Skip coords in the rect "under the monitor"
FragColor = vec4(0.0);
//First consider to skip the curved coords
if (DO_CURVATURE == 1.0) {
if ((GEOM_WARP_X > 0.0) || (GEOM_WARP_Y > 0.0)) {
vec2 coords_curved = Warp(coords, GEOM_WARP_X, GEOM_WARP_Y);
if ( ( (coords_curved.x > tol_start && coords_curved.x < 1.0 - tol_start ) && (coords_curved.y > tol_start && coords_curved.y < 1.0 - tol_start) ) &&
!( (coords.x < - tol_start || coords.x > 1.0 + tol_start) || (coords.y < - tol_start || coords.y > 1.0 + tol_start) ) )
return;
}
}
//...next, the straight ones (needed even when curvature is due, because it returns particular values in the corners)
//skip_pass = skip_pass && !( (coords.x < 0.0 -tol || coords.x > 1.0 +tol) || (coords.y < 0.0 -tol || coords.y > 1.0 +tol) );
if (coords.x > tol_start && coords.x < tol_end && coords.y > tol_start && coords.y < tol_end) return;
//Finally, emulate leds.
vec3 pixel_out = vec3(0.0);
float middle_x; float middle_y ;
middle_x=border_min;
for (middle_y=border_min ; middle_y <= border_max+eps ; middle_y=middle_y + fstep ) {
pixel_out +=circle_smooth(coords, vec2(middle_x,middle_y), radius, AMBI_FALLOFF, lod);
}
middle_x=border_max;
for (middle_y=border_min ; middle_y <= border_max+eps ; middle_y=middle_y + fstep ) {
pixel_out +=circle_smooth(coords, vec2(middle_x,middle_y), radius, AMBI_FALLOFF, lod);
}
middle_y=border_min;
for (middle_x=border_min+fstep ; middle_x <= border_max-fstep+eps ; middle_x=middle_x + fstep ) {
pixel_out +=circle_smooth(coords, vec2(middle_x,middle_y), radius, AMBI_FALLOFF, lod);
}
middle_y=border_max;
for (middle_x=border_min+fstep ; middle_x <= border_max-fstep+eps ; middle_x=middle_x + fstep ) {
pixel_out +=circle_smooth(coords, vec2(middle_x,middle_y), radius, AMBI_FALLOFF, lod);
}
FragColor = vec4(pixel_out,1.0);
return;
}