Skip to content

Commit

Permalink
1.2 Update
Browse files Browse the repository at this point in the history
The option to reduce brightness and saturation has been added. Additionally a diagonal dither is now available too.
  • Loading branch information
Immorpher committed Jun 8, 2024
1 parent db8b365 commit 8fa4de4
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 64 deletions.
10 changes: 5 additions & 5 deletions FTEQW (OpenGL)/README.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
About HSV Dither 1.1
About HSV Dither 1.2
----------------------------------------------
HSV Dither is a color boosting, banding, and dithering shader. It operates on the color and brightness channels independently and non-linearly.

Expand All @@ -7,13 +7,13 @@ Installation and Use
----------------------------------------------
To install this shader, move the "HSVDither.pk3" file into the "id1" directory within the FTEQW directory. To use this shader, either add "r_postprocshader hsvdither" text to your fte.cfg, autoexec.cfg file, or when the game is loaded open the console with the "'" key and type the command in. This only works with OpenGL rendering with FTEQW. Once the shader is loaded in FTEQW you can use these console variables to cusomize the shader:

r_hsvd_brightness is a non-linear brightness boost by boosting the V value of HSV.
r_hsvd_saturation is a non-linear saturation boost by boosting the S value of HSV.
r_hsvd_brightness is a brightness adjustment via the V value of HSV. A value of one is no change, greater than one increases brightness, and less than one decreases brightness.
r_hsvd_saturation is a saturation adjustment via the S value of HSV. A value of one is no change, greater than one increases saturation, and less than one decreases saturation.
r_hsvd_curve is the amount to non-linearly skew brightness banding. Higher numbers have smoother darks and band brights more, which is good for dark games.
r_hsvd_blevels is the brightness levels plus 1 (black). The lower the number, the more more bands and less brightness levels.
r_hsvd_bdither is the type of brightness dither to use: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
r_hsvd_bdither is the type of brightness dither to use: 0 for bayer 2x2, 1 for bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
r_hsvd_clevels is the number of color levels. The lower the number, the more more bands and less colors used.
r_hsvd_cdither is the type of color dither to use: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
r_hsvd_cdither is the type of color dither to use: 0 for bayer 2x2, 1 for bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
r_hsvd_scale is the pixel size of the dither. This can be done in combination with an in-engine pixel size setting.


Expand Down
39 changes: 29 additions & 10 deletions FTEQW (OpenGL)/glsl/hsvdither.glsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ---------------------------------------------------------------------
// About HSV Dither 1.1
// About HSV Dither 1.2

// HSV Dither is a color boosting, banding and dithering shader. It operates on the color and brightness channels independently and non-linearly.
// See user defined values section to customize this shader and learn more about its capabilities. The effects are enhanced if you pair this with increased pixel sizes.
Expand All @@ -15,13 +15,13 @@
// ---------------------------------------------------------------------
// User defined values

!!cvardf r_hsvd_brightness=1 // Non-linear brightness boost by boosting the V value of HSV.
!!cvardf r_hsvd_saturation=1 // Non-linear saturation boost by boosting the S value of HSV.
!!cvardf r_hsvd_brightness=2 // Brightness adjustment via the V value of HSV. A value of one is no change, greater than one increases brightness, and less than one decreases brightness.
!!cvardf r_hsvd_saturation=2 // Saturation adjustment via the S value of HSV. A value of one is no change, greater than one increases saturation, and less than one decreases saturation.
!!cvardf r_hsvd_curve=2 // Amount to non-linearly skew brightness banding. Higher numbers have smoother darks and band brights more, which is good for dark games.
!!cvardf r_hsvd_blevels=31 // Brightness levels plus 1 (black). The lower the number, the more more bands and less brightness levels.
!!cvardf r_hsvd_bdither=3 // Brightness dither: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
!!cvardf r_hsvd_clevels=15 // Color levels plus 1. The lower the number, the more more bands and less colors used.
!!cvardf r_hsvd_cdither=4 // Color dither: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
!!cvardf r_hsvd_blevels=23 // Brightness levels plus 1 (black). The lower the number, the more more bands and less brightness levels.
!!cvardf r_hsvd_bdither=4 // Brightness dither: 0 for bayer 2x2, 1 for bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
!!cvardf r_hsvd_clevels=23 // Color levels plus 1. The lower the number, the more more bands and less colors used.
!!cvardf r_hsvd_cdither=3 // Color dither: 0 for bayer 2x2, 1 for bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
!!cvardf r_hsvd_scale=2 // Pixel size of the dither. This can be done in combination with an in-engine pixel size setting.


