
// You may modify this to move more data from the vertex shader to the pixel shader.
// It needs at least the position to work.
struct VS_to_PS {
	float4 Pos : SV_POSITION;
	float4 Tex : TEXCOORD0;
	float4 Color : COLOR;
	float3 Normal_WorldSpace : NORMAL;
	float4 Pos_WorldSpace : TEXCOORD1;
	float4 Pos_CameraSpace : TEXCOORD2;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_to_PS VS( VS_structure input ) {
	VS_to_PS output = (VS_to_PS)0;
	
	// Convert vertice positions from object space to world space
	output.Pos_WorldSpace = mul( input.Pos, ObjectToWorld );
	// Convert vertice positions from world space to camera space
	output.Pos_CameraSpace = mul( output.Pos_WorldSpace, WorldToCamera );
	// Convert vertice positions from camera space to 2D projection
	output.Pos = mul( output.Pos_CameraSpace, CameraToImage );
	
	// Transform normals to world space
	output.Normal_WorldSpace = mul(input.Normal,(float3x3)ObjectToWorld);
	
	// Give the texture coordinates to the pixel shader
	output.Tex = input.Tex;
	
	// Give the vertex color multiplied with the instance color to the pixel shader
	output.Color = lerp(input.Color * InstanceColor, float4(0.0f,0.0f,1.0f,1.0f), input.Selected);
	
	return output;
}

#define WaveOffset1 Arg[0].xy
#define WaveOffset2 Arg[0].zw
#define WaveScale Arg[1].x
#define WaveIntensity Arg[1].y

#define ReflectionTexture tex_0
#define RefractionTexture tex_1
#define WaveTexture tex_2

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( VS_to_PS input) : SV_Target {
	float4 finalColor;
	
	// Sample the waves multiple times with different offsets and add the results before normalizing
	float2 waveOffset = (WaveTexture.Sample( samAnisotropicMipmap, (input.Pos_WorldSpace.xz + WaveOffset1) / WaveScale ).rg
			   + WaveTexture.Sample( samAnisotropicMipmap, (input.Pos_WorldSpace.xz + WaveOffset2) / WaveScale ).rg
			   - 1.0f) * (WaveIntensity / length(input.Pos_CameraSpace));
	
	// Sample the images
	float4 reflectionColor = ReflectionTexture.Sample( samClampedSharp, float2(input.Pos.x / Dimensions.x, 1.0f - (input.Pos.y / Dimensions.y)) + (waveOffset / float2(CameraXScale,CameraYScale) * 0.15f) );
	float4 refractionColor = RefractionTexture.Sample( samClampedSharp, (input.Pos.xy / Dimensions) - (waveOffset / float2(CameraXScale,CameraYScale) * 0.03f) );
	
	// Calculate how much you see thru the water
	float RefractionRatio = saturate((normalize(normalize(input.Pos_WorldSpace - CameraPos_WorldSpace) + (float3(waveOffset.x, 0.0f, waveOffset.y) * 3.0f)).y - 0.3f) * 10.0f);
	
	// Mix reflection and refraction
	finalColor = lerp(reflectionColor,refractionColor,RefractionRatio);
	
	// Show the final color without fog
	//return float4((lerp(finalColor,FogColor,saturate(length(input.Pos_CameraSpace) / FogDistance) * MaxFogIntensity)).xyz,finalColor.w);
	return finalColor;
}
