//
// Standard lighting - static model
// Atmosphere & single texture
//

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

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

// 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;
  float4 normalExtinction     : TEXCOORD6;    // Normal.rgb and extinction in .a
  float3 lightDirTS     : TEXCOORD7;    // Light direction in texture space
  //float3 eyeDirTS       : TEXCOORD8;    // Eye direction in texture space
  float3 eyePosTS       : TEXCOORD5;    // Eye position in texture space
  //float3 test           : TEXCOORD8;    // Bad attrib nr?
};

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,
  uniform float    extinctionFactor
)
{
  float4 MieColor;

  float3 posW;

//OUT.test=float3(1,0,1);  

  // Transform to clipspace
  OUT.Position=mul(modelViewProj,IN.Position);

  // World position
  posW=IN.Position.xyz;
  
  // Atmosphere
  CalculateAtmosphere(atmosRayleigh,atmosMie,sunIntensity,eyePosW,IN.Position,lightDirection,
    OUT.RayleighColor,OUT.MieColor,OUT.Direction);

  // Extinction factor of regular color
  OUT.normalExtinction.a=CalculateAtmosphereExtinction(OUT.Position,atmosRayleigh,atmosMie,extinctionFactor);
  
  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  OUT.normalExtinction.xyz=IN.normal.xyz; //mul((float3x3)modelMatrix, IN.normal);
  //OUT.FPosition=posW; //mul(modelMatrix,IN.Position).xyz;

  // Create coordinate system for object-> texture space
  // Also rotates along with the model (if present)
  float3 t=IN.tangent.xyz;
  float3 n=IN.normal;
  float3 b=cross(t,n);
  
  // Create TBN matrix
  float3x3 tbnMatrix=float3x3(t,b,n);
  
  // Calculate lightDir in tangent space
  OUT.lightDirTS=mul(tbnMatrix,lightDirection);
  
  // Position also in TS
  OUT.FPosition=mul(tbnMatrix,posW);
  
/*
  // Calculate eye direction in tangent space
  float3 eyeDirWC=eyePosW-posW;
  OUT.eyeDir=mul(tbnMatrix,eyeDirWC);
*/
  
  // Calculate eye position in tangent space
  OUT.eyePosTS=mul(tbnMatrix,eyePosW);
}
