/* COMPATIBILITY 
   - HLSL compilers
   - Cg   compilers
   - FX11 compilers
*/

/*
   Author: Themaister
   License: Public domain
*/

#include "../../compat_includes.inc"
uniform COMPAT_Texture2D(decal) : TEXUNIT0;
uniform float4x4 modelViewProj;

struct out_vertex
{
	float4 position : COMPAT_POS;
	float2 texCoord : TEXCOORD0;
	float4 c00_10   : TEXCOORD1;
	float4 c20_01   : TEXCOORD2;
	float4 c21_02   : TEXCOORD3;
	float4 c12_22   : TEXCOORD4;
	float2 c11      : TEXCOORD5;
	float2 pixel_no : TEXCOORD6;
#ifndef HLSL_4
	float4 Color    : COLOR;
#endif
};

out_vertex main_vertex(COMPAT_IN_VERTEX)
{
	out_vertex OUT;
#ifdef HLSL_4
	float4 position = VIN.position;
	float2 texCoord = VIN.texCoord;
#else
	OUT.Color = color;
#endif
	OUT.position = mul(modelViewProj, position);

	float dx = 1.0 / IN.texture_size.x;
	float dy = 1.0 / IN.texture_size.y;

	OUT.c00_10 = float4(texCoord + float2(-dx, -dy), texCoord + float2(0, -dy));
	OUT.c20_01 = float4(texCoord + float2(dx, -dy), texCoord + float2(-dx, 0));
	OUT.c21_02 = float4(texCoord + float2(dx, 0), texCoord + float2(-dx, dy));
	OUT.c12_22 = float4(texCoord + float2(0, dy), texCoord + float2(dx, dy));
	OUT.c11 = texCoord;
	OUT.pixel_no = texCoord * IN.texture_size;
	return OUT;
}

const float gamma = 2.4;
const float shine = 0.05;
const float blend = 0.65;

float dist(float2 coord, float2 source)
{
   float2 delta = coord - source;
   return sqrt(dot(delta, delta));
}

float color_bloom(float3 color)
{
   const float3 gray_coeff = float3(0.30, 0.59, 0.11);
   float bright = dot(color, gray_coeff);
   return lerp(1.0 + shine, 1.0 - shine, bright);
}

float3 lookup(float2 pixel_no, float offset_x, float offset_y, float3 color)
{
   float2 offset = float2(offset_x, offset_y);
   float delta = dist(frac(pixel_no), offset + float2(0.5, 0.5));
   return color * exp(-gamma * delta * color_bloom(color));
}

#define TEX(coord) COMPAT_SamplePoint(decal, coord).rgb

float4 dot_effect(float4 c00_10, float4 c20_01, float4 c21_02, float4 c12_22, float2 c11, float2 pixel_no)
{
   float3 mid_color = lookup(pixel_no, 0.0, 0.0, TEX(c11));
   float3 color = float3(0.0, 0.0, 0.0);
   color += lookup(pixel_no, -1.0, -1.0, TEX(c00_10.xy));
   color += lookup(pixel_no,  0.0, -1.0, TEX(c00_10.zw));
   color += lookup(pixel_no,  1.0, -1.0, TEX(c20_01.xy));
   color += lookup(pixel_no, -1.0,  0.0, TEX(c20_01.zw));
   color += mid_color;
   color += lookup(pixel_no,  1.0,  0.0, TEX(c21_02.xy));
   color += lookup(pixel_no, -1.0,  1.0, TEX(c21_02.zw));
   color += lookup(pixel_no,  0.0,  1.0, TEX(c12_22.xy));
   color += lookup(pixel_no,  1.0,  1.0, TEX(c12_22.zw));
   float3 out_color = lerp(1.2 * mid_color, color, blend);

   return float4(out_color, 1.0);
}

float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output
{
	return dot_effect(VOUT.c00_10, VOUT.c20_01, VOUT.c21_02, VOUT.c12_22, VOUT.c11, VOUT.pixel_no);
}
COMPAT_END