Expand Down Expand Up @@ -176,6 +176,13 @@ float ilgnoise(vec2 position) {
return fract(52.9829189*dot(wavenum,position)); // return the limit
}

// Diagonal dither adapted from ILG Noise
float diagonal(vec2 position) {
vec2 wavenum = vec2(0.2501,-0.1999); // screen position noise

return 2*abs(fract(dot(wavenum,position))-0.5); // return the limit
}

// Static noise based dither roughly learned from: https://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner
float staticnoise(vec2 position){
vec2 wavenum = vec2(78.233,12.9898)+ilgnoise(position); // screen position noise
Expand Down Expand Up @@ -207,7 +214,17 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function
bvec3 compare = bvec3(0,0,0); // boolean vector for comparison of dither limit vector

// saturation / brightness boost
c.yz = atan(c.yz*vec2(r_hsvd_saturation,r_hsvd_brightness))/atan(vec2(r_hsvd_saturation,r_hsvd_brightness)); // non-linear scale and normalize back to 1
if (r_hsvd_saturation > 1) { // saturate
c.y = atan(c.y*(r_hsvd_saturation-1))/atan(r_hsvd_saturation-1); // non-linear scale and normalize back to 1
} else { // desaturate
c.y *= r_hsvd_saturation;
}

if (r_hsvd_brightness > 1) { // brighten
c.z = atan(c.z*(r_hsvd_brightness-1))/atan(r_hsvd_brightness-1); // non-linear scale and normalize back to 1
} else { // darken
c.z *= r_hsvd_brightness;
}

// apply non-linear brightness banding
c.z = atan(c.z*r_hsvd_curve)/atan(r_hsvd_curve); // non-linear scale the colors before banding
Expand All @@ -232,7 +249,8 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function
case 8: ditherlimit.x = ilgnoise(position); break; // ILG Noise Dither
case 9: ditherlimit.x = tate(position); break; // Tate Dither
case 10: ditherlimit.x = zigzag(position); break; // ZigZag Dither
case 11: ditherlimit.x = 0.5; break; // None
case 11: ditherlimit.x = diagonal(position); break; // Diagonal Dither
case 12: ditherlimit.x = 0.5; break; // None
}

ditherlimit.y = ditherlimit.x; // Hue and saturation have same ditherlimit
Expand All @@ -250,7 +268,8 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function
case 8: ditherlimit.z = ilgnoise(position); break; // ILG Noise Dither
case 9: ditherlimit.z = tate(position); break; // Tate Dither
case 10: ditherlimit.z = zigzag(position); break; // ZigZag Dither
case 11: ditherlimit.z = 0.5; break; // None
case 11: ditherlimit.z = diagonal(position); break; // Diagonal Dither
case 12: ditherlimit.z = 0.5; break; // None
}

// determine which color values to quantize up for dithering
Expand Down
10 changes: 5 additions & 5 deletions GZDoom/README.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
About HSV Dither 1.1
About HSV Dither 1.2
----------------------------------------------
HSV Dither is a color boosting, banding, and dithering shader. It operates on the color and brightness channels independently and non-linearly.

Expand All @@ -7,13 +7,13 @@ Installation and Use
----------------------------------------------
To use the shader you can load it like any other WAD into GZDoom, where you can drag and drop "HSVDither.pk3" onto the program, or use a launcher like ZDL. If you click on "Full options menu" in the GZDoom options menu, you will find these specific "Bandither" options

