mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Use Luminance In Desaturate Shader (#557)
Updated desaturate shader to use perceptual luminance instead of HSV.
This commit is contained in:
parent
24d25d49ea
commit
429b37f6fc
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue