Skip to content

Commit

Permalink
Add hue and saturation controls on !adjust
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanhogg committed Nov 13, 2024
1 parent 5de4f2f commit 8990da1
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
11 changes: 11 additions & 0 deletions docs/shaders.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,16 @@ range around 0.5.
double the color value of each pixel, an adjustment of `-1` will half the value
of each pixel. Default is `0`.

`hue=` *DELTA*
: Specifies a positive or negative hue adjustment in the useful range
$(-0.5,0.5)$. All colors will be rotated around the standard HSV hue cylinder
by this amount.

`saturation=` *MULTIPLIER*
: Specifies an amount to multiple the saturation of each pixel by. Values
less than `1` will desaturate the image and values greater than `1` will
over-saturate it. A value of `0` will convert the image to grayscale.

`shadows=` *STOPS*
: Specifies an exposure adjustment to apply to the darker parts of the input
image (luminance < $0.25$).
Expand Down Expand Up @@ -358,6 +368,7 @@ The `!adjust` filter works in the following order:

- un-premultiply alpha
- apply `color_matrix`
- apply `hue` and `saturation`
- apply `exposure`
- apply `brightness` and `contrast`
- apply `shadows` and `highlights`
Expand Down
8 changes: 6 additions & 2 deletions src/flitter/render/window/glsl/adjust.frag
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ uniform float contrast;
uniform float brightness;
uniform float shadows;
uniform float highlights;
uniform float hue;
uniform float saturation;
uniform mat3 color_matrix;
% if tonemap_function == 'reinhard':
uniform float whitepoint;
Expand All @@ -30,8 +32,10 @@ void main() {
% endif
% endfor
vec3 col = merged.a > 0.0 ? merged.rgb / merged.a : vec3(0.0);
col = color_matrix * col;
col = filter_adjust(col, exposure, contrast, brightness, shadows, highlights);
vec3 hsv = rgb_to_hsv(color_matrix * col);
hsv.x += hue;
hsv.y *= saturation;
col = filter_adjust(hsv_to_rgb(hsv), exposure, contrast, brightness, shadows, highlights);
col = max(vec3(0.0), col);
% if gamma != 1:
col = pow(col, vec3(gamma));
Expand Down
15 changes: 15 additions & 0 deletions src/flitter/render/window/glsl/color_functions.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ vec3 tonemap_aces(vec3 color)
color = (color * (color + 0.0245786) - 0.000090537) / (color * (0.983729 * color + 0.4329510) + 0.238081);
return mat3(1.60475, -0.10208, -0.00327, -0.53108, 1.10813, -0.07276, -0.07367, -0.00605, 1.07602) * color;
}

vec3 rgb_to_hsv(vec3 color) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(color.bg, K.wz), vec4(color.gb, K.xy), step(color.b, color.g));
vec4 q = mix(vec4(p.xyw, color.r), vec4(color.r, p.yzx), step(p.x, color.r));
float d = q.x - min(q.w, q.y);
const float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv_to_rgb(vec3 color) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(color.xxx + K.xyz) * 6.0 - K.www);
return color.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y);
}
2 changes: 1 addition & 1 deletion src/flitter/render/window/shaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def render(self, node, references, **kwargs):
if tonemap not in self.TONEMAP_FUNCTIONS:
tonemap = None
super().render(node, references, exposure=0, contrast=1, brightness=0, shadows=0, highlights=0,
color_matrix=(1, 0, 0, 0, 1, 0, 0, 0, 1),
hue=0, saturation=1, color_matrix=(1, 0, 0, 0, 1, 0, 0, 0, 1),
gamma=1, tonemap_function=tonemap, **kwargs)


Expand Down

0 comments on commit 8990da1

Please sign in to comment.