// For PPL renderer (r_ppl = 1)

_detailBump.vsh
{
	include bump.vsh
}

_detailBump.fsh
{
	uniform sampler2D	u_ColorMap;
	uniform sampler2D	u_NormalMap;
	uniform sampler2D	u_SpecularMap;
	uniform sampler2D	u_detailNormalMap;
	uniform float		u_detailScale;
	uniform	float		u_Mirror;	// -1.0 for mirrors, else 1.0
	#if defined(ALPHATEST)
		uniform float	u_AlphaTestValue;
	#endif
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
		in	vec3	v_clipVertex;
	#endif
	in	vec2		texCoord;
	in	vec3		Tangent;
	in	vec3		Binormal;
	in	vec3		Normal;
	in	vec4		matColor;
#if defined(FAKE_PPL)
		uniform sampler2D	u_LightMap;
		uniform float		u_useLightMap;
		in	vec2		lmCoord;
		in	vec3		vertexColor;
#endif
	include PackData.inc
	void main(void)
	{
		include clipPlane.inc
		vec4 pix = texture2D(u_ColorMap, texCoord) * matColor;
		include alpha_test.inc
		vec3 spec = texture2D(u_SpecularMap, texCoord).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec4 tn = texture2D(u_NormalMap, texCoord) - vec4(0.5, 0.5, 0.5, 0.0);
		vec4 tdna = texture2D(u_detailNormalMap, texCoord * u_detailScale);
		vec3 tdn = tn.a * (tdna.xyz * vec3(2.0, 2.0, 0.0) - vec3(1.0, 1.0, 0.0));
		vec3 n = tangentToWorldMatrix * normalize(tn.xyz + tdn);
#if defined(FAKE_PPL)
		if (u_useLightMap == 1.0)
			PackData(pix, n, spec * tdna.a, nn, texture2D(u_LightMap, lmCoord).rgb);
		else
			PackData(pix, n, spec * tdna.a, nn, vertexColor);
#else
		PackData(pix, n, spec * tdna.a);
#endif
	}
}


_bump.vsh
{
	include bump.vsh
}

_bump.fsh
{
	uniform sampler2D	u_ColorMap;
	uniform sampler2D	u_NormalMap;
	uniform sampler2D	u_SpecularMap;
	uniform	float		u_Mirror;	// -1.0 for mirrors, else 1.0
	#if defined(ALPHATEST)
		uniform float	u_AlphaTestValue;
	#endif
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
		in	vec3	v_clipVertex;
	#endif
	in	vec2		texCoord;
	in	vec3		Tangent;
	in	vec3		Binormal;
	in	vec3		Normal;
	in	vec4		matColor;
#if defined(FAKE_PPL)
		uniform sampler2D	u_LightMap;
		uniform float		u_useLightMap;
		in	vec2		lmCoord;
		in	vec3		vertexColor;
#endif
	include PackData.inc
	void main(void)
	{
		include clipPlane.inc
		vec4 pix = texture2D(u_ColorMap, texCoord) * matColor;
		include alpha_test.inc
		vec3 spec = texture2D(u_SpecularMap, texCoord).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec3 n = tangentToWorldMatrix * normalize(texture2D(u_NormalMap, texCoord).xyz - 0.5);
#if defined(FAKE_PPL)
		if (u_useLightMap == 1.0)
			PackData(pix, n, spec, nn, texture2D(u_LightMap, lmCoord).rgb);
		else
			PackData(pix, n, spec, nn, vertexColor);
#else
		PackData(pix, n, spec);
#endif
	}
}


_bump_interpolate.vsh
{
	include bump_interpolate.vsh
}

