varying vec2 TexCoord0;
uniform sampler2D tex;
uniform sampler2D auxTex;
uniform vec2 texSize;
uniform vec2 auxTexSize;
uniform float pts;
uniform float intensity;

// The brightnesses at which different hatch lines appear
const float HATCH_0 = 0.8;
const float HATCH_1 = 0.6;
const float HATCH_2 = 0.3;
const float HATCH_3 = 0.15;

// How wide hatch lines are drawn.
const float WIDTH = 1.0;

const float HATCH_0_BRIGHTNESS = 0.8;
const float HATCH_1_BRIGHTNESS = 0.6;
const float HATCH_2_BRIGHTNESS = 0.3;
const float HATCH_3_BRIGHTNESS = 0.0;

const float LOOKUP_RADIUS = 1.0;

float GetLuma(vec3 rgb)
{
	return dot(vec3(0.2126, 0.7152, 0.0722), rgb);
}

float lookup(vec2 coord, float dx, float dy)
{
	vec2 uv = (coord + vec2(dx, dy) * LOOKUP_RADIUS) / texSize;
	vec4 color = texture2D(tex, uv);

	return GetLuma(color.rgb);
}

void main()
{
	vec3 res = vec3(1.0, 1.0, 1.0);
	vec4 texColor = texture2D(tex, TexCoord0);
	float brightness = GetLuma(texColor.rgb);

	// Check whether we have enough of a hue to warrant coloring our
	// hatch strokes. If not, just use greyscale for our hatch color.
	float dimmestChannel = min(min(texColor.r, texColor.g), texColor.b);
	float brightestChannel = max(max(texColor.r, texColor.g), texColor.b);
	float brightnessDelta = brightestChannel - dimmestChannel;
	if (brightnessDelta > 0.1)
		texColor = texColor * (1.0 / brightestChannel);
	else
		texColor.rgb = vec3(1.0, 1.0, 1.0);

	float lineDensity = 5.0 + 25.0 * (1.0 - intensity);
	vec2 coord = TexCoord0 * texSize;

	if (brightness < HATCH_0)
	{
		if (mod(coord.x + coord.y, lineDensity) <= WIDTH)
			res = texColor.rgb * HATCH_0_BRIGHTNESS;
	}
	if (brightness < HATCH_1)
	{
		if (mod(coord.x - coord.y, lineDensity) <= WIDTH)
			res = texColor.rgb * HATCH_1_BRIGHTNESS;
	}
	if (brightness < HATCH_2)
	{
		if (mod(coord.x + coord.y - (lineDensity * 0.5), lineDensity) <= WIDTH)
			res = texColor.rgb * HATCH_2_BRIGHTNESS;
	}
	if (brightness < HATCH_3)
	{
		if (mod(coord.x - coord.y - (lineDensity * 0.5), lineDensity) <= WIDTH)
			res = texColor.rgb * HATCH_3_BRIGHTNESS;
	}

	float luma_m1_m1 = lookup(coord, -1.0, -1.0);
	float luma_m1_0  = lookup(coord, -1.0,  0.0);
	float luma_m1_1  = lookup(coord, -1.0,  1.0);
	float luma_1_m1  = lookup(coord,  1.0, -1.0);
	float luma_1_0   = lookup(coord,  1.0,  0.0);
	float luma_1_1   = lookup(coord,  1.0,  1.0);
	float luma_0_m1  = lookup(coord,  0.0, -1.0);
	float luma_0_1   = lookup(coord,  0.0,  1.0);

	float gx =
		-1.0 * luma_m1_m1
		-2.0 * luma_m1_0
		-1.0 * luma_m1_1
		+1.0 * luma_1_m1
		+2.0 * luma_1_0
		+1.0 * luma_1_1;

	float gy =
		-1.0 * luma_m1_m1
		-2.0 * luma_0_m1
		-1.0 * luma_1_m1
		+1.0 * luma_m1_1
		+2.0 * luma_0_1
		+1.0 * luma_1_1;

	// Use g^2 to conceal noise in the video
	float g = gx * gx + gy * gy;
	res *= (1.0 - g);

	gl_FragColor = vec4(res, texColor.a);
}
