// First fur test shader

#version 130

#pragma vertex_shader

in vec4 vertex;
in vec3 normal;
in vec2 texCoord;
in vec4 colour;

in float offset;

#ifdef SKINNED
in vec4  weights;
in ivec4 indices;
uniform mat4 boneMatrices[84];
#endif


out vec3 norm;
out vec3 texcoord;
out float len;

uniform float layers;
uniform float furLength;
uniform mat4  transform;
uniform float droop;

uniform float time;
uniform mat4 modelMatrix;

void main() {
	vec4 pos = vertex;
	
	#ifdef SKINNED
	vec4 weight = weights;
	ivec4 index = indices;
	vec3 blendPos = vec3(0);
	vec3 blendNorm = vec3(0);
	for(int i=0; i<4; ++i) {
		blendPos  += (boneMatrices[index.x] * vertex).xyz * weight.x;
		blendNorm += mat3(boneMatrices[index.x]) * normal * weight.x;
		weight = weight.yzwx;
		index = index.yzwx;
	}
	pos.xyz = blendPos;
	#endif

	// gl_InstanceID requires GLSL 140, so use a vertex attribute 'offset'
	float val = offset / layers;


	vec3 left = cross(normal, vec3(0,1,0));
	vec3 down = normalize( cross(normal, left) );

	vec3 dir = normalize(normal * (colour.r*0.5+0.5) + down * (val) * droop);

	pos.xyz += dir * furLength * val * colour.r * colour.r;
	gl_Position = transform * pos;

	norm = mat3(modelMatrix) * normal;

	texcoord = vec3(texCoord.xy, val);
	len = colour.r;
}


#pragma fragment_shader

in vec3 norm;
in vec3 texcoord;
in float len;
out vec4 fragment;

uniform sampler2D skin;
uniform sampler2D noiseA;
uniform sampler2D noiseB;


uniform float scale1;	// 4.0
uniform float scale2;	// 8.0
uniform float gradient;
uniform float curve;	// 4.0
uniform float a;		// 0.1
uniform float cv;		// 0.0


float func(float x, float v) { return exp( log(x) * v ); }

void main() {
	
	vec4 diff = texture2D(skin, texcoord.st);
	diff.rgb *= 0.8;

	// Super basic lighting
	vec3 light = vec3(1,1,1);
	float ndotl = dot( normalize(norm), normalize(light) );
	float l = max(ndotl, (ndotl+1)/1.3*0.2+0.1);
	diff.rgb *= l;

	
	// Skin layer
	if(texcoord.z == 0) {
		fragment = diff;
		return;
	}

	if(len < 0.05) discard;		// Bald section

	
	float n0 = texture2D(noiseA, texcoord.xy * scale1).r;
	float n1 = texture2D(noiseB, (texcoord.xy + 0.5) * scale2).r;
	float value = min(n0 + n1, 1.0);

	float k = mix( 1-a, 1, cv);
	float kk = k * curve;
	float v1 = 0.5 * func(value, kk);

	float m = max(0.0, value - 1.0);
	float v2 = 1 - func(1.0 - m, kk);

	float meh = clamp(v2 * 500, 0, 1);
	v2 = v2 * 0.5 + 0.5;

	float aa = (v2 - v1) * meh + v1;
	float b = k * aa - texcoord.z - 0.011;
	if(b < 0) discard;


	//diff.rgb *= value.a;
	diff.rgb *= 1.0 + texcoord.z * len * gradient;

	diff.a = 1.0;
	fragment = diff;
}

