slang-shaders/bezel/koko-aio/shaders/first_pass.slang
2022-12-05 18:48:10 -06:00

178 lines
5.5 KiB
Plaintext

#version 450
#include "config.inc"
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
layout(location = 4) out vec3 temperature_rgb;
#include "includes/functions.include.slang"
vec3 kelvin2rgb(float k) {
//Convert kelvin temperature to rgb factors
k = clamp(k,1000,40000);
k=k/100.0;
float tmpCalc;
vec3 pixel_out;
if (k<=66) {
pixel_out.r = 255;
pixel_out.g = 99.47080258612 * log(k) - 161.11956816610;
} else {
pixel_out.r = 329.6987274461 * pow(k - 60 ,-0.13320475922);
pixel_out.g = 288.12216952833 * pow(k-60, -0.07551484921);
}
if (k >= 66)
pixel_out.b = 255;
else if (k<=19)
pixel_out.b = 0;
else
pixel_out.b = 138.51773122311 * log(k - 10) - 305.04479273072;
return pixel_out/255.0;
}
void main() {
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
if (TEMPERATURE != 6500)
temperature_rgb = kelvin2rgb(TEMPERATURE);
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 4) in vec3 temperature_rgb;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
#include "includes/functions.include.slang"
vec3 color_tools(vec3 pixel_out) {
//Apply color corrections to input signal.
//Push luminance without clipping
pixel_out = pixel_push_luminance(pixel_out,LUMINANCE);
//Modify saturation
if (!(SATURATION == 1.0)) {
const vec3 W = vec3(0.2125, 0.7154, 0.0721);
vec3 intensity = vec3(dot(pixel_out.rgb, W));
pixel_out.rgb = mix(intensity, pixel_out.rgb, SATURATION);
}
//Modify contrast and brightness
if (CONTRAST != 0.0 || BRIGHTNESS != 0.0)
pixel_out.rgb = scale_to_range_vec3(pixel_out.rgb, -CONTRAST, 1+CONTRAST) + BRIGHTNESS;
//Modify color temperature
if (TEMPERATURE != 6500.0) pixel_out.rgb = pixel_out.rgb * temperature_rgb;
return pixel_out;
}
vec3 pixel_no_flicker(vec2 coord){
vec3 pixel_out = texture(Source,coord).rgb;
if (DO_CCORRECTION == 1.0)
pixel_out = color_tools(pixel_out);
return pixel_out.rgb;
}
vec3 pixel_flickering() {
/* Simulates the flickering effect of the interlaced screens.
* As I remember, it was visible when a line and the next had high
* luminosity differences.
* So we need sample the current line and the previous one
* (eventually applying color corrections to both).
*
* Repeating the following:
* On frame 0, return the "clean" pixel
* On frame 1, mix the upper pixel with the current one
* On frame 2, mix the lower pixel with the current one
*
* The effect of the mix is the flickering itself, and we modulate
* the mix according to the luminance difference between the current
* pixel and the mixed one.
*
* We choose to alternate on a period of 3,
* (thus considering the upper pixel and the lower one)
* or else the high pixel persistance of lcd displays wont allow
* to see the effect (the lcd panel would just mix the pixels by itself (meh).
*/
vec3 pixel_cur = pixel_no_flicker(vTexCoord);
float mymod = params.FrameCount % 3;
if (mymod == 0.0) return pixel_cur;
float line_tick = (params.OriginalSize.y > MIN_LINES_INTERLACED ) ? 1 : 2 ;
vec3 flickline;
if (mymod == 1.0 )
flickline = pixel_no_flicker(vTexCoord + vec2(0.0,params.OriginalSize.w/line_tick));
else if (mymod == 2.0)
flickline = pixel_no_flicker(vTexCoord - vec2(0.0,params.OriginalSize.w/line_tick));
float lumdiff = (flickline.r+flickline.g+flickline.b)/3.0 -
(pixel_cur.r+pixel_cur.g+pixel_cur.b)/3.0;
if (lumdiff > 0.0) {
lumdiff = scale_to_range(lumdiff,0.0,SCANLINE_FLICKERING_POWER);
return mix(pixel_cur,flickline,lumdiff);
} else {
return pixel_cur;
}
}
void debug() {
//Just test patterns here
vec3 pixel_debug;
//Use one of the following to debug:
//pixel_debug=vec3(abs(sin(params.FrameCount/3.14/8.0))); //white fade
//pixel_debug=vec3(abs(sin(params.FrameCount/3.14/20)),0.0,0.0); //red fade
//pixel_debug=vec3(1.0);
//pixel_debug=vec3(0.0,1.0,0.0);
//pixel_debug=vec3(0.38,0.0,1.0)*vTexCoord.x;
pixel_debug=vec3(vTexCoord.x); //H bw gradient
//pixel_debug=vec3(floor(vTexCoord.x*16)/16); //H bw gradient 16gray
//pixel_debug=vec3(floor(vTexCoord.x*64)/64); //H bw gradient 64gray
//pixel_debug=vec3(floor(vTexCoord.x*128)/128); //H bw gradient 128gray
//pixel_debug=vec3(1,0,0,0)*floor(vTexCoord.x*64)/64; //H red gradient 64
//if (mod(params.FrameCount,100) < 50) pixel_debug=vec3(0.0) ; else pixel_debug=vec3(1.0);
//FragColor = vec4(color_tools(pixel_debug).rgb,1.0);
FragColor = vec4(pixel_debug,1.0);
}
void main() {
//debug(); return;
/* since flickering code needs
luminosity difference between 2 vertical lines
both have to be processed through color corrections and rgb pixel offsets.
before flickering code can operate. (pixel_no_flicker)
Therefore we call pixel_no_flicker inside it when we want flickering scanlines
and outside id when we dont.
*/
if (DO_SCANLINES == 0.0) {
FragColor= vec4(pixel_no_flicker(vTexCoord),1.0);
return;
}
//Implicit else: DO_SCANLINES == 1.0
if (scanline_have_to_flicker(is_interlaced())) {
FragColor = vec4(pixel_flickering(),1.0);
return;
}
//Implicit else: DO_SCANLINES == 1.0 but no flickering needed.
FragColor = vec4(pixel_no_flicker(vTexCoord),1.0);
}