float waterH(vec3 pos) {

	float noise = 0.0;

	vec2 wind = vec2(frameTimeCounter) * 3.0 * WATER_SPEED;

	noise += texture2D(noisetex, (pos.xz + wind * 0.1 + pos.y) / 2048.0).r;
	noise += texture2D(noisetex, (pos.xz - wind * 0.2 + pos.y) / 2048.0 * 2).r;
	noise -= texture2D(noisetex, (pos.xz + wind * 0.3 + pos.y) / 2048.0 * 4).r;
	noise += texture2D(noisetex, (pos.xz - wind * 0.1 + pos.y) / 2048.0 * 6).r;
	noise -= texture2D(noisetex, (pos.xz + wind * 0.2 + pos.y) / 2048.0 * 11).r;

	return noise;
}

float getCausticWaves(vec3 posxz) {

	float deltaPos = 0.1;
	float caustic_h0 = waterH(posxz);
	float caustic_h1 = waterH(posxz + vec3(deltaPos, 0.0, 0.0));
	float caustic_h2 = waterH(posxz + vec3(- deltaPos, 0.0, 0.0));
	float caustic_h3 = waterH(posxz + vec3(0.0, 0.0, deltaPos));
	float caustic_h4 = waterH(posxz + vec3(0.0, 0.0, - deltaPos));

	float caustic = Max0((1.0 - abs(0.5 - caustic_h0)) * (1.0 - (abs(caustic_h1 - caustic_h2) + abs(caustic_h3 - caustic_h4))));
	caustic = Max0(pow(caustic, 10)) * 2.0;

	return caustic;
}

vec3 GetCaustics(vec3 albedo, vec3 worldPos, vec3 cameraPosition, vec3 shadow, float skyLightMap, float lightmapX) {

	float FinalLight = 0.0;
	float causticfactor = 80.0 * (1.0 - pow(skyLightMap, 0.5)) * (1.0 - lightmapX * 0.8);
	causticfactor *= 0.1 + 0.9 * pow(skyLightMap, 0.5) * (1.0 - rainStrengthS + 0.05);

	#ifdef OVERWORLD
		vec3 causticcol = sqrt(rawWaterColor.rgb + vec3(0.001));
	#endif

	#ifdef END
		vec3 causticcol = sqrt(endColSqrt3.rgb + vec3(0.001));
	#endif

	vec3 causticpos = worldPos.xyz + cameraPosition.xyz;
	float caustic = getCausticWaves(causticpos);
	vec3 lightcaustic = 2.0 * caustic * causticfactor * causticcol * shadow;

	lightcaustic *= shadowFade;

	albedo.rgb *= 0.20 + lightmapX * 0.80;
	vec3 albedoWithWater = (albedo.rgb * rawWaterColor.rgb);
	albedo.rgb += (1.0 - lightmapX) * albedoWithWater;

	#ifdef SHADOW_COLOR
		albedo.rgb += albedoWithWater * shadowFade * shadow;
	#endif

	albedo.rgb *= 1.0 + lightcaustic;

	return albedo.rgb;
}