#extension GL_ARB_texture_rectangle : enable

uniform sampler2D noiseMap;
uniform sampler2D pgmlandMap;
uniform sampler2D pgmlandMap_tu5;

uniform vec2 pgmlandMapWH;

//uniform sampler2D hMap;
//uniform sampler2DRect hMap;
uniform sampler3D wave3D;
uniform float slice_nr;


/*
//Projgrid
uniform vec4 isect_mm;
uniform vec4 isect_pm;
uniform vec4 isect_pp;
uniform vec4 isect_mp;
*/


// PGM     //

uniform vec4 camPos;
uniform vec4 camDirX;
uniform vec4 camDirY;
uniform vec4 camDirZ;

uniform float ratio;

uniform float hScale;

uniform float hOffset;

uniform vec2 texLookupScale;

//uniform float texW;
//uniform float texH;

uniform float waveScale;
uniform float waveOff;

vec2 texCoords;
// PGM END //


uniform float pot;

varying vec4 terrain_pos;

uniform float pgmland_xcnt_inv;

//
void main1()
//void main()
{
  vec4 worldPos;

  terrain_pos.xyzw/terrain_pos.w;
  /*
  mix(mix(corners[0],corners[2], gl_TexCoord[0].y), 
      mix(corners[1],corners[3], gl_TexCoord[0].y), gl_TexCoord[0].x);
  */
  


  // worldPos.xyzw /= worldPos.w;
  

  //  texCoords = texLookupScale.st*worldPos.xz;
  texCoords = texLookupScale.st*terrain_pos.xz;

  //  worldPos.y = texture2D(pgmlandMap, texCoords).r * hScale;
  //  worldPos.y = texture3D(wave3D, vec3(texCoords.xy, 12.0*(slice_nr/16.0))).r * waveScale + waveOff;

  terrain_pos.y = texture2D(pgmlandMap, texCoords).r * hScale;

  //  gl_FragColor = worldPos;
  //  gl_FragColor = vec4(worldPos.xyz, 1.0);

  //  gl_FragColor = vec4(terrain_pos.xyz/terrain_pos.w, 1.0);
  //
  gl_FragColor = vec4(terrain_pos.xyz, 1.0);
}

/*
void main_new()
{
  vec4 hPos =
  mix(mix(corners[0],corners[2], gl_TexCoord[0].y), 
      mix(corners[1],corners[3], gl_TexCoord[0].y), gl_TexCoord[0].x);

  vec3 worldPos = hPos.xyz / hPos.w;

  texCoords = texLookupScale.st*worldPos.xz;

  //float wh = texture2DLod(pgmlandMap, texCoords, 2.0).r * hScale;
  worldPos.y = texture3D(wave3D, vec3(texCoords.xy, 12.0*(slice_nr/16.0))).r * waveScale + waveOff;

  gl_FragColor = vec4(worldPos, 1.0);
  
}
*/


 /**
/////////////////////////////////////////////////////////////////////////////
/////// Version 2 ///////
	  
	  	float wh_l0 = texture2D(pgmlandMap, texCoords, bias).r; 
	
	float wh_l1 = texture2D(pgmlandMap, texCoords+vec2(texLookupScale.s, 0.0), bias).r; 
	float wh_l2 = texture2D(pgmlandMap, texCoords-vec2(texLookupScale.s, 0.0), bias).r; 
	float wh_l3 = texture2D(pgmlandMap, texCoords+vec2(0.0, texLookupScale.t), bias).r; 
	float wh_l4 = texture2D(pgmlandMap, texCoords-vec2(0.0, texLookupScale.t), bias).r; 
	
	//	wh_l0 = mix(wh_l0, (wh_l1 + wh_l2 + wh_l3 + wh_l4)*0.25, 0.25);
	
	wh_l0 = (wh_l0 + wh_l1 + wh_l2 + wh_l3 + wh_l4)*0.2;

	//automatic mipmap ("fine enough")
	wh = texture2D(pgmlandMap, texCoords).r;

	float wh1 = texture2D(pgmlandMap, texCoords+vec2(texLookupScale.s, 0.0)).r;
	float wh2 = texture2D(pgmlandMap, texCoords-vec2(texLookupScale.s, 0.0)).r;
	float wh3 = texture2D(pgmlandMap, texCoords+vec2(0.0, texLookupScale.t)).r;
	float wh4 = texture2D(pgmlandMap, texCoords-vec2(0.0, texLookupScale.t)).r;

	wh = (wh + wh1 + wh2 + wh3 + wh4)*0.2;

	wh = mix(wh, wh_l0, 0.8);

	wh*=hScale;

	  
/////// Version 2 ///////
/////////////////////////////////////////////////////////////////////////////
**/



