// __multiversion__
// This signals the loading code to prepend either #version 100 or #version 300 es as apropriate.

#include "vertexVersionCentroid.h"
#if __VERSION__ >= 300
	#ifndef BYPASS_PIXEL_SHADER
		_centroid out vec2 uv0;
		_centroid out vec2 uv1;
	#endif
#else
	#ifndef BYPASS_PIXEL_SHADER
		varying vec2 uv0;
		varying vec2 uv1;
	#endif
#endif

#ifndef BYPASS_PIXEL_SHADER
	varying vec4 color;
#endif

#ifdef FOG
	varying vec4 fogColor;
#endif

#include "uniformWorldConstants.h"
#include "uniformPerFrameConstants.h"
#include "uniformShaderConstants.h"
#include "uniformRenderChunkConstants.h"
varying highp vec3 fragment_pos;
varying highp vec3 look_vector;
varying highp vec3 position;
varying highp vec3 look;
varying highp float sunfx;
varying float cont;
varying highp vec4 awn;
	varying float wfog;
   varying vec4 cclr;
	varying float rfog;
	varying float dfog;
   varying float af2;
	varying float af3;
attribute POS4 POSITION;
attribute vec4 COLOR;
attribute vec2 TEXCOORD_0;
attribute vec2 TEXCOORD_1;
uniform highp float TOTAL_REAL_WORLD_TIME;
const float rA = 1.0;
const float rB = 1.0;
const vec3 UNIT_Y = vec3(0,1,0);
const float DIST_DESATURATION = 56.0 / 255.0; //WARNING this value is also hardcoded in the water color, don'tchange

void main()
{
    POS4 worldPos;
#ifdef AS_ENTITY_RENDERER
		POS4 pos = WORLDVIEWPROJ * POSITION;
		worldPos = pos;
#else
    worldPos.xyz = (POSITION.xyz * CHUNK_ORIGIN_AND_SCALE.w) + CHUNK_ORIGIN_AND_SCALE.xyz;
    worldPos.w = 1.0;

    // Transform to view space before projection instead of all at once to avoid floating point errors
    // Not required for entities because they are already offset by camera translation before rendering
    // World position here is calculated above and can get huge
    POS4 pos = WORLDVIEW * worldPos;
    pos = PROJ * pos;
#endif
    gl_Position = pos;

#ifndef BYPASS_PIXEL_SHADER
    uv0 = TEXCOORD_0;
    uv1 = TEXCOORD_1;
	color = COLOR;
#endif

///// find distance from the camera

POS3 wave_pos = POSITION.xyz + VIEW_POS;
highp float t = TOTAL_REAL_WORLD_TIME;

#ifdef ALPHA_TEST
if(COLOR.g > COLOR.b){
float Wave = sin(t * 0.9 + t * 4.1 + wave_pos.y+wave_pos.z+wave_pos.z+wave_pos.y+wave_pos.x) * sin(wave_pos.x) * 0.03;
gl_Position.xy += (Wave) * 1.0;}
#endif

#if defined(FOG) || defined(BLEND)
	#ifdef FANCY
		vec3 relPos = -worldPos.xyz;
		float cameraDepth = length(relPos);
	#else
		float cameraDepth = pos.z;
	#endif
#endif

///// apply fog

#ifdef FOG
	float len = cameraDepth / RENDER_DISTANCE*0.7;
	#ifdef ALLOW_FADE
		len += RENDER_CHUNK_FOG_ALPHA;
	#endif

    fogColor.rgb = FOG_COLOR.rgb;
	fogColor.a = clamp((len - FOG_CONTROL.x) / (FOG_CONTROL.y - FOG_CONTROL.x), 0.0, 0.3);
#endif

///// blended layer (mostly water) magic
#ifdef BLEND
	//Mega hack: only things that become opaque are allowed to have vertex-driven transparency in the Blended layer...
	//to fix this we'd need to find more space for a flag in the vertex format. color.a is the only unused part
	bool shouldBecomeOpaqueInTheDistance = color.a < 0.95;
	if(shouldBecomeOpaqueInTheDistance) {
		#ifdef FANCY  /////enhance water
			float cameraDist = cameraDepth / FAR_CHUNKS_DISTANCE;
			color = COLOR;
		#else
			// Completely insane, but if I don't have these two lines in here, the water doesn't render on a Nexus 6
			vec4 surfColor = vec4(color.rgb, 1.0);
			color = surfColor;
				
			vec3 relPos = -worldPos.xyz;
			float camDist = length(relPos);
			float cameraDist = camDist / FAR_CHUNKS_DISTANCE;
		#endif //FANCY
		
		float alphaFadeOut = clamp(cameraDist, 0.0, 1.0);
		color.a = mix(color.a, 1.0, alphaFadeOut);
	}
#endif

float day_c = pow(max(min(1.0-FOG_COLOR.b * 1.2, 1.0), 0.0), 0.5);
float night_c = pow(max(min(1.0-FOG_COLOR.r * 1.5, 1.0), 0.0), 1.2);
float rain_f = (1.0 - pow(FOG_CONTROL.y, 11.0));

vec4 day = vec4(1.);
vec4 night = vec4(0.2,0.2,0.6,0.7);
vec4 dusk = vec4(0.5,0.5,0.5,1.0)*FOG_COLOR;
vec4 rain = vec4(0.13,0.13,0.13,0.5);

cclr = mix(mix(mix(day, dusk, day_c), night, night_c),rain, rain_f);


cont = length(-worldPos.xyz*1.2) / RENDER_DISTANCE*1.3;

POS3 cam_fix = worldPos.xyz + VIEW_POS;
position = POSITION.xyz + VIEW_POS.xyz;
look = worldPos.xyz;
fragment_pos = cam_fix;
fragment_pos.y += 0.0015;
look_vector = fragment_pos - VIEW_POS;

af2 = length(-worldPos.xyz*0.25)/
FAR_CHUNKS_DISTANCE*0.24;
af3 = length(-worldPos.xyz*0.8)/
RENDER_DISTANCE*0.8;

wfog = length(-worldPos.xyz*1.6)/
FAR_CHUNKS_DISTANCE*1.6;
dfog = length(-worldPos.xyz*2.48)/
FAR_CHUNKS_DISTANCE*4.88;
dfog = clamp(dfog, 0.0, 0.035);

rfog = length(-worldPos.xyz*1.5) / FAR_CHUNKS_DISTANCE*1.5;

af2 = clamp(af2,0.0,0.90);
af3 = clamp(af3,0.0,0.6);
rfog = clamp(rfog, 0.0, 0.9);
wfog = clamp(wfog, 0.0, 0.2);

#ifndef BYPASS_PIXEL_SHADER
	#ifndef FOG
		// If the FOG_COLOR isn't used, the reflection on NVN fails to compute the correct size of the constant buffer as the uniform will also be gone from the reflection data
		color.rgb += FOG_COLOR.rgb * 0.000001;
	#endif
#endif
}
