//////////////////////////////////////////////////////////////////////////////////////////
//
//  FILE        :  Asura_D3D_PS_Water.cpp
//
//  CREATED     :  Richard J. Fine  (17.3.2005)
//
//  Copyright (C) 2005 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////////////////


#include "Core/Asura.h"

// This file's header.
#include "Rendering/Asura_Direct3D_Shaders.h"

#ifdef ASURA_USE_WATER

static const char* const szPS_WATER_CODE =

/* This code was vaguely generated by FX Composer, from the following HLSL:

float4 PS_Water( vertexOutput IN): COLOR
{
  float4 basePlane = tex2D(baseTextureSampler, IN.baseTexCoords);
  float3 horizonColor = tex2D(horizonSampler, IN.horizonTexCoords);
  float fresnel = IN.parameters.x;
  float sunlightFalloff = IN.parameters.y;
  float3 sunColor = tex2D(sunSampler, IN.sunTexCoords);
  
  float3 base = (basePlane.rgb * basePlane.w * IN.lighting.xyz * IN.lighting.w);
  float3 horizon = horizonColor * horizonBrightness * fresnel;
  float3 sun = sunColor * sunlightFalloff * reflectionStrength;
  
  return float4(base + horizon + sun, 1 - (basePlane.w * IN.lighting.w));
}

  The minimum profile under which the code would compile was PS1.4. This shader is two-phase.
*/

// c0.x		= horizon	brightness 
// c1.x		= sun		brightnesss
// c2		= 0,0,0,1
// c3.w		= horizon fresnel scale
// t2.x		= fresnel
// t2.y		= sun falloff
//
// v0.xyz	= vertex colour
// v0.w		= ?? sun falloff
//
// c0.x		= horizon	brightness 
// c1.x		= sun		brightnesss
// c2		= 0,0,0,1
// c3.w		= horizon fresnel scale
// t2.x		= fresnel
// t2.y		= sun falloff
//
// v0.xyz	= vertex colour
// v0.w		= ?? sun falloff
"ps_1_4								"
"texld	r0,		t0					"	// r0		= water texture	
"mul	r2.xyz,	r0.w,	r0			"	// r2.xyz	= water texture * alpha
"mov	r4.x,	r0.w				"	// r4.x		= waterAlpha

"phase								"	//

"texcrd	r0.xyz,	t2					"	// r0.xyz	= t2 coord
"texld	r1,		t1					"	// r1		= horizon reflection
"texld	r3,		t3					"	// r3		= sun reflection

"mov	r4.w,	r4.x				"	// r4.w		= waterAlpha

"+mul	r1.xyz,	r1,		c0.x		"	// r1.xyz	= horizon * horizon brightness
"mul	r1.xyz,	r1,		r0.x		"	// r1.xyz	*= fresnel

"mul	r2.xyz,	r2,		v0			"	// r2.xyz	= water texture * vtxColour
"mul	r2.xyz,	r2,		v0.w		"	//			* vtxAlpha

"mad	r1.xyz,	r1,		c3.w,	r2	"	// r1.xyz	= (FinalHorizon * horizonFresnelScale) + FinalWater

"mul	r0.xyz,	r3,		r0.y		"	// r0.xyz	= (sunRef * refStrength
"mad	r0.xyz,	r0,		c1.x,	r1	"	// r0.xyz	* sun brightness) + FinalHoriz + FinalWater

"mad	r0.w,	r4.w,	-v0.w,	c2.w"	// r0.w		= 1 - (basePlane.w * vtxAlpha)
;


// Register the shader with Asura

static const Asura_Direct3D_PixelShader xPS_WATER_SHADER(ASURA_D3D_PS_WATER, szPS_WATER_CODE, 1.4f);

static const char* const szPS_WATER_BLENDED_CODE =

/* This code was vaguely generated by FX Composer, from the following HLSL:

float4 PS_Water_Blended( vertexOutput IN): COLOR
{
  float4 basePlane = tex2D(baseTextureSampler, IN.baseTexCoords);
  float3 horizonColor = tex2D(horizonSampler, IN.horizonTexCoords);
  float fresnel = IN.parameters.x;
  float sunlightFalloff = IN.parameters.y;
  float3 sunColor = tex2D(sunSampler, IN.sunTexCoords);
  
  float3 base = (basePlane.rgb * basePlane.w * IN.lighting.xyz * IN.lighting.w);
  float3 horizon = horizonColor * horizonBrightness;
  float3 sun = sunColor * sunlightFalloff * reflectionStrength;
  
  return float4(lerp(base, horizon, fresnel) + sun, 1 - (basePlane.w * IN.lighting.w));
}

  The minimum profile under which the code would compile was PS1.4. This shader is two-phase.
*/
"ps_1_4							"
"texcrd r0.xyz, t2				"
"texld r1, t1					"
"mul r1.xyz, r1, c0.x			"
"+ mul r2.w, r0.x, c3.w			"	// mul against fresnel scale instead of zero
"add r3.w, -r2.w, c2.w			"
"+ mul r1.xyz, r2.w, r1			"
"mov r2.y, r0.y					"
"mov r2.x, r3.w					"
"phase							"
"texld r0, t0					"
"texld r3, t3					"
"mov r2.w, r2.x					"
"+ mul r4.xyz, r0.w, r0			"
"mul r4.xyz, r4, v0				"
"mul r4.xyz, r4, v0.w			"
"mad r1.xyz, r4, r2.w, r1		"
"mul r2.xyz, r3, r2.y			"
"mad r0.xyz, r2, c1.x, r1		"
"+ mad r0.w, r0.w, -v0.w, c2.w	"
;

// Register the shader with Asura

static const Asura_Direct3D_PixelShader xPS_WATER_BLENDED_SHADER(ASURA_D3D_PS_WATER_BLENDED, szPS_WATER_BLENDED_CODE, 1.4f);

// Fallback version of the shader, only requires ps1.1
static const char* const szPS_WATER_FALLBACK_CODE = 
"ps_1_1							\n"
"tex t0							\n"

"mul r0.xyz, t0.w, t0			\n"	// base * basealpha
"mul r0.xyz, r0, v0				\n" // base * basealpha * lightalpha
"mul r0.xyz, t0, v0.w			\n"
"+ mov r0.w, c1.w				\n"

;

static const Asura_Direct3D_PixelShader xPS_WATER_FALLBACK_SHADER(ASURA_D3D_PS_WATER_FALLBACK, szPS_WATER_FALLBACK_CODE, 1.1f);

#endif