_bump_interpolate.fsh
{
	uniform sampler2D	u_ColorMap0;
	uniform sampler2D	u_ColorMap1;
	uniform sampler2D	u_NormalMap0;
	uniform sampler2D	u_NormalMap1;
	uniform sampler2D	u_SpecularMap0;
	uniform sampler2D	u_SpecularMap1;
	uniform	float		u_Mirror;
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
		in	vec3	v_clipVertex;
	#endif
	in	vec4		texCoords;
	in	vec3		Tangent;
	in	vec3		Binormal;
	in	vec3		Normal;
#if defined(FAKE_PPL)
		uniform sampler2D	u_LightMap;
		uniform float		u_useLightMap;
		in	vec2		lmCoord;
		in	vec4		vertexColor;
#else
		in	float	vertexAlpha;
#endif
	include PackData.inc
	void main(void)
	{
		include clipPlane.inc
		vec3 sample0 = texture2D(u_ColorMap0, texCoords.xy).rgb;
		vec4 sample1 = texture2D(u_ColorMap1, texCoords.zw);
#if defined(FAKE_PPL)
		float alpha = sample1.a * vertexColor.a;
#else
		float alpha = sample1.a * vertexAlpha;
#endif
		vec3 s0 = texture2D(u_SpecularMap0, texCoords.xy).rgb;
		vec3 s1 = texture2D(u_SpecularMap1, texCoords.zw).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec3 n0 = normalize(texture2D(u_NormalMap0, texCoords.xy).xyz - 0.5);
		vec3 n1 = normalize(texture2D(u_NormalMap1, texCoords.zw).xyz - 0.5);
		vec4 c = vec4(mix(sample0, sample1.rgb, alpha), 1.0);
		vec3 n = tangentToWorldMatrix * normalize(mix(n0, n1, alpha));
		vec3 s = mix(s0, s1, alpha);
#if defined(FAKE_PPL)
		if (u_useLightMap == 1.0)
			PackData(c, n, s, nn, texture2D(u_LightMap, lmCoord).rgb);
		else
			PackData(c, n, s, nn, vertexColor.rgb);
#else
		PackData(c, n, s);
#endif
	}
}


_bump_interpolate_at.vsh
{
	include bump_interpolate.vsh
}

_bump_interpolate_at.fsh
{
	uniform sampler2D	u_ColorMap0;
	uniform sampler2D	u_ColorMap1;
	uniform sampler2D	u_NormalMap0;
	uniform sampler2D	u_NormalMap1;
	uniform sampler2D	u_SpecularMap0;
	uniform sampler2D	u_SpecularMap1;
	uniform	float		u_Mirror;
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
		in	vec3	v_clipVertex;
	#endif
	in	vec4		texCoords;
	in	vec3		Tangent;
	in	vec3		Binormal;
	in	vec3		Normal;
#if defined(FAKE_PPL)
		uniform sampler2D	u_LightMap;
		uniform float		u_useLightMap;
		in	vec2		lmCoord;
		in	vec4		vertexColor;
#else
		in	float		vertexAlpha;
#endif
	include PackData.inc
	void main(void)
	{
		include clipPlane.inc
		vec3 sample0 = texture2D(u_ColorMap0, texCoords.xy).rgb;
		vec4 sample1 = texture2D(u_ColorMap1, texCoords.zw);
#if defined(FAKE_PPL)
		float alpha = sample1.a * vertexColor.a;
#else
		float alpha = sample1.a * vertexAlpha;
#endif
		vec3 s0 = texture2D(u_SpecularMap0, texCoords.xy).rgb;
		vec3 s1 = texture2D(u_SpecularMap1, texCoords.zw).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec3 n0 = normalize(texture2D(u_NormalMap0, texCoords.xy).xyz - 0.5);
		vec3 n1 = normalize(texture2D(u_NormalMap1, texCoords.zw).xyz - 0.5);
		alpha *= step(0.5, alpha);
		vec4 c = vec4(mix(sample0, sample1.rgb, alpha), 1.0);
		vec3 n = tangentToWorldMatrix * normalize(mix(n0, n1, alpha));
		vec3 s = mix(s0, s1, alpha);
#if defined(FAKE_PPL)
		if (u_useLightMap == 1.0)
			PackData(c, n, s, nn, texture2D(u_LightMap, lmCoord).rgb);
		else
			PackData(c, n, s, nn, vertexColor.rgb);
#else
		PackData(c, n, s);
#endif
	}
}


_detailBump_parallax.vsh
{
	include parallax.vsh
}


