//
// constants.cg
// 03-12-2009: Created
// All constants that are being used in shaders should be defined in here
//

#ifndef __COMMON_CONSTANTS_CG
#define __COMMON_CONSTANTS_CG

//
// Predefined by Racer:
// -DFAST        = cut some corners in the shaders to go faster
// -DCSM         = shadow mapping turned on
// -DCSM_BLUR    = blurring in shadow map
// -DATI         = ATI card; avoids loops etc
// -DREVERSED_Z  = depth buffer reversal (hardcoded currently)
// -DTEXDMG_CHANGE_VERTES = texture damage option
//

// Store log(z) in depth buffer, instead of regular value? Vertex shader
#define USE_LOG_Z_VS
// Write Log Z in fragment shader? (instead of the default pos.z)
// This does not seem to make a difference; the vertex shader appears
// to do all the grunt work, and writing Z just takes up valuable time
// (and prohibit early-out optimizations when fragment shaders start redefining Z).
//#define USE_LOG_Z_FS
// Use Log Z in shadowmapping?
//#define USE_LOG_Z_SHADOWMAPPING

// Bloom amount
const float bloomFactor=1.0;

// Gamma adjustment for some tonemappers (check hdr.cg)
// Values >1 make the image more contrasty, <1 is less contrast. A bit personal.
const float gammaFactor=1.25;

// Early out alpha - below this alpha, some shaders will discard
// the pixel before doing any further calculations
const float alphaThreshold=0.01;

// Shadow mapping
#define SM_MAX_SPLITS   4
#define PCF_NUM_SAMPLES 16
const float shadowMapSize=512.0;            // Should be the same as in racer.ini (renderer.shadowmapping.profile<n>.mapsize)
const int   iSqrtSamples=2;                 // Sample quality, should be 2,4,6...etc 2 or 4 is recommended

// Z correction for cameras (to avoid acne)
//const float smCor[SM_MAX_SPLITS]=  { 0.000017,0.000065,0.00025,0.001 };     // For 1830, profile0 (splitdist0=10)
//const float smCor[SM_MAX_SPLITS]=  { 0.00004,0.00017,0.00055,0.001 };     // For 1830
const float smCor[SM_MAX_SPLITS]=  { 0.0012,0.005,0.0075,0.028 };     // For 1830
//const float smCor[SM_MAX_SPLITS]=  { -0.1,-0.1,-0.1,-0.1};     // For 1830
//const float smCor[SM_MAX_SPLITS]=  { 0.00004,0.000065,0.00025,0.001 };     // For 1830

// blur filter kernel radius for PCF
//const float filterRadiusUV=2.0f/1024f;

// PCF samples for each split of sd map, max=16
//const int PCFSamples[SM_MAX_SPLITS]={16,8,4,1};

// Fake penumbra coefficient, 1= uniform blur, >1= scale the blur along the light direction
//const float penumbraCoe = 4.0f;

// 16 tap poisson disk distribution
const float2 poissonDisk[16]=
{
  float2( -0.94201624, -0.39906216 ),
  float2( 0.94558609, -0.76890725 ),
  float2( -0.094184101, -0.92938870 ),
  float2( 0.34495938, 0.29387760 ),
  float2( -0.91588581, 0.45771432 ),
  float2( -0.81544232, -0.87912464 ),
  float2( -0.38277543, 0.27676845 ),
  float2( 0.97484398, 0.75648379 ),
  float2( 0.44323325, -0.97511554 ),
  float2( 0.53742981, -0.47373420 ),
  float2( -0.26496911, -0.41893023 ),
  float2( 0.79197514, 0.19090188 ),
  float2( -0.24188840, 0.99706507 ),
  float2( -0.81409955, 0.91437590 ),
  float2( 0.19984126, 0.78641367 ),
  float2( 0.14383161, -0.14100790 )
};

// Math
const float deg2rad=57.2957795785523;

// Utilities used by many shaders
// 'zFar' should match racer.ini's fx.visibility
const float zFar=1000.0;
//const float zFar=50000.0;

