<languageVersion: 1.0;>
kernel LambertNormalMapShader
<
	namespace: "com.away3d";
	vendor: "Away3d";
	version: 1;
	description: "Applies a Lambert (diffuse) shaded lighting effect with support for normal maps.";
>
{
	input image4 diffuse;
	input image3 normalMap;
	input image3 positionMap;
	output pixel4 dst;
	
	parameter float4x4 positionTransformation
	<
		minValue: float4x4(-8000.0);
		maxValue: float4x4(8000.0);
		defaultValue: float4x4(0.0);
	>;
	
	parameter float3 diffuseColor
	<
		minValue: float3(0.0);
		maxValue: float3(1.0);
		defaultValue: float3(1.0);
		description: "The diffuse colour of the light";
	>;
	
	parameter float3 lightPosition
	<
		minValue: float3(-8000.0, -8000.0, -8000.0);
		maxValue: float3(8000.0, 8000.0, 8000.0);
		defaultValue: float3(0.0, 0.0, 0.0);
		description: "The position of the light source";
	>;
	
	parameter float3 ambientColor
	<
		minValue: float3(0.0);
		maxValue: float3(1.0);
		defaultValue: float3(0.0);
		description: "The ambient color of the environment";
	>;
	
	parameter float lightRadius
	<
		defaultValue: float(200.0);
		description: "The radius within the light intensity will be maximum";
	>;
	
	parameter float lightFalloff
	<
		defaultValue: float(1000.0);
		description: "The radius within the light intensity will be maximum";
	>;
	
	parameter float3 objectScale
	<
		defaultValue: float3(1.0);
		description: "The scale of the object, used to correct the light direction";
	>;
	
	void evaluatePixel()
	{
		float3 coord3d = sampleNearest(positionMap, outCoord());
		coord3d.x = coord3d.x*positionTransformation[0][0]+positionTransformation[3][0];
		coord3d.y = coord3d.y*positionTransformation[1][1]+positionTransformation[3][1];
		coord3d.z = coord3d.z*positionTransformation[2][2]+positionTransformation[3][2];
		
		float3 n = normalize(sampleNearest(normalMap, outCoord())-float3(0.5));
		
		float3 lightDir = (lightPosition-coord3d)*objectScale;
		
		float l = length(lightDir);
		float f;
		
		if (lightFalloff < 0.0)
			f = 1.0;
		else
			f = 1.0-min(max((l-lightRadius)/lightFalloff, 0.0), 1.0);
			
		lightDir /= l;
		lightDir.y = -lightDir.y;
		float nDotD = max(-dot(lightDir, n), 0.0);
		
		dst = sampleNearest(diffuse, outCoord());
		dst.xyz = dst.xyz*diffuseColor*nDotD*f+ambientColor*dst.a;
	}
}
