diff --git a/src/main.tscn b/src/main.tscn index 815017b..fc795bf 100644 --- a/src/main.tscn +++ b/src/main.tscn @@ -56,7 +56,7 @@ shader = ExtResource("1_rg2hr") shader = ExtResource("1_bg1gg") shader_parameter/color_low = Color(0, 0, 0, 1) shader_parameter/color_hi = Color(1, 1, 1, 1) -shader_parameter/threshold = 0.455 +shader_parameter/threshold = 0.174 shader_parameter/contrast = 1.0 shader_parameter/offset = 0.0 diff --git a/src/shaders/threshold.gdshader b/src/shaders/threshold.gdshader index 1fe4238..2832627 100644 --- a/src/shaders/threshold.gdshader +++ b/src/shaders/threshold.gdshader @@ -1,23 +1,35 @@ -/* Binary threshold shader */ +/* Binary threshold shader + * See https://stackoverflow.com/a/56678483 + */ shader_type canvas_item; uniform vec4 color_low: source_color = vec4(0.0, 0.0, 0.0, 1.0); uniform vec4 color_hi: source_color = vec4(1.0, 1.0, 1.0, 1.0); -uniform float threshold: hint_range(0.0, 1.0) = 0.5; +uniform float threshold: hint_range(0.0, 1.0) = 0.455; uniform float contrast: hint_range(0.0, 1.0) = 1.0; uniform float offset: hint_range(-1.0, 1.0) = 0.0; +float linearSRGB(float channel) { + if (channel <= 0.04045) { + return channel / 12.92; + } else { + return pow(((channel + 0.055) / 1.055), 2.4); + } +} + +float luminance(vec3 color) { + return 0.2126 * linearSRGB(color.r) + 0.7152 * linearSRGB(color.g) + 0.0722 * linearSRGB(color.b); +} void fragment() { vec3 screen_col = texture(TEXTURE, UV).rgb; - // calculate pixel luminosity - float luminosity = (screen_col.r * 0.299) + (screen_col.g * 0.587) + (screen_col.b * 0.114); + float Y = luminance(screen_col); // adjust contrast & offset - luminosity = clamp((luminosity - 0.5 + offset) * contrast + 0.5, 0.0, 1.0); + Y = clamp((Y - 0.5 + offset) * contrast + 0.5, 0.0, 1.0); - COLOR.rgba = luminosity > threshold ? color_hi : color_low; + COLOR.rgba = Y > threshold ? color_hi : color_low; }