float LogZ(float4 pos,float far)
// Converts linear Z to logarithmic Z.
// 'pos' is the position after multiplying with the projection matrix (or MVP)
// This trickery can be used in vertex shader to modify Z values
// being stored in the depth buffer, giving the option to massively
// increase the far plane (to for example 100 KM) without
// getting Z-fighting.
// See http://outerra.blogspot.nl/2012/11/maximizing-depth-buffer-range-and.html
{
#ifdef USE_LOG_Z_VS
  // Reduce C towards 0 to decrease near-polygon clipping
  //const float C=0.001;
  const float C=1.0;

  // From http://outerra.blogspot.nl/2012/11/maximizing-depth-buffer-range-and.html
  // Actually, 'logz' should be returned as well and written in the fragment shader
  // as 'gl_FragDepth=logz'.
  const float FC=1.0/log(zFar*C+1);
  float logz=log(pos.w*C + 1)*FC;
  return (2*logz-1)*pos.w;
#else
  return pos.z;
#endif
}

float LogZ2(float4 pos,float far,out float4 posOut)
// Converts linear Z to logarithmic Z.
// 'pos' is the position after multiplying with the projection matrix (or MVP)
// This trickery can be used in vertex shader to modify Z values
// being stored in the depth buffer, giving the option to massively
// increase the far plane (to for example 100 KM) without
// getting Z-fighting.
// See http://outerra.blogspot.nl/2012/11/maximizing-depth-buffer-range-and.html
{
#ifdef USE_LOG_Z_VS
  // Reduce C towards 0 to decrease near-polygon clipping
  const float C=0.001;
  //const float C=0.001;
  //const float C=1.0;

//posOut=pos;
  // From http://outerra.blogspot.nl/2012/11/maximizing-depth-buffer-range-and.html
  // Actually, 'logz' should be returned as well and written in the fragment shader
  // as 'gl_FragDepth=logz'.
  const float FC=1.0/log(zFar*C+1.0);
//return FC;
  float logz=log(pos.w*C + 1.0)*FC;
//return (pos.w/pos.z);
//return (pos.w-pos.z);
//return logz;
  //posOut.z=(2.0*logz-1.0)*pos.w;      // Org; DirectX?
//posOut.z=logz*pos.w;
//posOut.z=pos.w-1;       // MAGIC!
//posOut.z=pos.w-0.1;       // MAGIC!
//posOut.z=logz*pos.w;
//posOut.z=logz*pos.w-0.11;
//posOut.z=logz*(pos.z-0.05);
//posOut.z=logz*pos.z-0.12;
//posOut.z=logz*(pos.z-560);
//posOut.z=pos.z-0.21;
//posOut.z=pos.z;
  posOut.z=pos.w-0.1;       // 0.1 is tuning parameter for near polygons
//posOut.z=logz-0.2;
  //pos.z=(2*logz-1)*pos.w;
  posOut.xyw=pos.xyw;
  // Return value to be written in the Z buffer
  return logz;
#else
  posOut=pos;
  return pos.z;
#endif
}

#ifdef ND_OLD
float LogZ2_org(float4 pos,float far,out float4 posOut)
// Converts linear Z to logarithmic Z.
// 'pos' is the position after multiplying with the projection matrix (or MVP)
// This trickery can be used in vertex shader to modify Z values
// being stored in the depth buffer, giving the option to massively
// increase the far plane (to for example 100 KM) without
// getting Z-fighting.
// See http://outerra.blogspot.nl/2012/11/maximizing-depth-buffer-range-and.html
{
#ifdef USE_LOG_Z_VS
  // Reduce C towards 0 to decrease near-polygon clipping
  const float C=0.001;
  //const float C=0.001;
  //const float C=1.0;

  // From http://outerra.blogspot.nl/2012/11/maximizing-depth-buffer-range-and.html
  // Actually, 'logz' should be returned as well and written in the fragment shader
  // as 'gl_FragDepth=logz'.
  const float FC=1.0/log(zFar*C+1.0);
  float logz=log(pos.w*C + 1.0)*FC;
  posOut.z=(2.0*logz-1.0)*pos.w;
  posOut.xyw=pos.xyw;
  // Return value to be written in the Z buffer
  return logz;
#else
  posOut=pos;
  return pos.z;
#endif
}
#endif

#endif