"Brightness Boost" is a non-linear brightness boost by boosting the V value of HSV.
"Saturation Boost" is a non-linear saturation boost by boosting the S value of HSV.
"Brightness" is a brightness adjustment via the V value of HSV. A value of one is no change, greater than one increases brightness, and less than one decreases brightness.
"Saturation" is a saturation adjustment via the S value of HSV. A value of one is no change, greater than one increases saturation, and less than one decreases saturation.
"Banding Curve" is the ammount to non-linearly skew brightness banding. Higher numbers have smoother darks and band brights more, which is good for dark games.
"Brightness Levels" is the number of brightness levels. The lower the number, the more more bands and less brightness levels.
"Brightness Dither" is the type of brightness dither to use: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
"Brightness Dither" is the type of brightness dither to use: 0 for bayer 2x2, 1 for bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
"Color Levels" is the number of color levels. The lower the number, the more more bands and less colors used.
"Color Dither" is the type of color dither to use: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
"Color Dither" is the type of color dither to use: 0 for bayer 2x2, 1 for bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
"Dither Scale" is the pixel size of the dither. This can be done in combination with an in-engine pixel size setting.


Expand Down
12 changes: 6 additions & 6 deletions GZDoom/cvarinfo.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
user bool gl_hsvdither_enabled = true;
user float gl_hsvdither_brightness = 20;
user float gl_hsvdither_saturation = 20;
user float gl_hsvdither_brightness = 2;
user float gl_hsvdither_saturation = 2;
user float gl_hsvdither_curve = 2;
user float gl_hsvdither_blevels = 32;
user int gl_hsvdither_bdither = 3;
user float gl_hsvdither_clevels = 16;
user int gl_hsvdither_cdither = 4;
user float gl_hsvdither_blevels = 24;
user int gl_hsvdither_bdither = 4;
user float gl_hsvdither_clevels = 24;
user int gl_hsvdither_cdither = 3;
user float gl_hsvdither_scale = 2;
7 changes: 4 additions & 3 deletions GZDoom/menudef.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ OptionMenu "HSV Dither"
{
Title "HSV Dither"
Option "Enabled", "gl_hsvdither_enabled", "OnOff"
Slider "Brightness Boost", "gl_hsvdither_brightness", 1, 100, 1
Slider "Saturation Boost", "gl_hsvdither_saturation", 1, 100, 1
Slider "Brightness", "gl_hsvdither_brightness", 0, 5, 0.1
Slider "Saturation", "gl_hsvdither_saturation", 0, 5, 0.1
Slider "Banding Curve", "gl_hsvdither_curve", 0.1, 20.0, 0.1
Slider "Brightness Levels", "gl_hsvdither_blevels", 2.0, 64.0, 1.0
Option "Brightness Dither", "gl_hsvdither_bdither", "DitherOpts"
Expand All @@ -32,5 +32,6 @@ OptionValue "DitherOpts"
8, "ILG Noise"
9, "Tate"
10, "ZigZag"
11, "None"
11, "Diagonal"
12, "None"
}
46 changes: 34 additions & 12 deletions GZDoom/shaders/hsvdither.fp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ---------------------------------------------------------------------
// About HSV Dither 1.1
// About HSV Dither 1.2

// HSV Dither is a color boosting, banding and dithering shader. It operates on the color and brightness channels independently and non-linearly.
// See user defined values section to customize this shader and learn more about its capabilities. The effects are enhanced if you pair this with increased pixel sizes.
Expand All @@ -11,13 +11,13 @@
// ---------------------------------------------------------------------
// User defined values

float brightness = 1; // Non-linear brightness boost by boosting the V value of HSV.
float saturation = 1; // Non-linear saturation boost by boosting the S value of HSV.
float brightness = 2; // Brightness adjustment via the V value of HSV. A value of one is no change, greater than one increases brightness, and less than one decreases brightness.
float saturation = 2; // Saturation adjustment via the S value of HSV. A value of one is no change, greater than one increases saturation, and less than one decreases saturation.
float curve = 2; // Amount to non-linearly skew brightness banding. Higher numbers have smoother darks and band brights more, which is good for dark games.
float blevels = 31; // Brightness levels plus 1 (black). The lower the number, the more more bands and less brightness levels.
int bdither = 3; // Brightness dither: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
float clevels = 15; // Color levels plus 1. The lower the number, the more more bands and less colors used.
int cdither = 4; // Color dither: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, and 11 for none.
float blevels = 23; // Brightness levels plus 1 (black). The lower the number, the more more bands and less brightness levels.
int bdither = 4; // Brightness dither: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
float clevels = 23; // Color levels plus 1. The lower the number, the more more bands and less colors used.
int cdither = 3; // Color dither: 0 for Bayer 2x2, 1 for Bayer 8x8, 2 for static noise, 3 for motion noise, 4 for scanline, 5 for checker, 6 for magic square, 7 for grid, 8 for interleaved gradient noise, 9 for tate, 10 for zigzag, 11 for diagonal, and 12 for none.
int ditherscale = 2; // Pixel size of the dither. This can be done in combination with an in-engine pixel size setting.


