// $MinimumShaderProfile: ps_4_0

Texture2D tex : register(t0);
SamplerState samp : register(s0);

cbuffer PS_CONSTANTS : register(b0)
{
	float2 pxy;
	float2 wh;
	uint   counter;
	float  clock;
};

#define PI acos(-1)

float4 main(float4 pos : SV_POSITION, float2 coord : TEXCOORD) : SV_Target
{
	// - this is a very simple raytracer, one sphere only
	// - no reflection or refraction, yet (my ati 9800 has a 64 + 32 instruction limit...)

	float3 pl = float3(3, -3, -4); // light pos
	float4 cl = 0.4; // light color

	float3 pc = float3(0, 0, -1);  // cam pos
	float3 ps = float3(0, 0, 0.5); // sphere pos
	float r = 0.65; // sphere radius

	float3 pd = normalize(float3(coord.x - 0.5, coord.y - 0.5, 0) - pc);

	float A = 1;
	float B = 2 * dot(pd, pc - ps);
	float C = dot(pc - ps, pc - ps) - r * r;
	float D = B * B - 4 * A * C;

	float4 c0 = 0;

	if (D >= 0) {
		// t2 is the smaller, obviously...
		// float t1 = (-B + sqrt(D)) / (2 * A);
		// float t2 = (-B - sqrt(D)) / (2 * A);
		// float t = min(t1, t2);

		float t = (-B - sqrt(D)) / (2 * A);

		// intersection data
		float3 p = pc + pd * t;
		float3 n = normalize(p  - ps);
		float3 l = normalize(pl - p);

		// mapping the image onto the sphere
		coord = acos(-n) / PI;

		// rotate it
		coord.x = frac(coord.x + frac(clock / 10));

		// diffuse + specular
		c0 = tex.Sample(samp, coord) * dot(n, l) + cl * pow(max(dot(l, reflect(pd, n)), 0), 50);
	}

	return c0;
}