_detailBump_parallax.fsh
{
	uniform sampler2D	u_ColorMap;
	uniform sampler2D	u_HeightMap;
	uniform sampler2D	u_NormalMap;
	uniform sampler2D	u_SpecularMap;
	uniform sampler2D	u_detailNormalMap;
	uniform float		u_detailScale;
	uniform	float		u_Mirror;
	#if defined(ALPHATEST)
		uniform float	u_AlphaTestValue;
	#endif
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
	#endif
	in	vec2	texCoord;
	in	vec3	Tangent;
	in	vec3	Binormal;
	in	vec3	Normal;
	in	vec3	eyeSpaceNormal;
	in	vec3	eyeSpaceVert;
	in	vec4	matColor;
#if defined(FAKE_PPL)
		uniform sampler2D	u_LightMap;
		uniform float		u_useLightMap;
		in	vec2		lmCoord;
		in	vec3		vertexColor;
#endif
#ifndef CSM
		in	vec3		eyeVec;
#else
		in	vec3		eyeSpaceTangent;
		in	vec3		eyeSpaceBinormal;
		include intersect_cone_exp.inc
#endif
	include PackData.inc
	void main(void)
	{
		vec3 v_clipVertex = eyeSpaceVert;
		include clipPlane.inc

		float a;
		vec3 pt_eye;
#if defined(CSM)
		vec3 T = normalize(eyeSpaceTangent);
		vec3 B = normalize(eyeSpaceBinormal);
#endif
		vec3 N = normalize(eyeSpaceNormal);
		vec3 v = normalize(eyeSpaceVert);

		a = abs(dot(N, v));
		float Scale = sin(clamp(a, 0.0, 1.0) * 1.570796327);

#if defined(CSM)
		vec3 s;
		float df;

		// ray intersect in view direction
		a = Scale * HEIGHT_SCALE / a;
		s = vec3(a*dot(T, v), a*dot(B, v), 1.0);

		df = 0.05 * sqrt(length(fwidth(texCoord)));

		// find the distance to the actualy heightfield
		pt_eye = vec3(texCoord, 0.0);
		intersect_cone_exp (pt_eye, s, df);
#else
		include linearStepParallax.inc
#endif
		// compute the final color
		vec4 pix = texture2D(u_ColorMap, pt_eye.xy) * matColor;
		include alpha_test.inc
		vec3 spec = texture2D(u_SpecularMap, pt_eye.xy).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec4 tn = texture2D(u_NormalMap, pt_eye.xy) - vec4(0.5, 0.5, 0.5, 0.0);
		vec4 tdna = texture2D(u_detailNormalMap, pt_eye.xy * u_detailScale);
		vec3 tdn = tn.a * (tdna.xyz * vec3(2.0, 2.0, 0.0) - vec3(1.0, 1.0, 0.0));
		vec3 n = tangentToWorldMatrix * normalize(tn.xyz + tdn);
#if defined(FAKE_PPL)
		if (u_useLightMap == 1.0)
			PackData(pix, n, spec * tdna.a, nn, texture2D(u_LightMap, lmCoord).rgb);
		else
			PackData(pix, n, spec * tdna.a, nn, vertexColor);
#else
		PackData(pix, n, spec * tdna.a);
#endif
	}
}


_bump_parallax.vsh
{
	include parallax.vsh
}


_bump_parallax.fsh
{
	uniform sampler2D	u_ColorMap;
	uniform sampler2D	u_HeightMap;
	uniform sampler2D	u_NormalMap;
	uniform sampler2D	u_SpecularMap;
	uniform	float		u_Mirror;
	#if defined(ALPHATEST)
		uniform float	u_AlphaTestValue;
	#endif
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
	#endif
	in	vec2	texCoord;
	in	vec3	Tangent;
	in	vec3	Binormal;
	in	vec3	Normal;
	in	vec3	eyeSpaceNormal;
	in	vec3	eyeSpaceVert;
	in	vec4	matColor;
#if defined(FAKE_PPL)
		uniform sampler2D	u_LightMap;
		uniform float		u_useLightMap;
		in	vec2		lmCoord;
		in	vec3		vertexColor;
#endif
#ifndef CSM
		in	vec3		eyeVec;
#else
		in	vec3		eyeSpaceTangent;
		in	vec3		eyeSpaceBinormal;
		include intersect_cone_exp.inc
#endif
	include PackData.inc
	void main(void)
	{
		vec3 v_clipVertex = eyeSpaceVert;
		include clipPlane.inc

		float a;
		vec3 pt_eye;
#if defined(CSM)
		vec3 T = normalize(eyeSpaceTangent);
		vec3 B = normalize(eyeSpaceBinormal);
#endif
		vec3 N = normalize(eyeSpaceNormal);
		vec3 v = normalize(eyeSpaceVert);

		a = abs(dot(N, v));
		float Scale = sin(clamp(a, 0.0, 1.0) * 1.570796327);

#if defined(CSM)
		vec3 s;
		float df;

		// ray intersect in view direction
		a = Scale * HEIGHT_SCALE / a;
		s = vec3(a*dot(T, v), a*dot(B, v), 1.0);

		df = 0.05 * sqrt(length(fwidth(texCoord)));

		// find the distance to the actualy heightfield
		pt_eye = vec3(texCoord, 0.0);
		intersect_cone_exp (pt_eye, s, df);
#else
		include linearStepParallax.inc
#endif
		// compute the final color
		vec4 pix = texture2D(u_ColorMap, pt_eye.xy) * matColor;
		include alpha_test.inc
		vec3 spec = texture2D(u_SpecularMap, pt_eye.xy).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec3 n = tangentToWorldMatrix * normalize(texture2D(u_NormalMap, pt_eye.xy).xyz - 0.5);
#if defined(FAKE_PPL)
		if (u_useLightMap == 1.0)
			PackData(pix, n, spec, nn, texture2D(u_LightMap, lmCoord).rgb);
		else
			PackData(pix, n, spec, nn, vertexColor);
#else
		PackData(pix, n, spec);
#endif
	}
}



