//
// Standard lighting for waving dynamic objects
//

#include "atmosphere.cg"
#include "lighting.cg"

// App to vertex
struct a2v
{
  float4 Position : POSITION;
  float3 normal   : NORMAL;
  float2 tc0      : TEXCOORD0;
};

// Vertex to pixel shader structure
struct v2p
{
  float4 Position       : POSITION;
  float3 FPosition			: TEXCOORD4;    // For fragment shader
  //float3 Color 			: COLOR;
  float3 normal         : TEXCOORD5;
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float2 tc0            : TEXCOORD0;
  float3 Direction		  : TEXCOORD1;
  float  extinction		  : TEXCOORD6;
};

float3 Wave(float time,float3 pos,float2 uv)
// Returns world offset based on time and texture coordinates
{
  float3 off;
  float sinOff=pos.x+pos.y+pos.z;
  float t=-time*3;
  float sin1=sin(t*1.45+sinOff);
  float sin2=sin(t*3.12+sinOff);
  float sin3=sin(t*2.2+sinOff);
  float fx=uv.x*uv.x;
  float fy=uv.x*uv.y;
  
  off.x=sin1*fx*0.5;
  off.y=sin2*fx*0.5-fy*0.9;
  off.z=sin3*fx*0.5;
  
  return off;
}

void main(
  // a2v
  in  a2v IN,
  out v2p OUT,

  // Constants
  uniform float4x4 modelViewProj,
  uniform float4x4 modelMatrix,
  uniform float    time,
  uniform float3   lightDirection,
  uniform float3   eyePosW,
  uniform float3   lightColor,
  uniform float    scale,
  // Atmosphere
  uniform float    sunIntensity,
  uniform float    atmosRayleigh,
  uniform float    atmosMie,
  uniform float    extinctionFactor
)
{
  // Transform to clipspace
  float4 posWC=IN.Position;
  
  // Wave
  posWC.xyz+=scale*Wave(time,posWC,IN.tc0);
  OUT.Position=mul(modelViewProj,posWC);

  // Atmosphere
  CalculateAtmosphere(atmosRayleigh,atmosMie,sunIntensity,eyePosW,posWC,lightDirection,
    OUT.RayleighColor,OUT.MieColor,OUT.Direction);

  // Extinction factor of regular color
  OUT.extinction=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie,extinctionFactor);

  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  OUT.normal=mul((float3x3)modelMatrix, IN.normal);
  //OUT.normal=IN.normal; //mul((float3x3)modelMatrix, IN.normal);
  //OUT.FPosition=mul(modelMatrix,IN.Position).xyz;
  OUT.FPosition=posWC.xyz;
}