//void main_old() 
//
void main() 
{

  //safety "overlap"

  //uniform tesselation in screen-space
  //! vec4 tmp = vec4((gl_TexCoord[0].s-0.5)*2.005, (gl_TexCoord[0].t-0.5)*-2.005, -1.0, 0.0);

  // vec4 tmp = vec4((gl_TexCoord[0].s-0.5)*2.0, (gl_TexCoord[0].t-0.5)*-2.0, -1.0, 0.0);

  //non-uniform tesselation in screen-space
  //  float pot = 1.5;
  //  float pot = 2.5;
  //!  float pot = 2.75;
  //  float pot = 3.0;
  //  float pot = 5.0;
  //  float pot = 6.0;
  //  float pot = 10.0;


  //  float pot = 3.0*max(0.166, (1.0-(pow(camDirZ.y, 2.0))));
  ///  float pot = 3.0*max(0.2, (1.0-(pow(camDirZ.y-.5, 2.0))));

  // non-uniform in y
  //  vec4 tmp = vec4((gl_TexCoord[0].s-0.5)*2.0, (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);

  // non-uniform in x & y
  float vz = (gl_TexCoord[0].s-0.5)*2.005;
  //  float pos_neg_factor = ((vz<0.0)?-1.0:1.0);
  float pos_neg_factor = ((vz<0.0)?0.0:1.0);

  //  float nonlinear = sin(abs(vz)*3.1415*0.5);
  //
  float nonlinear = abs(vz);
  float nonlin_pot = 2.0;
  float nonlin_val = abs(pow( nonlinear, nonlin_pot));


  //if 0.5*abs(vz) it's like having a doubled grid-resolution in x-dir
  // float lin_step = 0.6*abs(vz);
 float lin_step = 0.5*abs(vz);

  //  float lin_step = 50.0*pgmland_xcnt_inv*abs(vz);
  //  float lin_step = 0.25*pgmland_xcnt_inv*abs(vz);
  //  float lin_step = 0.125*abs(vz);
  //  float lin_step = 0.05*abs(vz);

  float for_pos = max( +nonlin_val, +lin_step);
  float for_neg = min( -nonlin_val, -lin_step);

  float for_x = mix(for_neg, for_pos, pos_neg_factor);
  vec4 tmp = vec4( for_x, (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);

  ///  vec4 tmp = vec4( max(pow( abs(vz), 2.5), 10.0*pgmland_xcnt_inv*abs(vz))*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);

  // vec4 tmp = vec4( sin( abs(vz)*3.1415*0.5)*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);
  //vec4 tmp = vec4( pow( abs(vz), 1.5)*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);
  //  vec4 tmp = vec4(vz, (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);
  //  vec4 tmp = vec4( max(pow( abs(vz), 6.0), 0.5*pgmland_xcnt_inv)*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);

  //  vec4 tmp = vec4( pow( sin(abs(vz)*3.1415*0.5), 2.0)*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);
  //  vec4 tmp = vec4( max(pow( abs(vz), 6.0), 0.5*pgmland_xcnt_inv)*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);
  //  vec4 tmp = vec4( pow( sin(abs(vz)*3.1415*0.5), 1.25)*((vz<0.0)?-1.0:1.0), (pow(gl_TexCoord[0].t,pot)-0.5)*-2.0, -1.0, 0.0);


  //vec4 tmp = vec4((gl_TexCoord[0].s-0.5)*1.7505, (gl_TexCoord[0].t-0.5)*-1.7505, -1.0, 0.0);

  //vec4 tmp = vec4((gl_TexCoord[0].s-0.5)*1.005, (gl_TexCoord[0].t-0.5)*-1.005, -1.0, 0.0);

  vec4 Gij = max(ratio,1.0)*tmp.x*camDirX + max((1.0/ratio),1.0)*tmp.y*camDirY + tmp.z*camDirZ;

  /// 
 float t = ((camPos.y )/(- Gij.y));
   ///  float t = ((camPos.y)/( -hOffset/hScale - Gij.y));

  //  if(t>0.0)  //not necessary - auxCam fixed
    {
      vec4 Pij = camPos + t * (Gij);

	Pij.w=1.0;
	
	//ORIG
	texCoords = vec2(texLookupScale.s*Pij.x, texLookupScale.t*Pij.z);

	

	//fetch data from 16bit per sample single channel heightmap texture

	//float wh = texture3D(wave3D, vec3(texCoords.xy, 12.0*(slice_nr/16.0))).r * waveScale + waveOff + 30.0;


	float wh;

	//access a coarser lod, than automatically calculated through "bias"
	//	float bias = 1.0;
	float bias = 1.0;





	/*
	wh = mix(wh_l0, texture2D(pgmlandMap, texCoords).r, .25);
	wh*=hScale;
	*/


/////////////////////////////////////////////////////////////////////////////
/////// Version 1.4.2 ///////

bias = 0.75;

//float lf = 0.5;
 float lf = 0.75;

	  vec2 dx = vec2(lf/pgmlandMapWH.s, 0.0);
	  vec2 dz = vec2(0.0, lf/pgmlandMapWH.t);
	 
	float wh_l0 = texture2D(pgmlandMap, texCoords).r; 
	float wh_l1 = texture2D(pgmlandMap, texCoords+dx).r; 
	float wh_l2 = texture2D(pgmlandMap, texCoords-dx).r; 
	float wh_l3 = texture2D(pgmlandMap, texCoords+dz).r; 
	float wh_l4 = texture2D(pgmlandMap, texCoords-dz).r; 


	float bf = 1.25/lf;
	       
	float wh0 = texture2D(pgmlandMap, texCoords, bias).r;

	// save tex fetches
	//	float wh1 = texture2D(pgmlandMap, texCoords+dx*bf, bias).r;
	//	float wh2 = texture2D(pgmlandMap, texCoords-dx*bf, bias).r;
	//	float wh3 = texture2D(pgmlandMap, texCoords+dz*bf, bias).r;
	//	float wh4 = texture2D(pgmlandMap, texCoords-dz*bf, bias).r;

	
	//	wh = (wh1 + wh2 + wh3 + wh4)*.25;
	//	wh = mix(wh0, wh, 0.4);

	//	wh1 = (wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25;
	//	wh_l0 = mix(wh_l0, wh1, 0.4);
	wh_l1 = (wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25;
	wh_l0 = mix(wh_l0, wh_l1, 0.4);


	// wh = mix(wh_l0, wh, 0.4);
	wh = mix(wh_l0, wh0, 0.4);


 wh *= hScale;


/////// Version 1.4.2 ///////
/////////////////////////////////////////////////////////////////////////////

	/*	
/////////////////////////////////////////////////////////////////////////////
/////// Version 1.4 ///////

bias = 0.5;

	  //  float lf = 0.5;
	  float lf = 0.5;

	  vec2 dx = vec2(lf/pgmlandMapWH.s, 0.0);
	  vec2 dz = vec2(0.0, lf/pgmlandMapWH.t);
	 
	float wh_l0 = texture2D(pgmlandMap, texCoords).r; 
	float wh_l1 = texture2D(pgmlandMap, texCoords+dx).r; 
	float wh_l2 = texture2D(pgmlandMap, texCoords-dx).r; 
	float wh_l3 = texture2D(pgmlandMap, texCoords+dz).r; 
	float wh_l4 = texture2D(pgmlandMap, texCoords-dz).r; 


	//	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	//	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;


	float bf = 1.25/lf;
	       
	float wh0 = texture2D(pgmlandMap, texCoords, bias).r;
	float wh1 = texture2D(pgmlandMap, texCoords+dx*bf, bias).r;
	float wh2 = texture2D(pgmlandMap, texCoords-dx*bf, bias).r;
	float wh3 = texture2D(pgmlandMap, texCoords+dz*bf, bias).r;
	float wh4 = texture2D(pgmlandMap, texCoords-dz*bf, bias).r;

	// wh = (wh1 + wh2 + wh3 + wh4)*.25;
	// wh = mix(wh0, wh, 0.35);
	
// wh = (wh0 + wh1 + wh2 + wh3 + wh4)*.2;
// wh_l0 = (wh_l0 + wh_l1 + wh_l2 + wh_l3 + wh_l4)*.2;
	
	wh = (wh1 + wh2 + wh3 + wh4)*.25;
	wh = mix(wh0, wh, 0.4);

	wh1 = (wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25;
	wh_l0 = mix(wh_l0, wh1, 0.4);


 wh = mix(wh_l0, wh, 0.4);
 wh *= hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;

/////// Version 1.4 ///////
/////////////////////////////////////////////////////////////////////////////
*/


	/*
/////////////////////////////////////////////////////////////////////////////
/////// Version 1.3 ///////
	  vec2 dx = vec2(1.0/pgmlandMapWH.s, 0.0);
	  vec2 dz = vec2(0.0, 1.0/pgmlandMapWH.t);

	  Gij.xyz = normalize(Gij.xyz);

	  dx*=Gij.x;
	  dz*=Gij.z;

	 
	float wh_l0 = texture2D(pgmlandMap, texCoords).r; 
	float wh_l1 = texture2D(pgmlandMap, texCoords+dx).r; 
	float wh_l2 = texture2D(pgmlandMap, texCoords-dx).r; 
	float wh_l3 = texture2D(pgmlandMap, texCoords+dz).r; 
	float wh_l4 = texture2D(pgmlandMap, texCoords-dz).r; 


	//	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	//	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;



	       
	float wh0 = texture2D(pgmlandMap, texCoords, bias).r;
	float wh1 = texture2D(pgmlandMap, texCoords+dx, bias+Gij.x).r;
	float wh2 = texture2D(pgmlandMap, texCoords-dx, bias+Gij.x).r;
	float wh3 = texture2D(pgmlandMap, texCoords+dz, bias+Gij.z).r;
	float wh4 = texture2D(pgmlandMap, texCoords-dz, bias+Gij.z).r;

	


 
 // wh = mix((wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25, (wh1 + wh2 + wh3 + wh4)*.25, 0.4)*hScale;
	// wh = (wh1 + wh2 + wh3 + wh4)*.25;
 // wh = mix(wh0, wh, 0.35);
	
// wh = (wh0 + wh1 + wh2 + wh3 + wh4)*.2;
// wh_l0 = (wh_l0 + wh_l1 + wh_l2 + wh_l3 + wh_l4)*.2;
	
	wh = (wh1 + wh2 + wh3 + wh4)*.25;
	wh = mix(wh0, wh, 0.35);

	wh1 = (wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25;
	wh_l0 = mix(wh_l0, wh1, 0.35);


 wh = mix(wh_l0, wh, 0.4);
 wh *= hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;

/////// Version 1.3 ///////
/////////////////////////////////////////////////////////////////////////////
*/


	/*
/////////////////////////////////////////////////////////////////////////////
/////// Version 1.2 ///////
	 
	float wh_l0 = texture2D(pgmlandMap, texCoords).r; 

	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;



	       
	float wh1 = texture2D(pgmlandMap, texCoords+vec2(1.0/pgmlandMapWH.s, 0.0), bias).r;
	float wh2 = texture2D(pgmlandMap, texCoords-vec2(1.0/pgmlandMapWH.s, 0.0), bias).r;
	float wh3 = texture2D(pgmlandMap, texCoords+vec2(0.0, 1.0/pgmlandMapWH.t), bias).r;
	float wh4 = texture2D(pgmlandMap, texCoords-vec2(0.0, 1.0/pgmlandMapWH.t), bias).r;

	


 
 // wh = mix((wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25, (wh1 + wh2 + wh3 + wh4)*.25, 0.4)*hScale;
 wh = (wh1 + wh2 + wh3 + wh4)*.25;
 wh = mix(wh_l0, wh, 0.2)*hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;

/////// Version 1.2 ///////
/////////////////////////////////////////////////////////////////////////////
*/

	/*
/////////////////////////////////////////////////////////////////////////////
/////// Version 1.1 ///////
	 
	float wh_l0 = texture2D(pgmlandMap, texCoords, bias).r; 

	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;



	       
 float wh1 = texture2D(pgmlandMap, texCoords+vec2(1.0/pgmlandMapWH.s, 0.0)).r;
 float wh2 = texture2D(pgmlandMap, texCoords-vec2(1.0/pgmlandMapWH.s, 0.0)).r;
 float wh3 = texture2D(pgmlandMap, texCoords+vec2(0.0, 1.0/pgmlandMapWH.t)).r;
 float wh4 = texture2D(pgmlandMap, texCoords-vec2(0.0, 1.0/pgmlandMapWH.t)).r;

	


 
 // wh = mix((wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25, (wh1 + wh2 + wh3 + wh4)*.25, 0.4)*hScale;
 wh = (wh1 + wh2 + wh3 + wh4)*.25;
 wh = mix(wh_l0, wh, 0.2)*hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;

/////// Version 1.1 ///////
/////////////////////////////////////////////////////////////////////////////
*/



	/*	
/////////////////////////////////////////////////////////////////////////////
/////// Version 1 ///////
	 
	float wh_l0 = texture2D(pgmlandMap, texCoords, bias).r; 

	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;



       
 float wh1 = texture2D(pgmlandMap, texCoords+vec2(texLookupScale.s, 0.0)).r;
 float wh2 = texture2D(pgmlandMap, texCoords-vec2(texLookupScale.s, 0.0)).r;
 float wh3 = texture2D(pgmlandMap, texCoords+vec2(0.0, texLookupScale.t)).r;
 float wh4 = texture2D(pgmlandMap, texCoords-vec2(0.0, texLookupScale.t)).r;
	


 
 // wh = mix((wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25, (wh1 + wh2 + wh3 + wh4)*.25, 0.4)*hScale;
 wh = (wh1 + wh2 + wh3 + wh4)*.25;
 wh = mix(wh_l0, wh, 0.2)*hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;

/////// Version 1 ///////
/////////////////////////////////////////////////////////////////////////////
*/

	/*	
/////////////////////////////////////////////////////////////////////////////
/////// Version 1.5 ///////
	 
	float wh_l0 = texture2D(pgmlandMap, texCoords, bias).r; 

	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;



       
	// float wh1 = texture2D(pgmlandMap, texCoords+vec2(texLookupScale.s, 0.0)).r;
	// float wh2 = texture2D(pgmlandMap, texCoords-vec2(texLookupScale.s, 0.0)).r;
	// float wh3 = texture2D(pgmlandMap, texCoords+vec2(0.0, texLookupScale.t)).r;
	// float wh4 = texture2D(pgmlandMap, texCoords-vec2(0.0, texLookupScale.t)).r;

	float wh1 = texture2D(pgmlandMap, texCoords).r;
	


 
 // wh = mix((wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25, (wh1 + wh2 + wh3 + wh4)*.25, 0.4)*hScale;
	// wh = (wh1 + wh2 + wh3 + wh4)*.25;
	wh = wh1;
 wh = mix(wh_l0, wh, 0.2)*hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;

/////// Version 1.5 ///////
/////////////////////////////////////////////////////////////////////////////
*/


 ///wh -= 200.0;
   ////
wh += hOffset;

	//
	gl_FragColor = vec4(Pij.x, wh, Pij.z, 1.0);
	//	gl_FragColor = vec4(texCoords.x, wh, texCoords.z, 1.0);

    }

}










  /*
void main(void)
{
  vec4 hPos =
  mix(mix(isect_mm, isect_mp, gl_TexCoord[0].y), 
      mix(isect_pm, isect_pp, gl_TexCoord[0].y), gl_TexCoord[0].x);

  //perform perspective divide
  // => yields the worldspace position in real coordinates
  vec3 worldPos = hPos.xyz / hPos.w;

  texCoords = texLookupScale.st * worldPos.xz;


  float wh;

  //access a coarser lod, than automatically calculated through "bias"
  float bias = 1.0;


	float wh_l0 = texture2D(pgmlandMap, texCoords, bias).r; 

	float wh_l00 = texture2D(pgmlandMap, texCoords, bias+0.5).r; 
	wh_l0 = 0.7*wh_l0 + 0.3*wh_l00;



	
 float wh1 = texture2D(pgmlandMap, texCoords+vec2(texLookupScale.s, 0.0)).r;
 float wh2 = texture2D(pgmlandMap, texCoords-vec2(texLookupScale.s, 0.0)).r;
 float wh3 = texture2D(pgmlandMap, texCoords+vec2(0.0, texLookupScale.t)).r;
 float wh4 = texture2D(pgmlandMap, texCoords-vec2(0.0, texLookupScale.t)).r;
	


 
 // wh = mix((wh_l1 + wh_l2 + wh_l3 + wh_l4)*.25, (wh1 + wh2 + wh3 + wh4)*.25, 0.4)*hScale;
 wh = (wh1 + wh2 + wh3 + wh4)*.25;
 wh = mix(wh_l0, wh, 0.2)*hScale;

 //wh = texture2D(pgmlandMap, texCoords, 3.0).r*hScale;


/////// Version 1 ///////
/////////////////////////////////////////////////////////////////////////////




 ///wh -= 200.0;
wh += hOffset;

 worldPos.y = wh;
	//
	gl_FragColor = vec4(worldPos, 1.0);

}
  */
