
#define MAX_INSTRUCTIONS 960
#define USE_NORMALMAP
#define EXTRA_LIGHT

varying vec3 Vnormal;
varying vec3 pos;
varying vec3 view;
varying vec4 camn;

uniform sampler2D noiseTex;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform float tex2CoordMul;
uniform float time;
uniform vec3 light;
uniform vec3 camera;
uniform vec3 camdir;

const float mul = 8.0;	// perlin scale
const float mul2 = 16.0;	// perlin scale for ground shadows
const float timeMultiplier = 0.000002;
const float texMul = 1.0/512.0;
const float mid = 0.5;

const float normalDecrease = 120.0;
const float normalExtraMul = 64.0;

//const float ambient = 0.30;


#if MAX_INSTRUCTIONS > 96

	vec3 noiset(vec2 xy) { return texture2D(noiseTex, xy).rgb; }
	vec3 noiset(vec3 xyz) { return texture2D(noiseTex, vec2(xyz.x+xyz.z*17.0, xyz.y+xyz.z*37.0)).rgb; }

	vec3 getCol(vec2 coord, float newTime, float octave) {
		return //noiset(vec3(coord*octave*0.0078125, newTime))*128.0+
		       noiset(vec3(coord*octave*0.015625, newTime))*64.0+
		       //noiset(vec3(coord*octave*0.03125, newTime))*32.0+
		       noiset(vec3(coord*octave*0.0625, newTime))*16.0+
		       //noiset(vec3(coord*octave*0.125, newTime))*8.0+
		       noiset(vec3(coord*octave*0.25, newTime))*4.0+
		       //noiset(vec3(coord*octave*0.5, newTime))*2.0+
		       noiset(vec3(coord*octave, newTime));

	}

	float getHeight(vec2 coord, float time) {
		return clamp(getCol(coord, time, mul2).r, -85.0, 85.0);
	}

	vec3 getDir(vec2 coord, float newTime) {
		float sx = getHeight(vec2(coord.x-texMul, coord.y), newTime) - getHeight(vec2(coord.x+texMul, coord.y), newTime);
		float sy = getHeight(vec2(coord.x, coord.y-texMul), newTime) - getHeight(vec2(coord.x, coord.y+texMul), newTime);
		return normalize(vec3(sx, normalDecrease, sy));
	}

	void main() {
		vec3 Nnormal = Vnormal;
		vec3 normal = Nnormal;

		vec2 coord = vec2(gl_TexCoord[0].xy);
		vec3 normLight = normalize(light);

		float newTime = time*timeMultiplier;

		vec3 col = getCol(coord, newTime, mul);

		col /= 85.0;

		float alpha = 1.0;

#ifdef EXTRA_LIGHT
		vec3 hdir = getDir(vec2(coord.x*normalExtraMul, coord.y*normalExtraMul*4.0), 0.89764);

		vec3 xz = vec3(Nnormal.x, 0.0, Nnormal.z);
		float s = length(xz);
		xz = normalize(xz);
		vec3 zx = vec3(xz.z, 0.0, -xz.x);
		hdir = (hdir*zx)*zx + ((hdir*Nnormal)*Nnormal.y+(hdir*xz)*s)*Nnormal + ((hdir*xz)*Nnormal.y-(hdir*Nnormal)*s)*xz;
#else
		vec3 hdir = Vnormal;
#endif
		float lightMul = dot(hdir, normLight);

		normal.y = clamp((normal.y-0.85)*6.66, 0.0, 1.0);


		float doth = getCol(coord*8.0, 1.0, 1.0).r/85.0;
		vec3 ldot = fract(25.0*pos+9.0*doth+0.15*view);
		ldot *= 1.0-ldot;
		float sparkle = clamp(1.0-4.1*(ldot.x+ldot.y+ldot.z), 0.0, 1.0);
		sparkle = sparkle*sparkle;
		float dotsi = clamp(dot(reflect(-normalize(view), normalize(Nnormal)), camera), 0.0, 1.0);
		sparkle = sparkle*dotsi;
		
		vec3 snCol = vec3(0.425+sparkle, 0.45+sparkle*1.25, 0.475+sparkle*2.0);

		// edge shit
		float shade = max(dot(view, camn.xyz), 0.0);
		shade = clamp(sqrt(shade)*1.5, 0.0, 1.0);
		
		//col = (snCol*(texture2D(tex1, gl_TexCoord[0].xy*8.0)+texture2D(tex2, gl_TexCoord[0].xy*tex2CoordMul)).rgb*(0.5+0.5*lightMul));
		col = snCol+0.5*(texture2D(tex1, gl_TexCoord[0].xy*8.0)+texture2D(tex2, gl_TexCoord[0].xy*tex2CoordMul)).rgb*(0.5+0.5*lightMul);

		// fog
		vec3 fogCol = gl_Fog.color.rgb;

		float fogMix = (gl_Fog.end-gl_FogFragCoord+gl_Fog.start)*gl_Fog.scale;
		fogMix = clamp(fogMix, 0.0, 1.0);

		col = mix(fogCol, shade*col*(0.75+0.25*lightMul), fogMix);

		gl_FragColor = vec4(col, alpha);
	}


#endif