// Pixellate - Area-weighted pixel sampling filter
// Based on https://github.com/libretro/common-shaders/blob/master/interpolation/shaders/pixellate.cg

//!BGFX EFFECT
//!VERSION 1

//!NAME Pixellate
//!CATEGORY Pixel Art
//!DESCRIPTION Area-weighted sampling filter that produces clean pixel scaling by blending colors based on coverage area.


//!TEXTURE
Texture2D INPUT;

//!TEXTURE
Texture2D OUTPUT;

//!SAMPLER
//!FILTER POINT
SamplerState sam;


//!PASS 1
//!STYLE PS
//!IN INPUT
//!OUT OUTPUT

float4 Pass1(float2 pos) {
	float2 texelSize = GetInputPt();

	// Calculate sampling range (slightly less than half output pixel)
	float2 range = GetOutputPt() / 2.0f * 0.999f;

	// Compute bounding box edges
	float left = pos.x - range.x;
	float right = pos.x + range.x;
	float top = pos.y + range.y;
	float bottom = pos.y - range.y;

	// Sample colors at the four corners (snapped to texel centers)
	float3 topLeftColor = INPUT.SampleLevel(sam, (floor(float2(left, top) / texelSize) + 0.5) * texelSize, 0).rgb;
	float3 topRightColor = INPUT.SampleLevel(sam, (floor(float2(right, top) / texelSize) + 0.5) * texelSize, 0).rgb;
	float3 bottomLeftColor = INPUT.SampleLevel(sam, (floor(float2(left, bottom) / texelSize) + 0.5) * texelSize, 0).rgb;
	float3 bottomRightColor = INPUT.SampleLevel(sam, (floor(float2(right, bottom) / texelSize) + 0.5) * texelSize, 0).rgb;

	// Find the texel boundary intersection point
	float2 border = clamp(round(pos / texelSize) * texelSize, float2(left, bottom), float2(right, top));

	// Calculate total area for normalization
	float totalArea = 4.0 * range.x * range.y;

	// Blend colors weighted by their coverage area
	float3 averageColor;
	averageColor = ((border.x - left) * (top - border.y) / totalArea) * topLeftColor;
	averageColor += ((right - border.x) * (border.y - bottom) / totalArea) * bottomRightColor;
	averageColor += ((border.x - left) * (border.y - bottom) / totalArea) * bottomLeftColor;
	averageColor += ((right - border.x) * (top - border.y) / totalArea) * topRightColor;

	return float4(averageColor, 1.0);
}
