/** Some utility functions for all shaders to use */

#define ALPHA_TEST_THRESHOLD (0.2)

// Scales a value from range [-1, 1] to [0, 1]
float compress(float a)
{
	return (1.0+a)*0.5;
}

vec3 compressv3(vec3 v)
{
	return (vec3(1.0)+v)*0.5;
}

vec3 decompressv3(vec3 compressed_v)
{
	return vec3(-1.0) + 2.0*compressed_v;
}

float scaleSpecular(float spec) {
	return spec/1000.0;
}

float unscaleSpecular(float spec) {
	return spec*1000.0;
}

float noise(vec3 pos) {
	return fract(9992.41*cos(10.9*(pos.x*19.9+pos.y*15.1+pos.z*1.97)));
}

vec2 camshake(float t) {
	return vec2((pow(1.0+sin(t*3.11), 1.3)-.5) * (0.2 + 0.2*cos(t*2.31)), 
	(pow(1.0+sin(t*4.0), 1.5)-.5) * (0.2 + 0.2*sin(t*1.4)));
}

// http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
    vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

// Would a macro suffice too?
float saturate(float x) {
	return clamp(x, 0.0, 1.0);
}