Expand Down Expand Up @@ -154,6 +154,13 @@ float ilgnoise(vec2 position) {
return fract(52.9829189*dot(wavenum,position)); // return the limit
}

// Diagonal dither adapted from ILG Noise
float diagonal(vec2 position) {
vec2 wavenum = vec2(0.2501,-0.1999); // screen position noise

return 2*abs(fract(dot(wavenum,position))-0.5); // return the limit
}

// Static noise based dither roughly learned from: https://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner
float staticnoise(vec2 position){
vec2 wavenum = vec2(78.233,12.9898)+ilgnoise(position); // screen position noise
Expand Down Expand Up @@ -184,7 +191,20 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function
bvec3 compare = bvec3(0,0,0); // boolean vector for comparison of dither limit vector

// saturation / brightness boost
c.yz = atan(c.yz*vec2(saturation,brightness))/atan(vec2(saturation,brightness)); // non-linear scale and normalize back to 1
if (saturation > 1) { // saturate
saturation = saturation-1;
c.y = atan(c.y*saturation)/atan(saturation); // non-linear scale and normalize back to 1
} else { // desaturate
c.y *= saturation;
}

if (brightness > 1) { // brighten
brightness = brightness-1;
c.z = atan(c.z*brightness)/atan(brightness); // non-linear scale and normalize back to 1
} else { // darken
c.z *= brightness;
}


// apply non-linear brightness banding
c.z = atan(c.z*curve)/atan(curve); // non-linear scale the colors before banding
Expand All @@ -209,7 +229,8 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function
case 8: ditherlimit.x = ilgnoise(position); break; // ILG Noise Dither
case 9: ditherlimit.x = tate(position); break; // Tate Dither
case 10: ditherlimit.x = zigzag(position); break; // ZigZag Dither
case 11: ditherlimit.x = 0.5; break; // None
case 11: ditherlimit.x = diagonal(position); break; // Diagonal Dither
case 12: ditherlimit.x = 0.5; break; // None
}

ditherlimit.y = ditherlimit.x; // Hue and saturation have same ditherlimit
Expand All @@ -227,7 +248,8 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function
case 8: ditherlimit.z = ilgnoise(position); break; // ILG Noise Dither
case 9: ditherlimit.z = tate(position); break; // Tate Dither
case 10: ditherlimit.z = zigzag(position); break; // ZigZag Dither
case 11: ditherlimit.z = 0.5; break; // None
case 11: ditherlimit.z = diagonal(position); break; // Diagonal Dither
case 12: ditherlimit.z = 0.5; break; // None
}

// determine which color values to quantize up for dithering
Expand All @@ -250,8 +272,8 @@ vec4 colround(vec2 position, vec4 color){ // Rounding function

void main()
{
brightness = (hsvd_brightness)/20; // grab brightness boost from GZDoom
saturation = (hsvd_saturation)/20; // grab saturation boost from GZDoom
brightness = hsvd_brightness; // grab brightness boost from GZDoom
saturation = hsvd_saturation; // grab saturation boost from GZDoom
curve = hsvd_curve; // grab banding curve from GZDoom
blevels = hsvd_blevels - 1.0; // grab brightness levels from GZDoom
bdither = hsvd_bdither; // grab brightness dither from GZDoom
Expand Down
Loading

0 comments on commit 8fa4de4

Please sign in to comment.