From 239b6f01be33ee117f42d3f89b7f9ead393b2b29 Mon Sep 17 00:00:00 2001 From: hunterk Date: Tue, 28 Apr 2020 22:37:24 -0500 Subject: [PATCH] add modular image adjustment shader --- include/img/black_lvl.h | 12 +++ include/img/black_lvl_dogway.h | 12 +++ include/img/border_mask.h | 17 +++ include/img/bright_con.h | 16 +++ include/img/cgwg_warp.h | 78 ++++++++++++++ include/img/channel_mix.h | 13 +++ include/img/col_mangler.h | 23 ++++ include/img/col_tools.h | 6 ++ include/img/corner.h | 20 ++++ include/img/curvature.h | 113 ++++++++++++++++++++ include/img/exp_gamma.h | 19 ++++ include/img/film_grain.h | 27 +++++ include/img/gamma_srgb.h | 19 ++++ include/img/gristle_warp.h | 23 ++++ include/img/helper_macros.h | 71 +++++++++++++ include/img/image_flip.h | 16 +++ include/img/int_ar.h | 28 +++++ include/img/lottes_warp.h | 16 +++ include/img/lum_chrom.h | 18 ++++ include/img/lut1.h | 29 ++++++ include/img/lut2.h | 43 ++++++++ include/img/moncurve.h | 45 ++++++++ include/img/param_floats.h | 67 ++++++++++++ include/img/sat_lum.h | 21 ++++ include/img/sharpening.h | 24 +++++ include/img/sigmoidal_con.h | 54 ++++++++++ include/img/stretch_zoom_pan.h | 23 ++++ include/img/subpx_masks.h | 11 ++ include/img/vignette.h | 17 +++ include/img/white_point.h | 60 +++++++++++ misc/colorspace-tools.h | 26 +++++ misc/img_mod.slang | 185 +++++++++++++++++++++++++++++++++ misc/img_mod.slangp | 7 ++ 33 files changed, 1159 insertions(+) create mode 100644 include/img/black_lvl.h create mode 100644 include/img/black_lvl_dogway.h create mode 100644 include/img/border_mask.h create mode 100644 include/img/bright_con.h create mode 100644 include/img/cgwg_warp.h create mode 100644 include/img/channel_mix.h create mode 100644 include/img/col_mangler.h create mode 100644 include/img/col_tools.h create mode 100644 include/img/corner.h create mode 100644 include/img/curvature.h create mode 100644 include/img/exp_gamma.h create mode 100644 include/img/film_grain.h create mode 100644 include/img/gamma_srgb.h create mode 100644 include/img/gristle_warp.h create mode 100644 include/img/helper_macros.h create mode 100644 include/img/image_flip.h create mode 100644 include/img/int_ar.h create mode 100644 include/img/lottes_warp.h create mode 100644 include/img/lum_chrom.h create mode 100644 include/img/lut1.h create mode 100644 include/img/lut2.h create mode 100644 include/img/moncurve.h create mode 100644 include/img/param_floats.h create mode 100644 include/img/sat_lum.h create mode 100644 include/img/sharpening.h create mode 100644 include/img/sigmoidal_con.h create mode 100644 include/img/stretch_zoom_pan.h create mode 100644 include/img/subpx_masks.h create mode 100644 include/img/vignette.h create mode 100644 include/img/white_point.h create mode 100644 misc/img_mod.slang create mode 100644 misc/img_mod.slangp diff --git a/include/img/black_lvl.h b/include/img/black_lvl.h new file mode 100644 index 0000000..1750651 --- /dev/null +++ b/include/img/black_lvl.h @@ -0,0 +1,12 @@ +#ifndef BLACK_LVL +#define BLACK_LVL + +#pragma parameter ia_black_level "Black Level" 0.00 -0.50 0.50 0.01 + +vec3 black_level(vec3 in_col){ + vec3 out_col = in_col - vec3(ia_black_level); + out_col *= (vec3(1.0) / vec3(1.0 - ia_black_level)); + return out_col; +} + +#endif diff --git a/include/img/black_lvl_dogway.h b/include/img/black_lvl_dogway.h new file mode 100644 index 0000000..fc536bc --- /dev/null +++ b/include/img/black_lvl_dogway.h @@ -0,0 +1,12 @@ +#ifndef BLACK_LVL +#define BLACK_LVL + +#pragma parameter ia_black_level "Black Level" 0.00 -0.50 0.50 0.01 + +vec3 black_level(vec3 in_col){ + vec3 out_col = in_col; + out_col += (ia_black_level / 20.0) * (1.0 - out_col); + return out_col; +} + +#endif diff --git a/include/img/border_mask.h b/include/img/border_mask.h new file mode 100644 index 0000000..5940429 --- /dev/null +++ b/include/img/border_mask.h @@ -0,0 +1,17 @@ +#ifndef BORDER_MASK +#define BORDER_MASK + +#pragma parameter ia_TOPMASK "Overscan Mask Top" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_BOTMASK "Overscan Mask Bottom" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_LMASK "Overscan Mask Left" 0.0 0.0 1.0 0.0025 +#pragma parameter ia_RMASK "Overscan Mask Right" 0.0 0.0 1.0 0.0025 + +vec3 border_mask(vec3 in_col, vec2 coord){ + vec3 out_col = (coord.y > ia_TOPMASK && coord.y < (1.0 - ia_BOTMASK)) ? + in_col : vec3(0.0); + out_col = (coord.x > ia_LMASK && coord.x < (1.0 - ia_RMASK)) ? + out_col : vec3(0.0); + return out_col; +} + +#endif diff --git a/include/img/bright_con.h b/include/img/bright_con.h new file mode 100644 index 0000000..a1ff273 --- /dev/null +++ b/include/img/bright_con.h @@ -0,0 +1,16 @@ +#ifndef BRIGHT_CON +#define BRIGHT_CON + +#pragma parameter ia_contrast "Contrast" 1.0 0.0 10.0 0.05 +#pragma parameter ia_bright_boost "Brightness Boost" 0.0 -1.0 1.0 0.05 + +vec3 cntrst(vec3 in_col){ + vec3 out_col = in_col - 0.5; + out_col *= ia_contrast; + out_col += 0.5; + out_col += ia_bright_boost; + out_col = clamp(out_col, 0.0, 1.0); + return out_col; +} + +#endif diff --git a/include/img/cgwg_warp.h b/include/img/cgwg_warp.h new file mode 100644 index 0000000..3c9de9a --- /dev/null +++ b/include/img/cgwg_warp.h @@ -0,0 +1,78 @@ +#ifndef CURV +#define CURV + +#pragma parameter Radius "cgwg Curvature Radius" 2.0 0.1 10.0 0.1 +#pragma parameter Distance "cgwg Viewing Distance" 1.5 0.1 3.0 0.1 +#pragma parameter x_tilt "Horizontal Tilt" 0.0 -0.5 0.5 0.05 +#pragma parameter y_tilt "Vertical Tilt" 0.0 -0.5 0.5 0.05 + +// cgwg's geom +// license: GPLv2 + +vec2 sinangle = sin(vec2(x_tilt, y_tilt)); +vec2 cosangle = cos(vec2(x_tilt, y_tilt)); +const vec2 aspect = vec2(1.0, 0.75); +#define FIX(c) max(abs(c), 1e-5); + +float intersect(vec2 xy) +{ + float A = dot(xy,xy) + Distance*Distance; + float B = 2.0*(Radius*(dot(xy,sinangle) - Distance*cosangle.x*cosangle.y) - Distance*Distance); + float C = Distance*Distance + 2.0*Radius*Distance*cosangle.x*cosangle.y; + + return (-B-sqrt(B*B - 4.0*A*C))/(2.0*A); +} + +vec2 fwtrans(vec2 uv) +{ + float r = FIX(sqrt(dot(uv,uv))); + uv *= sin(r/Radius)/r; + float x = 1.0-cos(r/Radius); + float D = Distance/Radius + x*cosangle.x*cosangle.y+dot(uv,sinangle); + + return Distance*(uv*cosangle-x*sinangle)/D; +} + +vec2 bkwtrans(vec2 xy) +{ + float c = intersect(xy); + vec2 point = (vec2(c, c)*xy - vec2(-Radius, -Radius)*sinangle) / vec2(Radius, Radius); + vec2 poc = point/cosangle; + vec2 tang = sinangle/cosangle; + + float A = dot(tang, tang) + 1.0; + float B = -2.0*dot(poc, tang); + float C = dot(poc, poc) - 1.0; + + float a = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A); + vec2 uv = (point - a*sinangle) / cosangle; + float r = Radius*acos(a); + r = FIX(r); + + return uv*r/sin(r/Radius); +} + +vec3 maxscale() +{ + vec2 c = bkwtrans(-Radius * sinangle / (1.0 + Radius/Distance*cosangle.x*cosangle.y)); + vec2 a = vec2(0.5,0.5)*aspect; + + vec2 lo = vec2(fwtrans(vec2(-a.x, c.y)).x, + fwtrans(vec2( c.x, -a.y)).y)/aspect; + + vec2 hi = vec2(fwtrans(vec2(+a.x, c.y)).x, + fwtrans(vec2( c.x, +a.y)).y)/aspect; + + return vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y)); +} + +vec2 warp(vec2 coord) +{ + vec3 stretch = maxscale(); + coord = (coord - vec2(0.5, 0.5))*aspect*stretch.z + stretch.xy; + + return (bkwtrans(coord) / + vec2(1.0, 1.0)/aspect + vec2(0.5, 0.5)); +} + +#endif diff --git a/include/img/channel_mix.h b/include/img/channel_mix.h new file mode 100644 index 0000000..dc11414 --- /dev/null +++ b/include/img/channel_mix.h @@ -0,0 +1,13 @@ +#ifndef CHANNEL_MIX +#define CHANNEL_MIX + +#pragma parameter ia_rr "Red Channel" 1.0 0.0 2.0 0.01 +#pragma parameter ia_gg "Green Channel" 1.0 0.0 2.0 0.01 +#pragma parameter ia_bb "Blue Channel" 1.0 0.0 2.0 0.01 + +vec3 channel_mix(vec3 in_col){ + vec3 out_col = in_col * vec3(ia_rr, ia_gg, ia_bb); + return out_col; +} + +#endif diff --git a/include/img/col_mangler.h b/include/img/col_mangler.h new file mode 100644 index 0000000..52cb31e --- /dev/null +++ b/include/img/col_mangler.h @@ -0,0 +1,23 @@ +#ifndef CHANNEL_MIX +#define CHANNEL_MIX + +#pragma parameter ia_rr "Red Channel" 1.0 0.0 2.0 0.01 +#pragma parameter ia_gg "Green Channel" 1.0 0.0 2.0 0.01 +#pragma parameter ia_bb "Blue Channel" 1.0 0.0 2.0 0.01 +#pragma parameter ia_rg "Red-Green Tint" 0.0 0.0 1.0 0.005 +#pragma parameter ia_rb "Red-Blue Tint" 0.0 0.0 1.0 0.005 +#pragma parameter ia_gr "Green-Red Tint" 0.0 0.0 1.0 0.005 +#pragma parameter ia_gb "Green-Blue Tint" 0.0 0.0 1.0 0.005 +#pragma parameter ia_br "Blue-Red Tint" 0.0 0.0 1.0 0.005 +#pragma parameter ia_bg "Blue-Green Tint" 0.0 0.0 1.0 0.005 + +mat3 mangler = mat3( ia_rr, ia_rg, ia_rb, //red channel + ia_gr, ia_gg, ia_gb, //green channel + ia_br, ia_bg, ia_bb); //blue channel + +vec3 channel_mix(vec3 in_col){ + vec3 out_col = in_col * mangler; + return out_col; +} + +#endif diff --git a/include/img/col_tools.h b/include/img/col_tools.h new file mode 100644 index 0000000..396d477 --- /dev/null +++ b/include/img/col_tools.h @@ -0,0 +1,6 @@ +#ifndef COL_TOOLS +#define COL_TOOLS + +#include "../../misc/colorspace-tools.h" + +#endif diff --git a/include/img/corner.h b/include/img/corner.h new file mode 100644 index 0000000..5659776 --- /dev/null +++ b/include/img/corner.h @@ -0,0 +1,20 @@ +#ifndef CORNER +#define CORNER + +#pragma parameter cornersize "Corner Size" 0.03 0.001 1.0 0.005 +#pragma parameter cornersmooth "Corner Smoothness" 1000.0 80.0 2000.0 100.0 + +const vec2 corner_aspect = vec2(1.0, 0.75); + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) + vec2(0.5, 0.5); + coord = min(coord, vec2(1.0) - coord) * corner_aspect; + vec2 cdist = vec2(cornersize); + coord = (cdist - min(coord, cdist)); + float dist = sqrt(dot(coord, coord)); + + return clamp((cdist.x - dist)*cornersmooth, 0.0, 1.0); +} + +#endif diff --git a/include/img/curvature.h b/include/img/curvature.h new file mode 100644 index 0000000..a5773f5 --- /dev/null +++ b/include/img/curvature.h @@ -0,0 +1,113 @@ +#ifndef CURV +#define CURV + +// A collection of 2D curvature/warp functions + +// torridgristle +vec2 tg_warp(vec2 texCoord){ + vec2 Distortion = vec2(warpX, warpY) * 15.; + vec2 curvedCoords = texCoord * 2.0 - 1.0; + float curvedCoordsDistance = sqrt(curvedCoords.x*curvedCoords.x+curvedCoords.y*curvedCoords.y); + + curvedCoords = curvedCoords / curvedCoordsDistance; + + curvedCoords = curvedCoords * (1.0-pow(vec2(1.0-(curvedCoordsDistance/1.4142135623730950488016887242097)),(1.0/(1.0+Distortion*0.2)))); + + curvedCoords = curvedCoords / (1.0-pow(vec2(0.29289321881345247559915563789515),(1.0/(vec2(1.0)+Distortion*0.2)))); + + curvedCoords = curvedCoords * 0.5 + 0.5; + return curvedCoords; +} + +// lottes +// Distortion of scanlines, and end of screen alpha. +vec2 tl_warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY); + + return pos*0.5 + 0.5; +} + +// cgwg's geom +// license: GPLv2 + +const float d = 1.5; +const vec2 sinangle = vec2(1.0); +const vec2 cosangle = vec2(1.0); +const vec2 aspect = vec2(1.0, 0.75); +float R = max(warpX, warpY); +#define FIX(c) max(abs(c), 1e-5); + +float intersect(vec2 xy) +{ + float A = dot(xy,xy) + d*d; + float B = 2.0*(R*(dot(xy,sinangle) - d*cosangle.x*cosangle.y) - d*d); + float C = d*d + 2.0*R*d*cosangle.x*cosangle.y; + + return (-B-sqrt(B*B - 4.0*A*C))/(2.0*A); +} + +vec2 fwtrans(vec2 uv) +{ + float r = FIX(sqrt(dot(uv,uv))); + uv *= sin(r/R)/r; + float x = 1.0-cos(r/R); + float D = d/R + x*cosangle.x*cosangle.y+dot(uv,sinangle); + + return d*(uv*cosangle-x*sinangle)/D; +} + +vec3 maxscale() +{ + vec2 c = bkwtrans(-R * sinangle / (1.0 + R/d*cosangle.x*cosangle.y)); + vec2 a = vec2(0.5,0.5)*aspect; + + vec2 lo = vec2(fwtrans(vec2(-a.x, c.y)).x, + fwtrans(vec2( c.x, -a.y)).y)/aspect; + + vec2 hi = vec2(fwtrans(vec2(+a.x, c.y)).x, + fwtrans(vec2( c.x, +a.y)).y)/aspect; + + return vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y)); +} + +vec2 bkwtrans(vec2 xy) +{ + float c = intersect(xy); + vec2 point = (vec2(c, c)*xy - vec2(-R, -R)*sinangle) / vec2(R, R); + vec2 poc = point/cosangle; + vec2 tang = sinangle/cosangle; + + float A = dot(tang, tang) + 1.0; + float B = -2.0*dot(poc, tang); + float C = dot(poc, poc) - 1.0; + + float a = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A); + vec2 uv = (point - a*sinangle) / cosangle; + float r = FIX(R*acos(a)); + + return uv*r/sin(r/R); +} + +vec2 cgwg_warp(vec2 coord) +{ + vec3 stretch = max_scale(); + coord = (coord - vec2(0.5, 0.5))*aspect*stretch.z + stretch.xy; + + return (bkwtrans(coord) / + vec2(1.0, 1.0)/aspect + vec2(0.5, 0.5)); +} + +float corner(vec2 coord) +{ + coord = (coord - vec2(0.5)) + vec2(0.5, 0.5); + coord = min(coord, vec2(1.0) - coord) * aspect; + vec2 cdist = vec2(cornersize); + coord = (cdist - min(coord, cdist)); + float dist = sqrt(dot(coord, coord)); + + return clamp((cdist.x - dist)*cornersmooth, 0.0, 1.0); +} + +#endif diff --git a/include/img/exp_gamma.h b/include/img/exp_gamma.h new file mode 100644 index 0000000..4998572 --- /dev/null +++ b/include/img/exp_gamma.h @@ -0,0 +1,19 @@ +#ifndef GAMMA +#define GAMMA + +#pragma parameter ia_monitor_gamma "Physical Monitor Gamma" 2.2 0.1 5.0 0.05 +#pragma parameter ia_target_gamma_r "Simulated Gamma R Channel" 2.2 0.1 5.0 0.05 +#pragma parameter ia_target_gamma_g "Simulated Gamma G Channel" 2.2 0.1 5.0 0.05 +#pragma parameter ia_target_gamma_b "Simulated Gamma B Channel" 2.2 0.1 5.0 0.05 + +vec3 gamma_in(vec3 in_col){ + vec3 out_col = pow(in_col, vec3(ia_target_gamma_r, ia_target_gamma_g, ia_target_gamma_b)); + return out_col; +} + +vec3 gamma_out(vec3 in_col){ + vec3 out_col= pow(in_col, 1./vec3(ia_monitor_gamma)); + return out_col; +} + +#endif diff --git a/include/img/film_grain.h b/include/img/film_grain.h new file mode 100644 index 0000000..637f476 --- /dev/null +++ b/include/img/film_grain.h @@ -0,0 +1,27 @@ +#ifndef FILM_GRAIN +#define FILM_GRAIN + +#pragma parameter ia_GRAIN_STR "Grain Strength" 0.0 0.0 72.0 3.0 + +#include "col_tools.h" + +//https://www.shadertoy.com/view/4sXSWs strength= 16.0 +vec3 rgb_grain(vec2 uv, float strength, uint counter){ + float x = ((uv.x + 4.0 ) * (uv.y + 5.0 ) * ((mod(vec2(counter, counter).x, 800.0) + 10.0) * 8.0)); + float y = ((uv.x + 5.0 ) * (uv.y + 6.0 ) * ((mod(vec2(counter, counter).x, 678.0) + 8.0) * 6.0)); + float z = ((uv.x + 6.0 ) * (uv.y + 4.0 ) * ((mod(vec2(counter, counter).x, 498.0) + 6.0) * 10.0)); + float r = (mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005); + float g = (mod((mod(y, 13.0) + 1.0) * (mod(y, 123.0) + 1.0), 0.01)-0.005); + float b = (mod((mod(z, 13.0) + 1.0) * (mod(z, 123.0) + 1.0), 0.01)-0.005); + return vec3(r, g, b) * strength; +} + +vec3 luma_grain(vec3 in_col, vec2 uv, float strength, uint counter){ + float x = (uv.x + 4.0 ) * (uv.y + 4.0 ) * ((mod(vec2(counter, counter).x, 800.0) + 10.0) * 10.0); + x = (mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005) * strength; + vec3 out_col = RGBtoYIQ(in_col); + out_col.r += x; + return YIQtoRGB(out_col); +} + +#endif diff --git a/include/img/gamma_srgb.h b/include/img/gamma_srgb.h new file mode 100644 index 0000000..716c93d --- /dev/null +++ b/include/img/gamma_srgb.h @@ -0,0 +1,19 @@ +#ifndef GAMMA +#define GAMMA + +#pragma parameter gamma_in_lvl "CRT Gamma" 2.4 0.0 3.0 0.05 +#pragma parameter gamma_out_lvl "LCD Gamma" 2.2 0.0 3.0 0.05 + +#include "moncurve.h" + +vec3 gamma_in(vec3 in_col){ + vec3 out_col = moncurve_f_f3(in_col, gamma_in_lvl + 0.15, 0.055); + return out_col; +} + +vec3 gamma_out(vec3 in_col){ + vec3 out_col = moncurve_r_f3(in_col, gamma_out_lvl + 0.20, 0.055); + return out_col; +} + +#endif diff --git a/include/img/gristle_warp.h b/include/img/gristle_warp.h new file mode 100644 index 0000000..a766003 --- /dev/null +++ b/include/img/gristle_warp.h @@ -0,0 +1,23 @@ +#ifndef CURV +#define CURV + +#pragma parameter warpX "Warp X" 0.031 0.0 0.125 0.01 +#pragma parameter warpY "Warp Y" 0.041 0.0 0.125 0.01 +vec2 Distortion = vec2(warpX, warpY) * 15.; + +vec2 warp(vec2 texCoord){ + vec2 Distortion = vec2(warpX, warpY) * 15.; + vec2 curvedCoords = texCoord * 2.0 - 1.0; + float curvedCoordsDistance = sqrt(curvedCoords.x*curvedCoords.x+curvedCoords.y*curvedCoords.y); + + curvedCoords = curvedCoords / curvedCoordsDistance; + + curvedCoords = curvedCoords * (1.0-pow(vec2(1.0-(curvedCoordsDistance/1.4142135623730950488016887242097)),(1.0/(1.0+Distortion*0.2)))); + + curvedCoords = curvedCoords / (1.0-pow(vec2(0.29289321881345247559915563789515),(1.0/(vec2(1.0)+Distortion*0.2)))); + + curvedCoords = curvedCoords * 0.5 + 0.5; + return curvedCoords; +} + +#endif diff --git a/include/img/helper_macros.h b/include/img/helper_macros.h new file mode 100644 index 0000000..c1dcfa2 --- /dev/null +++ b/include/img/helper_macros.h @@ -0,0 +1,71 @@ +#ifndef HELPER_MACROS +#define HELPER_MACROS + +// All of the parameter macros in one place +// replace 'global' with whichever struct you use for parameters + +#define ia_FLIP_HORZ global.ia_FLIP_HORZ +#define ia_FLIP_VERT global.ia_FLIP_VERT +#define ia_overscan_percent_x global.ia_overscan_percent_x +#define ia_overscan_percent_y global.ia_overscan_percent_y +#define ia_ZOOM global.ia_ZOOM +#define ia_XPOS global.ia_XPOS +#define ia_YPOS global.ia_YPOS +#define ia_GRAIN_STR global.ia_GRAIN_STR +#define ia_SHARPEN global.ia_SHARPEN +#define ia_saturation global.ia_saturation +#define ia_luminance global.ia_luminance +#define ia_contrast global.ia_contrast +#define ia_bright_boost global.ia_bright_boost +#define ia_black_level global.ia_black_level +#define ia_target_gamma_r global.ia_target_gamma_r +#define ia_target_gamma_g global.ia_target_gamma_g +#define ia_target_gamma_b global.ia_target_gamma_b +#define ia_monitor_gamma global.ia_monitor_gamma +#define ia_R global.ia_R +#define ia_G global.ia_G +#define ia_B global.ia_B +#define ia_TOPMASK global.ia_TOPMASK +#define ia_BOTMASK global.ia_BOTMASK +#define ia_LMASK global.ia_LMASK +#define ia_RMASK global.ia_RMASK +#define ia_rr global.ia_rr +#define ia_gg global.ia_gg +#define ia_bb global.ia_bb +#define ia_rg global.ia_rg +#define ia_rb global.ia_rb +#define ia_gr global.ia_gr +#define ia_gb global.ia_gb +#define ia_br global.ia_br +#define ia_bg global.ia_bg +#define temperature global.temperature +#define luma_preserve global.luma_preserve +#define wp_red global.wp_red +#define wp_green global.wp_green +#define wp_blue global.wp_blue +#define integer_scale global.integer_scale +#define overscale global.overscale +#define ar_num global.ar_num +#define ar_den global.ar_den +#define g_hpfix global.g_hpfix +#define g_cntrst global.g_cntrst +#define g_mid global.g_mid +#define mask_strength global.mask_strength +#define mask_picker global.mask_picker +#define LUT_Size1 global.LUT_Size1 +#define LUT_Size2 global.LUT_Size2 +#define g_vignette global.g_vignette +#define g_vstr global.g_vstr +#define g_vpower global.g_vpower +#define gamma_in_lvl global.gamma_in_lvl +#define gamma_out_lvl global.gamma_out_lvl +#define warpX global.warpX +#define warpY global.warpY +#define cornersize global.cornersize +#define cornersmooth global.cornersmooth +#define Radius global.Radius +#define Distance global.Distance +#define x_tilt global.x_tilt +#define y_tilt global.y_tilt + +#endif diff --git a/include/img/image_flip.h b/include/img/image_flip.h new file mode 100644 index 0000000..d09e573 --- /dev/null +++ b/include/img/image_flip.h @@ -0,0 +1,16 @@ +#ifndef IMAGE_FLIP +#define IMAGE_FLIP + +// wraps the Position in gl_Position calculation + +#pragma parameter ia_FLIP_HORZ "Flip Horiz Axis" 0.0 0.0 1.0 1.0 +#pragma parameter ia_FLIP_VERT "Flip Vert Axis" 0.0 0.0 1.0 1.0 + +vec4 flip_pos(vec4 in_pos){ + vec4 out_pos = in_pos; + out_pos.x = (ia_FLIP_HORZ < 0.5) ? out_pos.x : 1.0 - out_pos.x; + out_pos.y = (ia_FLIP_VERT < 0.5) ? out_pos.y : 1.0 - out_pos.y; + return out_pos; +} + +#endif diff --git a/include/img/int_ar.h b/include/img/int_ar.h new file mode 100644 index 0000000..6be0570 --- /dev/null +++ b/include/img/int_ar.h @@ -0,0 +1,28 @@ +#ifndef INT_AR +#define INT_AR + +// Forces integer scaling and arbitrary aspect ratio +// by hunterk +// license: public domain + +// Apply in the vertex to the texCoord + +#pragma parameter ar_num "Aspect Ratio Numerator" 64.0 1.0 256. 1.0 +#pragma parameter ar_den "Aspect Ratio Denominator" 49.0 1.0 256. 1.0 +#pragma parameter integer_scale "Force Integer Scaling" 0.0 0.0 1.0 1.0 +#pragma parameter overscale "Integer Overscale" 0.0 0.0 1.0 1.0 + +const vec2 middle = vec2(0.4999999, 0.4999999); + +vec2 int_ar(vec2 coord, vec4 tex_size, vec4 out_size){ + vec2 corrected_size = tex_size.xy * vec2(ar_num / ar_den, 1.0) + * vec2(tex_size.y / tex_size.x, 1.0); + float full_scale = (integer_scale > 0.5) ? floor(out_size.y / + tex_size.y) + overscale : out_size.y / tex_size.y; + vec2 scale = (out_size.xy / corrected_size) / full_scale; + vec2 diff = coord.xy - middle; + vec2 ar_coord = middle + diff * scale; + return ar_coord; +} + +#endif diff --git a/include/img/lottes_warp.h b/include/img/lottes_warp.h new file mode 100644 index 0000000..d348a02 --- /dev/null +++ b/include/img/lottes_warp.h @@ -0,0 +1,16 @@ +#ifndef CURV +#define CURV + +#pragma parameter warpX "Warp X" 0.031 0.0 0.125 0.01 +#pragma parameter warpY "Warp Y" 0.041 0.0 0.125 0.01 + +// Distortion of scanlines, and end of screen alpha. +vec2 warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY); + + return pos*0.5 + 0.5; +} + +#endif diff --git a/include/img/lum_chrom.h b/include/img/lum_chrom.h new file mode 100644 index 0000000..0f64fab --- /dev/null +++ b/include/img/lum_chrom.h @@ -0,0 +1,18 @@ +#ifndef SAT_LUM +#define SAT_LUM + +#pragma parameter ia_saturation "Chrominance" 1.0 0.01 2.0 0.01 +#pragma parameter ia_luminance "Luminance" 1.0 0.0 2.0 0.01 + +#include "col_tools.h" + +// Note: This saturation should be similar to broadcast television. +// 0% chrome == pure luma. + +vec3 sat_lum(vec3 in_col){ + vec3 out_col = RGBtoYIQ(in_col); + out_col *= vec3(ia_luminance, ia_saturation, ia_saturation); + return YIQtoRGB(out_col); +} + +#endif diff --git a/include/img/lut1.h b/include/img/lut1.h new file mode 100644 index 0000000..ed57bd4 --- /dev/null +++ b/include/img/lut1.h @@ -0,0 +1,29 @@ +#ifndef LUT +#define LUT + +// only #include in the fragment stage +#pragma parameter LUT_Size1 "LUT Size 1" 16.0 1.0 64.0 1.0 + +layout(set = 0, binding = 3) uniform sampler2D SamplerLUT1; + +// This shouldn't be necessary but it seems some undefined values can +// creep in and each GPU vendor handles that differently. This keeps +// all values within a safe range +vec3 mixfix(vec3 a, vec3 b, float c) +{ + return (a.z < 1.0) ? mix(a, b, c) : a; +} + +vec3 lut1(vec3 in_col) +{ + float red = ( in_col.r * (LUT_Size1 - 1.0) + 0.4999 ) / (LUT_Size1 * LUT_Size1); + float green = ( in_col.g * (LUT_Size1 - 1.0) + 0.4999 ) / LUT_Size1; + float blue1 = (floor( in_col.b * (LUT_Size1 - 1.0) ) / LUT_Size1) + red; + float blue2 = (ceil( in_col.b * (LUT_Size1 - 1.0) ) / LUT_Size1) + red; + float mixer = clamp(max((in_col.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0); + vec3 color1 = texture( SamplerLUT1, vec2( blue1, green )).rgb; + vec3 color2 = texture( SamplerLUT1, vec2( blue2, green )).rgb; + return mixfix(color1, color2, mixer); +} + +#endif diff --git a/include/img/lut2.h b/include/img/lut2.h new file mode 100644 index 0000000..8435e3b --- /dev/null +++ b/include/img/lut2.h @@ -0,0 +1,43 @@ +#ifndef LUT +#define LUT + +// only #include in the fragment stage +#pragma parameter LUT_Size1 "LUT Size 1" 16.0 1.0 64.0 1.0 +#pragma parameter LUT_Size2 "LUT Size 2" 16.0 1.0 64.0 1.0 + +layout(set = 0, binding = 3) uniform sampler2D SamplerLUT1; +layout(set = 0, binding = 4) uniform sampler2D SamplerLUT2; + +// This shouldn't be necessary but it seems some undefined values can +// creep in and each GPU vendor handles that differently. This keeps +// all values within a safe range +vec3 mixfix(vec3 a, vec3 b, float c) +{ + return (a.z < 1.0) ? mix(a, b, c) : a; +} + +vec3 lut1(vec3 in_col) +{ + float red = ( in_col.r * (LUT_Size1 - 1.0) + 0.4999 ) / (LUT_Size1 * LUT_Size1); + float green = ( in_col.g * (LUT_Size1 - 1.0) + 0.4999 ) / LUT_Size1; + float blue1 = (floor( in_col.b * (LUT_Size1 - 1.0) ) / LUT_Size1) + red; + float blue2 = (ceil( in_col.b * (LUT_Size1 - 1.0) ) / LUT_Size1) + red; + float mixer = clamp(max((in_col.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0); + vec3 color1 = texture( SamplerLUT1, vec2( blue1, green )).rgb; + vec3 color2 = texture( SamplerLUT1, vec2( blue2, green )).rgb; + return mixfix(color1, color2, mixer); +} + +vec3 lut2(vec3 in_col) +{ + float red = ( in_col.r * (LUT_Size2 - 1.0) + 0.4999 ) / (LUT_Size2 * LUT_Size2); + float green = ( in_col.g * (LUT_Size2 - 1.0) + 0.4999 ) / LUT_Size2; + float blue1 = (floor( in_col.b * (LUT_Size2 - 1.0) ) / LUT_Size2) + red; + float blue2 = (ceil( in_col.b * (LUT_Size2 - 1.0) ) / LUT_Size2) + red; + float mixer = clamp(max((in_col.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0); + vec3 color1 = texture( SamplerLUT2, vec2( blue1, green )).rgb; + vec3 color2 = texture( SamplerLUT2, vec2( blue2, green )).rgb; + return mixfix(color1, color2, mixer); +} + +#endif diff --git a/include/img/moncurve.h b/include/img/moncurve.h new file mode 100644 index 0000000..46347d6 --- /dev/null +++ b/include/img/moncurve.h @@ -0,0 +1,45 @@ +#ifndef MONCURVE +#define MONCURVE + +float moncurve_f( float color, float gamma, float offs) +{ + // Forward monitor curve + color = clamp(color, 0.0, 1.0); + float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma); + float xb = offs / ( gamma - 1.0); + + color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs; + return color; +} + + +vec3 moncurve_f_f3( vec3 color, float gamma, float offs) +{ + color.r = moncurve_f( color.r, gamma, offs); + color.g = moncurve_f( color.g, gamma, offs); + color.b = moncurve_f( color.b, gamma, offs); + return color.rgb; +} + + +float moncurve_r( float color, float gamma, float offs) +{ + // Reverse monitor curve + color = clamp(color, 0.0, 1.0); + float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma); + float rs = pow( ( gamma - 1.0) / offs, gamma - 1.0) * pow( ( 1.0 + offs) / gamma, gamma); + + color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs; + return color; +} + + +vec3 moncurve_r_f3( vec3 color, float gamma, float offs) +{ + color.r = moncurve_r( color.r, gamma, offs); + color.g = moncurve_r( color.g, gamma, offs); + color.b = moncurve_r( color.b, gamma, offs); + return color.rgb; +} + +#endif diff --git a/include/img/param_floats.h b/include/img/param_floats.h new file mode 100644 index 0000000..d22c9a9 --- /dev/null +++ b/include/img/param_floats.h @@ -0,0 +1,67 @@ +#ifndef PARAM_FLOATS +#define PARAM_FLOATS + +// The parameters that go into your struct +// Collected here for tidiness + float ia_FLIP_HORZ; + float ia_FLIP_VERT; + float ia_overscan_percent_x; + float ia_overscan_percent_y; + float ia_ZOOM; + float ia_XPOS; + float ia_YPOS; + float ia_GRAIN_STR; + float ia_SHARPEN; + float ia_saturation; + float ia_luminance; + float ia_contrast; + float ia_bright_boost; + float ia_black_level; + float ia_target_gamma_r; + float ia_target_gamma_g; + float ia_target_gamma_b; + float ia_monitor_gamma; + float ia_TOPMASK; + float ia_BOTMASK; + float ia_LMASK; + float ia_RMASK; + float ia_rr; + float ia_gg; + float ia_bb; + float ia_rg; + float ia_rb; + float ia_gr; + float ia_gb; + float ia_br; + float ia_bg; + float temperature; + float luma_preserve; + float wp_red; + float wp_green; + float wp_blue; + float ar_num; + float ar_den; + float integer_scale; + float overscale; + float g_hpfix; + float g_cntrst; + float g_mid; + float mask_strength; + float mask_picker; + float LUT_Size1; + float LUT_Size2; + float g_vignette; + float g_vstr; + float g_vpower; + float gamma_in_lvl; + float gamma_out_lvl; + float warpX; + float warpY; + float cornersize; + float cornersmooth; + float Radius; + float Distance; + float x_tilt; + float y_tilt; + +#endif diff --git a/include/img/sat_lum.h b/include/img/sat_lum.h new file mode 100644 index 0000000..9c46b18 --- /dev/null +++ b/include/img/sat_lum.h @@ -0,0 +1,21 @@ +#ifndef SAT_LUM +#define SAT_LUM + +#pragma parameter ia_saturation "Saturation" 1.0 0.0 5.0 0.1 +#pragma parameter ia_luminance "Value" 1.0 0.0 2.0 0.1 + +#include "col_tools.h" + +// Note: saturation 0 does not mean grayscale in this case. +// It's purely a measure of the saturation of the colors. +// That is, pure r, g and b each look white. + +vec3 sat_lum(vec3 in_color){ + vec3 out_color = RGBtoHSV(in_color); + out_color *= vec3(1.0, ia_saturation, ia_luminance); + out_color = HSVtoRGB(out_color); + out_color = clamp(out_color, 0.0, 1.0); + return out_color; +} + +#endif diff --git a/include/img/sharpening.h b/include/img/sharpening.h new file mode 100644 index 0000000..f2e89dc --- /dev/null +++ b/include/img/sharpening.h @@ -0,0 +1,24 @@ +#ifndef SHARP_COORD +#define SHARP_COORD + +// wrap texture coordinate when sampling + +#pragma parameter ia_SHARPEN "Sharpen" 0.0 0.0 1.0 0.05 + +const vec2 offset = vec2(0.5, 0.5); + +// based on "Improved texture interpolation" by Iñigo Quílez +// Original description: http://www.iquilezles.org/www/articles/texture/texture.htm +vec2 sharp(vec2 in_coord, vec4 tex_size){ + vec2 p = in_coord.xy; + p = p * tex_size.xy + offset; + vec2 i = floor(p); + vec2 f = p - i; + f = f * f * f * (f * (f * 6.0 - vec2(15.0, 15.0)) + vec2(10.0, 10.0)); + p = i + f; + p = (p - offset) * tex_size.zw; + p = mix(in_coord, p, ia_SHARPEN); + return p; +} + +#endif diff --git a/include/img/sigmoidal_con.h b/include/img/sigmoidal_con.h new file mode 100644 index 0000000..e143769 --- /dev/null +++ b/include/img/sigmoidal_con.h @@ -0,0 +1,54 @@ +#ifndef SIG_CON +#define SIG_CON + +// borrowed from dogway's grade shader + +#pragma parameter g_cntrst "Contrast" 0.0 -1.0 1.0 0.05 +#pragma parameter g_mid "Contrast Pivot" 0.5 0.0 1.0 0.01 +#pragma parameter g_hpfix "Contrast Hotspot Fix" 0.0 0.0 1.0 1.00 + +#include "col_tools.h" +#include "moncurve.h" + +// Performs better in gamma encoded space +float contrast_sigmoid(float color, float cont, float pivot){ + + cont = pow(cont + 1., 3.); + + float knee = 1. / (1. + exp(cont * pivot)); + float shldr = 1. / (1. + exp(cont * (pivot - 1.))); + + color = (1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee); + + return color; +} + + +// Performs better in gamma encoded space +float contrast_sigmoid_inv(float color, float cont, float pivot){ + + cont = pow(cont - 1., 3.); + + float knee = 1. / (1. + exp (cont * pivot)); + float shldr = 1. / (1. + exp (cont * (pivot - 1.))); + + color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont; + + return color; +} + +// Saturation agnostic sigmoidal contrast +vec3 cntrst(vec3 in_col){ + vec3 Yxy = XYZtoYxy(sRGB_to_XYZ(in_col)); + float toGamma = clamp(moncurve_r(Yxy.r, 2.40, 0.055), 0.0, 1.0); + toGamma = (g_hpfix == 0.0) ? toGamma : ((Yxy.r > 0.5) ? + contrast_sigmoid_inv(toGamma, 2.3, 0.5) : toGamma); + float sigmoid = (g_cntrst > 0.0) ? contrast_sigmoid(toGamma, g_cntrst, g_mid) : contrast_sigmoid_inv(toGamma, g_cntrst, g_mid); + vec3 out_col = vec3(moncurve_f(sigmoid, 2.40, 0.055), Yxy.g, Yxy.b); + vec3 XYZsrgb = clamp(XYZ_to_sRGB(YxytoXYZ(out_col)), 0.0, 1.0); + out_col = (g_cntrst == 0.0) && (g_hpfix == 0.0) ? in_col : + ((g_cntrst != 0.0) || (g_hpfix != 0.0) ? XYZsrgb : in_col); + return out_col; +} + +#endif diff --git a/include/img/stretch_zoom_pan.h b/include/img/stretch_zoom_pan.h new file mode 100644 index 0000000..0be4641 --- /dev/null +++ b/include/img/stretch_zoom_pan.h @@ -0,0 +1,23 @@ +#ifndef CROP_ZOOM_PAN +#define CROP_ZOOM_PAN + +// wraps the standard TexCoord + +#pragma parameter ia_overscan_percent_x "Stretch Width" 0.0 -25.0 25.0 1.0 +#pragma parameter ia_overscan_percent_y "Stretch Height" 0.0 -25.0 25.0 1.0 +#pragma parameter ia_ZOOM "Zoom In/Out" 1.0 0.0 4.0 0.01 +#pragma parameter ia_XPOS "Pan X" 0.0 -2.0 2.0 0.005 +#pragma parameter ia_YPOS "Pan Y" 0.0 -2.0 2.0 0.005 + +const vec2 shift = vec2(0.5); + +vec2 crop_zoom_pan(vec2 in_coord){ + vec2 out_coord = in_coord - shift; + out_coord /= ia_ZOOM; + out_coord *= vec2(1.0 - ia_overscan_percent_x / 100.0, 1.0 - ia_overscan_percent_y / 100.0); + out_coord += shift; + out_coord += vec2(ia_XPOS, ia_YPOS); + return out_coord; +} + +#endif diff --git a/include/img/subpx_masks.h b/include/img/subpx_masks.h new file mode 100644 index 0000000..3a8a248 --- /dev/null +++ b/include/img/subpx_masks.h @@ -0,0 +1,11 @@ +#ifndef SUBPX_MASKS +#define SUBPX_MASKS + +#pragma parameter mask_strength "Phosphor Mask Strength" 0.5 0.0 1.0 0.01 +#pragma parameter mask_picker "Phosphor Mask Layout" 0.0 0.0 19.0 1.0 + +int mask = int(mask_picker); + +#include "../subpixel_masks.h" + +#endif diff --git a/include/img/vignette.h b/include/img/vignette.h new file mode 100644 index 0000000..afff7cb --- /dev/null +++ b/include/img/vignette.h @@ -0,0 +1,17 @@ +#ifndef VIG +#define VIG + +#pragma parameter g_vignette "Vignette Toggle" 1.0 0.0 1.0 1.0 +#pragma parameter g_vstr "Vignette Strength" 40.0 0.0 50.0 1.0 +#pragma parameter g_vpower "Vignette Power" 0.20 0.0 0.5 0.01 + +vec3 vignette(vec3 in_col, vec2 in_coord){ + vec2 coord = in_coord * (1.0 - in_coord.xy); + float vig = coord.x * coord.y * g_vstr; + vig = min(pow(vig, g_vpower), 1.0); + vec3 out_col = in_col; + out_col *= (g_vignette == 1.0) ? vig : 1.0; + return out_col; +} + +#endif diff --git a/include/img/white_point.h b/include/img/white_point.h new file mode 100644 index 0000000..4d38f9b --- /dev/null +++ b/include/img/white_point.h @@ -0,0 +1,60 @@ +#ifndef WHITE_POINT +#define WHITE_POINT + +// White Point Mapping +// ported by Dogway +// +// From the first comment post (sRGB primaries and linear light compensated) +// http://www.zombieprototypes.com/?p=210#comment-4695029660 +// Based on the Neil Bartlett's blog update +// http://www.zombieprototypes.com/?p=210 +// Inspired itself by Tanner Helland's work +// http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code + +#include "col_tools.h" + +#pragma parameter temperature "White Point" 6500.0 1031.0 12047.0 72.0 +#pragma parameter luma_preserve "Preserve Luminance" 1.0 0.0 1.0 1.0 +#pragma parameter wp_red "Red Shift" 0.0 -1.0 1.0 0.01 +#pragma parameter wp_green "Green Shift" 0.0 -1.0 1.0 0.01 +#pragma parameter wp_blue "Blue Shift" 0.0 -1.0 1.0 0.01 + +vec3 wp_adjust(vec3 color){ + + float temp = temperature / 100.; + float k = temperature / 10000.; + float lk = log(k); + + vec3 wp = vec3(1.); + + // calculate RED + wp.r = (temp <= 65.) ? 1. : 0.32068362618584273 + (0.19668730877673762 * pow(k - 0.21298613432655075, - 1.5139012907556737)) + (- 0.013883432789258415 * lk); + + // calculate GREEN + float mg = 1.226916242502167 + (- 1.3109482654223614 * pow(k - 0.44267061967913873, 3.) * exp(- 5.089297600846147 * (k - 0.44267061967913873))) + (0.6453936305542096 * lk); + float pg = 0.4860175851734596 + (0.1802139719519286 * pow(k - 0.14573069517701578, - 1.397716496795082)) + (- 0.00803698899233844 * lk); + wp.g = (temp <= 65.5) ? ((temp <= 8.) ? 0. : mg) : pg; + + // calculate BLUE + wp.b = (temp <= 19.) ? 0. : (temp >= 66.) ? 1. : 1.677499032830161 + (- 0.02313594016938082 * pow(k - 1.1367244820333684, 3.) * exp(- 4.221279555918655 * (k - 1.1367244820333684))) + (1.6550275798913296 * lk); + + // clamp + wp.rgb = clamp(wp.rgb, vec3(0.), vec3(1.)); + + // R/G/B independent manual White Point adjustment + wp.rgb += vec3(wp_red, wp_green, wp_blue); + + // Linear color input + return color * wp; +} + +vec3 white_point(vec3 in_col){ + vec3 original = sRGB_to_linear(in_col, 2.20); + vec3 adjusted = wp_adjust(original); + vec3 base_luma = XYZtoYxy(sRGB_to_XYZ(original)); + vec3 adjusted_luma = XYZtoYxy(sRGB_to_XYZ(adjusted)); + adjusted = (luma_preserve > 0.5) ? adjusted_luma + (vec3(base_luma.r,0.,0.) - vec3(adjusted_luma.r,0.,0.)) : adjusted_luma; + return linear_to_sRGB(XYZ_to_sRGB(YxytoXYZ(adjusted)), 2.20); +} + +#endif diff --git a/misc/colorspace-tools.h b/misc/colorspace-tools.h index 7c7ad1e..9c6a2c9 100644 --- a/misc/colorspace-tools.h +++ b/misc/colorspace-tools.h @@ -64,6 +64,32 @@ vec3 srgb_linear(vec3 x) { #endif } +vec3 linear_to_sRGB(vec3 color, float gamma){ + + color = clamp(color, 0.0, 1.0); + color.r = (color.r <= 0.00313066844250063) ? + color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055; + color.g = (color.g <= 0.00313066844250063) ? + color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055; + color.b = (color.b <= 0.00313066844250063) ? + color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055; + + return color.rgb; +} + +vec3 sRGB_to_linear(vec3 color, float gamma){ + + color = clamp(color, 0.0, 1.0); + color.r = (color.r <= 0.04045) ? + color.r / 12.92 : pow((color.r + 0.055) / (1.055), gamma); + color.g = (color.g <= 0.04045) ? + color.g / 12.92 : pow((color.g + 0.055) / (1.055), gamma); + color.b = (color.b <= 0.04045) ? + color.b / 12.92 : pow((color.b + 0.055) / (1.055), gamma); + + return color.rgb; +} + //Conversion matrices vec3 RGBtoXYZ(vec3 RGB) { diff --git a/misc/img_mod.slang b/misc/img_mod.slang new file mode 100644 index 0000000..afd5036 --- /dev/null +++ b/misc/img_mod.slang @@ -0,0 +1,185 @@ +#version 450 + +// Modular Image Adjustment +// Author: hunterk +// License: Public domain + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + uint FrameCount; + vec4 OutputSize; +} registers; + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +#include "../include/img/param_floats.h" +} global; + +#include "../include/img/helper_macros.h" + +/////////////////////////////// INCLUDES //////////////////////////////// +// comment the #include and corresponding line to remove functionality // +///////////////////////////////////////////////////////////////////////// + +// Flip image vertically or horizontally +#include "../include/img/image_flip.h" + +// Stretching, Zooming, Panning +#include "../include/img/stretch_zoom_pan.h" + +// Film grain effect +#include "../include/img/film_grain.h" + +// Sharp, antialiased pixels; use with linear filtering +#include "../include/img/sharpening.h" + +// Saturation and Luminance +//#include "../include/img/sat_lum.h" +#include "../include/img/lum_chrom.h" + +// Gamma correction +// exp_gamma is basic pow function +//#include "../include/img/exp_gamma.h" +#include "../include/img/gamma_srgb.h" + +// Mask edges to hide unsightly garbage +#include "../include/img/border_mask.h" + +// Change the whitepoint to warmer/cooler +#include "../include/img/white_point.h" + +// Add a phosphor mask effect onto the image +#include "../include/img/subpx_masks.h" + +// Force integer scaling and custom aspect ratio +//#include "../include/img/int_ar.h" + +// Vignette; Darkens image around edges +//#include "../include/img/vignette.h" + + +// Black level +// uncomment only one of the next 2 lines to set black level method +//#include "../include/img/black_lvl.h" +#include "../include/img/black_lvl_dogway.h" + +// Brightness and Contrast control +// uncomment only one of the next 2 lines to set contract complexity; +// sigmoidal_con is advanced, bright_con is basic +#include "../include/img/sigmoidal_con.h" +//#include "../include/img/bright_con.h" + +// Adjust color balance and tint +// uncomment only one of the next 2 lines to set color channel complexity; +// color mangler is advanced, channel mixer is basic +//#include "../include/img/col_mangler.h" +#include "../include/img/channel_mix.h" + +// 2D screen curvature +//#include "../include/img/gristle_warp.h" +//#include "../include/img/lottes_warp.h" +#include "../include/img/cgwg_warp.h" + +// Rounded corners +#include "../include/img/corner.h" + +////////////////////////////// END INCLUDES ////////////////////////////// + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + vec4 pos = Position; + +// apply axis flip + pos = flip_pos(pos); + + gl_Position = global.MVP * pos; + + vec2 coord = TexCoord.st; + +// apply crop/zoom/pan + coord = crop_zoom_pan(TexCoord); + +// apply integer scaling and aspect ratio +// coord = int_ar(coord, registers.SourceSize, registers.OutputSize); + + vTexCoord = coord; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +//////////////////////////////// LUTS /////////////////////////////////// +// Use either 1 or 2 color-grading LUTs +// uncomment only one of the next 2 lines +//#include "../include/img/lut1.h" +//#include "../include/img/lut2.h" +////////////////////////////// END LUTS ///////////////////////////////// + +void main() +{ +// declare texture coordinates + vec2 coord = vTexCoord.xy; + +// apply sharpening to coords + coord = sharp(vTexCoord, registers.SourceSize); + +// apply screen curvature + coord = warp(coord); + +// sample the texture + vec3 res = texture(Source, coord).rgb; + +// apply grain (expects to run in gamma space) + res = luma_grain(res, vTexCoord.xy, ia_GRAIN_STR, registers.FrameCount); + +// saturation and luminance (expects to run in gamma space) + res = sat_lum(res); + +// contrast + res = cntrst(res); + +// apply first gamma transform (linearize) +// (whether LUT or gamma should come first depends on LUT) + res = gamma_in(res); + +// apply LUT1 +// res = lut1(res); + +// apply white point adjustment + res = white_point(res); + +// black level + res = black_level(res); + +// channel mix + res = channel_mix(res); + +// overscan mask + res = border_mask(res, coord.xy); + +// apply LUT2 (whether LUT or gamma should come first depends on LUT) +// res = lut2(res); + +// apply gamma curve + res = gamma_out(res); + +// apply mask effect + res *= mask_weights(gl_FragCoord.xy, mask_strength, mask); + +// apply vignette effect +// res = vignette(res, vTexCoord.xy); + +// apply rounded corners + res *= corner(coord); + + FragColor = vec4(res, 1.0); +} diff --git a/misc/img_mod.slangp b/misc/img_mod.slangp new file mode 100644 index 0000000..07621d9 --- /dev/null +++ b/misc/img_mod.slangp @@ -0,0 +1,7 @@ +shaders = 1 + +shader0 = img_mod.slang + +textures = "SamplerLUT1;SamplerLUT2" +SamplerLUT1 = ../reshade/shaders/LUT/16.png +SamplerLUT2 = ../reshade/shaders/LUT/16.png