Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Luminance In Desaturate Shader #557

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 44 additions & 37 deletions src/Shaders/Desaturate.shader
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,61 @@ uniform sampler2D selection;
uniform bool affect_selection;
uniform bool has_selection;

vec3 rgb2hsb(vec3 c){
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz),
vec4(c.gb, K.xy),
step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r),
vec4(c.r, p.yzx),
step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),
d / (q.x + e),
q.x);
float stolChannel(float x) {
return (x < 0.04045) ? (x / 12.92) : pow((x + 0.055) / 1.055, 2.4);
}

vec3 hsb2rgb(vec3 c){
vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
6.0)-3.0)-1.0,
0.0,
1.0 );
rgb = rgb*rgb*(3.0-2.0*rgb);
return c.z * mix(vec3(1.0), rgb, c.y);
vec3 standardToLinear(vec3 c) {
return vec3(
stolChannel(c.r),
stolChannel(c.g),
stolChannel(c.b));
}

float ltosChannel(float x) {
return (x > 0.0031308) ? (pow(x, 1.0 / 2.4) * 1.055 - 0.055) : (x * 12.92);
}

vec3 linearToStandard(vec3 c) {
return vec3(
ltosChannel(c.r),
ltosChannel(c.g),
ltosChannel(c.b));
}

float luminance(vec3 lin) {
return 0.21264935 * lin.r
+ 0.71516913 * lin.g
+ 0.07218152 * lin.b;
}

void fragment() {
// Get color from the sprite texture at the current pixel we are rendering
vec4 original_color = texture(TEXTURE, UV);
vec4 selection_color = texture(selection, UV);

vec3 col = original_color.rgb;
vec3 hsb = rgb2hsb(col);
float gray = hsb.z;
if (red)
col.x = gray;
if (green)
col.y = gray;
if (blue)
col.z = gray;
// Transform from standard RGB to linear RGB.
vec3 std = original_color.rgb;
vec3 lin = standardToLinear(std);

// Find the y component of linear RGB to XYZ transformation.
float lum = luminance(lin);
vec3 des = vec3(
red ? lum : lin.r,
green ? lum : lin.g,
blue ? lum : lin.b);
vec3 stdPrime = linearToStandard(des);

vec3 output;
if(affect_selection && has_selection)
output = mix(original_color.rgb, col, selection_color.a);
else
output = col;
if (alpha)
COLOR = vec4(output.rgb, gray);
else
COLOR = vec4(output.rgb, original_color.a);
if(affect_selection && has_selection) {
output = mix(original_color.rgb, stdPrime, selection_color.a);
} else {
output = stdPrime;
}

if (alpha) {
COLOR = vec4(output.rgb, ltosChannel(lum));
} else {
COLOR = vec4(output.rgb, original_color.a);
}
}