// AUTOGENERATED COPYRIGHT HEADER START
// Copyright (C) 2018-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// AUTOGENERATED COPYRIGHT HEADER END

#include "shared.effect"

uniform texture2d image;
uniform float2 imageTexel;
uniform float2 separableTexel;

VertexData VSDefault(VertexData vtx)
{
	vtx.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj);
	return vtx;
}

float4 Linear(VertexData vtx) : TARGET
{
	// The GPU takes care of the UVs here.
	return image.Sample(LinearRepeatSampler, vtx.uv);
}

technique Linear
{
	pass
	{
		vertex_shader = DefaultVertexShader(vtx);
		pixel_shader  = Linear(vtx);
	}
}

float4 MagicKernel2011(VertexData vtx) : TARGET {
	// [0.015625] [0.046875] [0.015625]
	// [0.046875] [0.140625] [0.046875]
	// [0.015625] [0.046875] [0.015625]
	// X weight .25
	// Y weight .25
	
	// Create UVs that are "centered" on the texel.
	float2 uv = (floor(vtx.uv / imageTexel) + 0.5) * imageTexel;

	float4 tl = image.Sample(LinearRepeatSampler, uv + imageTexel * float2(-.25, -.25));
	float4 tr = image.Sample(LinearRepeatSampler, uv + imageTexel * float2( .25, -.25));
	float4 bl = image.Sample(LinearRepeatSampler, uv + imageTexel * float2(-.25,  .25));
	float4 br = image.Sample(LinearRepeatSampler, uv + imageTexel * float2( .25,  .25));

	return (tl + tr + bl + br) / 4.;
}

technique MagicKernel2011
{
	pass
	{
		vertex_shader = DefaultVertexShader(vtx);
		pixel_shader  = MagicKernel2011(vtx);
	}
}

float4 MagicKernel2011Separable(VertexData vtx) : TARGET {
	// 1/8 3/4 1/8
	// Separable 3-tap, optimizable to 2-tap. Slower than Single Pass

	// Create UVs that are "centered" on the texel.
	float2 uv = (floor(vtx.uv / imageTexel) + 0.5) * imageTexel;

	float4 center = image.Sample(PointRepeatSampler, uv);
	float4 m1 = image.Sample(PointRepeatSampler, uv + separableTexel * -1.);
	float4 p1 = image.Sample(PointRepeatSampler, uv + separableTexel * 1.);

	return ((center * 0.75) + ((m1 + p1) * 0.125));
}

technique MagicKernel2011Separable
{
	pass
	{
		vertex_shader = DefaultVertexShader(vtx);
		pixel_shader = MagicKernel2011Separable(vtx);
	}
	pass
	{
		vertex_shader = DefaultVertexShader(vtx);
		pixel_shader = MagicKernel2011Separable(vtx);
	}
}

float4 MagicKernelSharp2021Separable(VertexData vtx) : TARGET {
	// -1 +6 -35 +204 -35 +6 -1 / 144
	// Separable 7-tap, AFAIK not optimizable due to negative weights.
	
	// Create UVs that are "centered" on the texel.
	float2 uv = (floor(vtx.uv / imageTexel) + 0.5) * imageTexel;

	float4 center = image.Sample(PointRepeatSampler, uv);
	float4 m1 = image.Sample(PointRepeatSampler, uv + separableTexel * -1.);
	float4 m2 = image.Sample(PointRepeatSampler, uv + separableTexel * -2.);
	float4 m3 = image.Sample(PointRepeatSampler, uv + separableTexel * -3.);
	float4 p1 = image.Sample(PointRepeatSampler, uv + separableTexel * 1.);
	float4 p2 = image.Sample(PointRepeatSampler, uv + separableTexel * 2.);
	float4 p3 = image.Sample(PointRepeatSampler, uv + separableTexel * 3.);

	return ((center * 204.) + ((m1 + p1) * -35.) + ((m2 + p2) * 6.) + ((m3 + p3) * -1.)) / 144.;
}

technique MagicKernelSharp2021Separable
{
	pass
	{
		vertex_shader = DefaultVertexShader(vtx);
		pixel_shader = MagicKernelSharp2021Separable(vtx);
	}
	pass
	{
		vertex_shader = DefaultVertexShader(vtx);
		pixel_shader = MagicKernelSharp2021Separable(vtx);
	}
}
