/* Hard-edge shader
 * Adapted from https://github.com/samuelbigos/godot_dither_shader
 */

shader_type canvas_item;

// uniform sampler2D dither_tex;
uniform sampler2D color_tex;

uniform int bit_depth;
uniform float contrast;
uniform float offset;
// uniform int dither_size;

void fragment() {
	//// sample the screen texture at the desired output resolution (according to dither_size)
	//// this pixelates the output
	//vec2 screen_size = vec2(textureSize(TEXTURE, 0)) / float(dither_size);
	//vec2 screen_sample_uv = floor(UV * screen_size) / screen_size;
	//vec3 screen_col = texture(TEXTURE, screen_sample_uv).rgb;
	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);

	// adjust contrast & offset
	// XXX: need to redefine contrast???
	luminosity = clamp((luminosity - 0.5 + offset) * contrast + 0.5, 0.0, 1.0);

	// reduce luminosity bit depth to increase banding if desired
	float b = float(bit_depth);
	luminosity = floor(luminosity * b) / b;

	// map palette texture to 1px high
	ivec2 col_size = textureSize(color_tex, 0);
	col_size /= col_size.y;

	float col_x = float(col_size.x) - 1.0;
	float col_texel_size = 1.0 / col_x;  // size of one color boundary

	luminosity = max(luminosity - 0.00001, 0.0);  // fix for `floor` when luminosity == 1.0
	float lum_lower = floor(luminosity * col_x) * col_texel_size;
	float lum_upper = (floor(luminosity * col_x) + 1.0) * col_texel_size;
	// fractional portion of scaled luminosity
	float lum_scaled = luminosity * col_x - floor(luminosity * col_x);

	//// map dither texture onto screen
	//ivec2 noise_size = textureSize(dither_tex, 0);
	//vec2 inv_noise_size = vec2(1.0 / float(noise_size.x), 1.0 / float(noise_size.y));
	//vec2 noise_uv = UV * inv_noise_size * vec2(float(screen_size.x), float(screen_size.y));
	//float threshold = texture(dither_tex, noise_uv).r;

	//// add dither margins to allow fully dark and light dither patterns at edges of luminosity
	//threshold = threshold * 0.99 + 0.005;

	//// the lower lum_scaled is, the fewer pixels will be below the dither threshold,
	//// and thus will use the lower bound color, and vice versa
	//float ramp_val = lum_scaled < threshold ? 0.0f : 1.0f;
	float ramp_val = lum_scaled < 0.5 ? 0.0f : 1.0f;
	// sample at lower bound color if ramp_val is 0.0, upper bound color if 1.0
	float col_sample = mix(lum_lower, lum_upper, ramp_val);

	COLOR.rgb = texture(color_tex, vec2(col_sample, 0.5)).rgb;
}
