[Vertex shader]

uniform vec3 lightPos;
uniform vec3 camPos;
uniform vec3 scale;

varying vec2 texCoord;
varying vec3 lightVec;
varying vec3 viewVec;
varying vec3 lightCoord;

void main(){
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

	texCoord = gl_MultiTexCoord0.xy;

	vec3 lVec = lightPos - gl_Vertex.xyz;
	lightVec.x = dot(lVec, gl_MultiTexCoord1.xyz);
	lightVec.y = dot(lVec, gl_MultiTexCoord2.xyz);
	lightVec.z = dot(lVec, gl_MultiTexCoord3.xyz);

	vec3 vVec = camPos - gl_Vertex.xyz;
	viewVec.x = dot(vVec, gl_MultiTexCoord1.xyz);
	viewVec.y = dot(vVec, gl_MultiTexCoord2.xyz);
	viewVec.z = dot(vVec, gl_MultiTexCoord3.xyz);

	lightCoord = gl_Vertex.xyz * scale + 0.5;
}


[Fragment shader]

uniform sampler2D Base;
uniform sampler2D Bump;
uniform sampler3D LightVolume;

varying vec2 texCoord;
varying vec3 lightVec;
varying vec3 viewVec;
varying vec3 lightCoord;

void main(){
	float atten = 1.0 / (1.0 + 0.000002 * dot(lightVec, lightVec));

	vec3 lVec = normalize(lightVec);
	vec3 vVec = normalize(viewVec);

	vec4 base = texture2D(Base, texCoord);
	vec3 bump = texture2D(Bump, texCoord).xyz * 2.0 - 1.0;

	float shadow = texture3D(LightVolume, lightCoord).x;

	bump = normalize(bump);

	float diffuse = saturate(dot(lVec, bump));
	float specular = pow(saturate(dot(reflect(-vVec, bump), lVec)), 24.0);

	gl_FragColor = 0.1 * base + (diffuse * base + 0.5 * specular) * atten * shadow;
}