// NOTE:
// _bump_interpolate_parallax(_at) uses 8 textures,
// so we can't use lightmaps for FAKE_PPL variants.
// We will use vertex lighting.

_bump_interpolate_parallax.vsh
{
	include parallax_interpolate.vsh
}

_bump_interpolate_parallax.fsh
{
	uniform sampler2D	u_ColorMap0;
	uniform sampler2D	u_ColorMap1;
	uniform sampler2D	u_HeightMap0;
	uniform sampler2D	u_HeightMap1;
	uniform sampler2D	u_NormalMap0;
	uniform sampler2D	u_NormalMap1;
	uniform sampler2D	u_SpecularMap0;
	uniform sampler2D	u_SpecularMap1;
	uniform	float		u_Mirror;
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
	#endif
	in	vec2	texCoord;
	in	vec3	Tangent;
	in	vec3	Binormal;
	in	vec3	Normal;
	in	vec3	eyeSpaceNormal;
	in	vec3	eyeSpaceVert;
#if defined(FAKE_PPL)
	in	vec4	vertexColor;
#else
	in	float	vertexAlpha;
#endif
#ifndef CSM
	in	vec3	eyeVec;
#else
	in	vec3	eyeSpaceTangent;
	in	vec3	eyeSpaceBinormal;
	include intersect_cone_exp2.inc
#endif
	include PackData.inc
	void main(void)
	{
		vec3 v_clipVertex = eyeSpaceVert;
		include clipPlane.inc

		float a, alpha;
		vec3 pt_eye0, pt_eye1, sample0, sample1;

#if defined(FAKE_PPL)
		alpha = vertexColor.a * texture2D(u_ColorMap0, texCoord).a;
#else
		alpha = vertexAlpha * texture2D(u_ColorMap0, texCoord).a;
#endif
#if defined(CSM)
		vec3 T = normalize(eyeSpaceTangent);
		vec3 B = normalize(eyeSpaceBinormal);
#endif
		vec3 N = normalize(eyeSpaceNormal);
		vec3 v = normalize(eyeSpaceVert);

		a = abs(dot(N, v));
		float Scale = sin(clamp(a, 0.0, 1.0) * 1.570796327);

#if defined(CSM)
		vec3 s;
		float df;

		// ray intersect in view direction
		a = Scale * HEIGHT_SCALE / a;
		s = vec3(a*dot(T, v), a*dot(B, v), 1.0);

		df = 0.05 * sqrt(length(fwidth(texCoord)));

		// find the distance to the actualy heightfield
		pt_eye0 = pt_eye1 = vec3(texCoord, 0.0);
		intersect_cone_exp2 (pt_eye0, pt_eye1, u_HeightMap0, u_HeightMap1, s, df);
#else
		include linearStepParallax2.inc
#endif
		// interpolate offsets (alpha is non-parallaxed)
		pt_eye0.xy += alpha * (pt_eye1.xy - pt_eye0.xy);

		// use it to sample texture
		sample0 = texture2D(u_ColorMap0, pt_eye0.xy).rgb;
		sample1 = texture2D(u_ColorMap1, pt_eye0.xy).rgb;
		vec3 s0 = texture2D(u_SpecularMap0, pt_eye0.xy).rgb;
		vec3 s1 = texture2D(u_SpecularMap1, pt_eye0.xy).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec3 n0 = normalize(texture2D(u_NormalMap0, pt_eye0.xy).xyz - 0.5);
		vec3 n1 = normalize(texture2D(u_NormalMap1, pt_eye0.xy).xyz - 0.5);
		vec4 c = vec4(mix(sample0, sample1, alpha), 1.0);
		vec3 n = tangentToWorldMatrix * normalize(mix(n0, n1, alpha));
		vec3 sp = mix(s0, s1, alpha);
#if defined(FAKE_PPL)
		PackData(c, n, sp, nn, vertexColor.rgb);
#else
		PackData(c, n, sp);
#endif
	}
}



