// Sharp Bilinear - Crisp bilinear interpolation for pixel art
// Based on https://github.com/libretro/common-shaders/blob/master/interpolation/shaders/sharp-bilinear.cg

//!BGFX EFFECT
//!VERSION 1

//!NAME Sharp Bilinear
//!CATEGORY Pixel Art
//!DESCRIPTION Produces sharp pixel art scaling by constraining bilinear interpolation to texel boundaries, avoiding the typical blurry look of standard bilinear filtering.


//!TEXTURE
Texture2D INPUT;

//!TEXTURE
Texture2D OUTPUT;

//!SAMPLER
//!FILTER LINEAR
// Uses hardware bilinear interpolation for efficient sampling
SamplerState sam;


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

float4 Pass1(float2 pos) {
	float2 inputPt = GetInputPt();
	float2 scale = GetScale();

	// Convert position to texel coordinates
	float2 texel = pos * GetInputSize();
	float2 texel_floored = floor(texel);

	// Calculate fractional position within texel
	float2 s = frac(texel);

	// Determine the region where we want sharp (non-interpolated) output
	float2 region_range = 0.5 - 0.5 / scale;

	// Compute distance from texel center
	float2 center_dist = s - 0.5;

	// Clamp interpolation to create sharp regions near texel centers
	// Uses hardware bilinear interpolator to avoid manual 4-sample filtering
	float2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;

	// Calculate final sampling position
	float2 mod_texel = texel_floored + f;

	return INPUT.SampleLevel(sam, mod_texel * inputPt, 0);
}
