//
// Standard lighting with reflection - dynamic models (modelMatrix)
// RvG, 16-3-09
//

#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;
  float2 tc0            : TEXCOORD0;
  float3 Direction      : TEXCOORD1;
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float3 FPosition      : TEXCOORD4;    // For fragment shader
  float3 normal         : TEXCOORD5;
  // Interpolate fresnel in PS
  float3 I              : TEXCOORD6;
  //float  fresnel        : TEXCOORD6;
  float3 R              : TEXCOORD7;    // Reflection vector
  float  extinction     : COLOR;        // 0..1
};

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

  // Constants
  uniform float4x4 modelViewProj,
  uniform float4x4 modelMatrix,
  uniform float3   lightDirection,
  uniform float3   eyePosW,
  uniform float3   lightColor,
  // Atmosphere
  uniform float    sunIntensity,
  uniform float    atmosRayleigh,
  uniform float    atmosMie
)
{
  // Transform to clipspace
  OUT.Position=mul(modelViewProj,IN.Position);
  float3 posW=mul(modelMatrix,IN.Position).xyz;

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

  // Extinction factor of regular color
  OUT.extinction=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie);
  
  float3 N=mul((float3x3)modelMatrix,IN.normal);

  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  //OUT.normal=IN.normal; //mul((float3x3)modelMatrix, IN.normal);
  OUT.normal=N;
  OUT.FPosition=posW; //mul(modelMatrix,IN.Position).xyz;
  
  // Reflection
  float3 I=posW-eyePosW;
  OUT.R=reflect(I,N);

/*  
  // Fresnel
  const float fresnelBias=0; //0.2;
  const float fresnelScale=1.0; //0.9
  const float fresnelPower=2.0; //4.0;
  I=normalize(I);
  float dotIN=dot(I,N);
  // Avoid sharp edges
//  dotIN=min(dotIN,0.2);
//  dotIN=max(dotIN,-0.2);
  OUT.fresnel=fresnelBias+fresnelScale*pow(1.0+dotIN,fresnelPower);
//OUT.fresnel=pow(1+dotIN,fresnelPower);
//OUT.fresnel=N; //dotIN;
*/

  // Fresnel in pixel shader (pixely effects when done in VS)
  OUT.I=I;
  
/*
  // Reflection (dynamic)
  float3 posW=mul(modelMatrix,IN.Position).xyz;
  float3 I=posW-eyePosW;
  float3 Nwc=mul((float3x3)modelMatrix,IN.normal);
  R=reflect(I,Nwc);
*/
}