_bump_interpolate_parallax_at.vsh
{
	include parallax_interpolate.vsh
}


_bump_interpolate_parallax_at.fsh
{
	uniform sampler2D	u_ColorMap0;
	uniform sampler2D	u_ColorMap1;
	uniform sampler2D	u_HeightMap0;
	uniform sampler2D	u_HeightMap1;
	uniform sampler2D	u_NormalMap0;
	uniform sampler2D	u_NormalMap1;
	uniform sampler2D	u_SpecularMap0;
	uniform sampler2D	u_SpecularMap1;
	uniform	float		u_Mirror;
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
	#endif
	in	vec2	texCoord;
	in	vec3	Tangent;
	in	vec3	Binormal;
	in	vec3	Normal;
	in	vec3	eyeSpaceNormal;
	in	vec3	eyeSpaceVert;
#if defined(FAKE_PPL)
	in	vec4	vertexColor;
#else
	in	float	vertexAlpha;
#endif
#ifndef CSM
	in	vec3	eyeVec;
#else
	in	vec3	eyeSpaceTangent;
	in	vec3	eyeSpaceBinormal;
	include intersect_cone_exp2.inc
#endif
	include PackData.inc
	void main(void)
	{
		vec3 v_clipVertex = eyeSpaceVert;
		include clipPlane.inc

		float a, alpha;
		vec3 pt_eye0, pt_eye1, sample0;
		vec4 sample1;

#if defined(FAKE_PPL)
		alpha = vertexColor.a * texture2D(u_ColorMap0, texCoord).a;
#else
		alpha = vertexAlpha * texture2D(u_ColorMap0, texCoord).a;
#endif
#if defined(CSM)
		vec3 T = normalize(eyeSpaceTangent);
		vec3 B = normalize(eyeSpaceBinormal);
#endif
		vec3 N = normalize(eyeSpaceNormal);
		vec3 v = normalize(eyeSpaceVert);

		a = abs(dot(N, v));
		float Scale = sin(clamp(a, 0.0, 1.0) * 1.570796327);

#if defined(CSM)
		vec3 s;
		float df;

		// ray intersect in view direction
		a = Scale * HEIGHT_SCALE / a;
		s = vec3(a*dot(T, v), a*dot(B, v), 1.0);

		df = 0.05 * sqrt(length(fwidth(texCoord)));

		// find the distance to the actualy heightfield
		pt_eye0 = pt_eye1 = vec3(texCoord, 0.0);
		intersect_cone_exp2 (pt_eye0, pt_eye1, u_HeightMap0, u_HeightMap1, s, df);
#else
		include linearStepParallax2.inc
#endif
		// interpolate offsets (alpha is non-parallaxed)
		pt_eye0.xy += alpha * (pt_eye1.xy - pt_eye0.xy);

		// use it to sample texture
		sample0 = texture2D(u_ColorMap0, pt_eye0.xy).rgb;
		sample1 = texture2D(u_ColorMap1, pt_eye0.xy);

		// interpolate colors
#if defined(FAKE_PPL)
		alpha = sample1.a * vertexColor.a;
#else
		alpha = sample1.a * vertexAlpha;
#endif
		vec3 s0 = texture2D(u_SpecularMap0, pt_eye0.xy).rgb;
		vec3 s1 = texture2D(u_SpecularMap1, pt_eye0.xy).rgb;
		vec3 nn = normalize(Normal) * mix(1.0, -1.0, float(gl_FrontFacing)) * u_Mirror;
		mat3 tangentToWorldMatrix = mat3(normalize(Tangent), normalize(Binormal), nn);
		vec3 n0 = normalize(texture2D(u_NormalMap0, pt_eye0.xy).xyz - 0.5);
		vec3 n1 = normalize(texture2D(u_NormalMap1, pt_eye0.xy).xyz - 0.5);
		alpha *= step(0.5, alpha);
		vec4 c = vec4(mix(sample0, sample1.rgb, alpha), 1.0);
		vec3 n = tangentToWorldMatrix * normalize(mix(n0, n1, alpha));
		vec3 sp = mix(s0, s1, alpha);
#if defined(FAKE_PPL)
		PackData(c, n, sp, nn, vertexColor.rgb);
#else
		PackData(c, n, sp);
#endif
	}
}
