_Ambient.vsh
{
	uniform	mat4	u_ModelViewMatrix;
	uniform	mat4	u_ModelViewProjectionMatrix;
	uniform vec4	u_ambientColor;		// rgb = ambientColor, a = ambientScale
	#if defined(CLIP)
		out	vec3	v_clipVertex;
	#endif
	out	vec4	color;
	include deforms.inc
	include colorGen.inc
	void main(void)
	{
		mat2 dummy;
		vec4 glVertex = DeformGeometry(dummy);
		color = clamp((colorGen(glVertex.xyz, u_gen, u_parm0, u_parm1, u_parm2, u_parma) + vec4(u_ambientColor.rgb, 0.0)) * vec4(vec3(u_ambientColor.a), 1.0), 0.0, 1.0);
		gl_Position = u_ModelViewProjectionMatrix * glVertex;
		include clipVertex.inc
	}
}

_Ambient.fsh
{
	uniform sampler2DRect	u_ColorBuffer;
	uniform sampler2DRect	u_SpecularBuffer;
	uniform sampler2DRect	u_NormalBuffer;
	#if defined(ALPHATEST)
		uniform float	u_AlphaTestValue;
	#endif
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
		in	vec3	v_clipVertex;
	#endif
	in	vec4	color;
	out	vec4	fragColor;
	void main(void)
	{
		include clipPlane.inc
		vec4 spec = texture(u_SpecularBuffer, gl_FragCoord.xy);
		if (spec.a == 1.0)
		{
			discard;	// no portal surfaces draw
			return;
		}
		vec4 diffuse = texture(u_ColorBuffer, gl_FragCoord.xy);
		vec4 pix = diffuse * color;
		include alpha_test.inc
		float pbr = texture(u_NormalBuffer, gl_FragCoord.xy).a;
		if (abs(pbr) != 0.5)
			pix = pix * vec4(spec.aaa, 1.0) + vec4(diffuse.rgb * spec.ggg, 0.0);	// PBR: multiple to ambient occlusion and add emission
		fragColor = pix;
	}
}


_Lighting.vsh
{
	uniform	mat4	u_ModelViewMatrix;
	uniform	mat4	u_ModelViewProjectionMatrix;
	#if defined(CLIP)
		out	vec3	v_clipVertex;
	#endif
	include deforms.inc
	void main(void)
	{
		mat2 dummy;
		vec4 glVertex = DeformGeometry(dummy);
		gl_Position = u_ModelViewProjectionMatrix * glVertex;
		include clipVertex.inc
	}
}

_Lighting.fsh
{
	uniform sampler2DRect	u_SpecularBuffer;
	uniform sampler2DRect	u_LightBuffer;
	#if defined(CLIP)
		uniform vec4	u_clipPlane;
		in	vec3	v_clipVertex;
	#endif
	out	vec3		fragColor;
	void main(void)
	{
		include clipPlane.inc
		vec4 specular = texture(u_SpecularBuffer, gl_FragCoord.xy);
		if (specular.a == 1.0)
		{
			discard;	// no portal surfaces draw
			return;
		}
		fragColor = texture(u_LightBuffer, gl_FragCoord.xy).rgb;
	}
}


_FBO2Screen.vsh
{
	include generic_vertex.vsh
}

_FBO2Screen.fsh
{
	uniform	sampler2DRect	u_ColorBuffer;
	out	vec3		fragColor;
	uniform	vec4		u_colorModifier;	// rgba = brightness | contrast | saturation | 1.0/gamma
	include	gamma.inc
#if defined(COLOR_VIBRANCE)
	include colorVibrance.inc
#endif
	void main(void)
	{
		vec3 color = texture(u_ColorBuffer, gl_FragCoord.xy).rgb;
		if (any(notEqual(u_colorModifier.rgb, vec3(1.0))))
			BrightnessContrastSaturation(color, u_colorModifier.rgb);
		color = pow(color, vec3(u_colorModifier.a));
#if defined(COLOR_VIBRANCE)
		fragColor = ColorVibrance(color);
#else
		fragColor = color;
#endif
	}
}


_FBO2ScreenDistorted.vsh
{
	include generic_vertex.vsh
}

_FBO2ScreenDistorted.fsh
{
	uniform sampler2DRect	u_ColorBuffer0;
	uniform sampler2DRect	u_DistortBuffer;
	uniform sampler2DRect	u_ColorBuffer1;
	uniform sampler2DRect	u_ColorBuffer2;
	uniform sampler2DRect	u_ColorBuffer3;
	uniform sampler2DRect	u_ColorBuffer4;
	uniform sampler2DRect	u_ColorBuffer5;
	uniform sampler2DRect	u_ColorBuffer6;
	uniform sampler2DRect	u_ColorBuffer7;
	uniform vec2		u_Scale;
	out	vec3		fragColor;
	uniform	vec4		u_colorModifier;	// rgba = brightness | contrast | saturation | 1.0/gamma
	uniform	float		u_blurMap;		// 0: no blurMaping
	uniform	float		u_blurMapQuality;	// 0: fast but w/o linear interpolation
	include	gamma.inc
#if defined(COLOR_VIBRANCE)
	include colorVibrance.inc
#endif
	vec3 GetScreenTexel(in vec3 tc)
	{
		if (u_blurMap == 0.0)
			return texture(u_ColorBuffer0, tc.xy).rgb;

		if (u_blurMapQuality == 0.0)
		{
			if (tc.z > 240.0/256.0)
				return texture(u_ColorBuffer0, tc.xy).rgb;
			if (tc.z > 224.0/256.0)
				return texture(u_ColorBuffer1, tc.xy * (1.0/2.0)).rgb;
			if (tc.z > 208.0/256.0)
				return texture(u_ColorBuffer2, tc.xy * (1.0/3.0)).rgb;
			if (tc.z > 192.0/256.0)
				return texture(u_ColorBuffer3, tc.xy * (1.0/4.0)).rgb;
			if (tc.z > 176.0/256.0)
				return texture(u_ColorBuffer4, tc.xy * (1.0/5.0)).rgb;
			if (tc.z > 160.0/256.0)
				return texture(u_ColorBuffer5, tc.xy * (1.0/6.0)).rgb;
			if (tc.z > 144.0/256.0)
				return texture(u_ColorBuffer6, tc.xy * (1.0/7.0)).rgb;
		}
		else
		{
			float m;
			vec3 c0, c1;
			if (tc.z > 240.0/256.0)
			{
				c0 = texture(u_ColorBuffer0, tc.xy).rgb;
				c1 = texture(u_ColorBuffer1, tc.xy * (1.0/2.0)).rgb;
				m = (tc.z - 240.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 224.0/256.0)
			{
				c0 = texture(u_ColorBuffer1, tc.xy * (1.0/2.0)).rgb;
				c1 = texture(u_ColorBuffer2, tc.xy * (1.0/3.0)).rgb;
				m = (tc.z - 224.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 208.0/256.0)
			{
				c0 = texture(u_ColorBuffer2, tc.xy * (1.0/3.0)).rgb;
				c1 = texture(u_ColorBuffer3, tc.xy * (1.0/4.0)).rgb;
				m = (tc.z - 208.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 192.0/256.0)
			{
				c0 = texture(u_ColorBuffer3, tc.xy * (1.0/4.0)).rgb;
				c1 = texture(u_ColorBuffer4, tc.xy * (1.0/5.0)).rgb;
				m = (tc.z - 192.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 176.0/256.0)
			{
				c0 = texture(u_ColorBuffer4, tc.xy * (1.0/5.0)).rgb;
				c1 = texture(u_ColorBuffer5, tc.xy * (1.0/6.0)).rgb;
				m = (tc.z - 176.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 160.0/256.0)
			{
				c0 = texture(u_ColorBuffer5, tc.xy * (1.0/6.0)).rgb;
				c1 = texture(u_ColorBuffer6, tc.xy * (1.0/7.0)).rgb;
				m = (tc.z - 160.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 144.0/256.0)
			{
				c0 = texture(u_ColorBuffer6, tc.xy * (1.0/7.0)).rgb;
				c1 = texture(u_ColorBuffer7, tc.xy * (1.0/8.0)).rgb;
				m = (tc.z - 144.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
		}
		return texture(u_ColorBuffer7, tc.xy * (1.0/8.0)).rgb;
	}

	void main(void)
	{
		vec3 tsm = texture(u_DistortBuffer, gl_FragCoord.xy).xyz;
		tsm.xy = gl_FragCoord.xy + (tsm.xy - 0.5) * u_Scale;
		vec3 color = GetScreenTexel(tsm);
		if (any(notEqual(u_colorModifier.rgb, vec3(1.0))))
			BrightnessContrastSaturation(color, u_colorModifier.rgb);
		color = pow(color, vec3(u_colorModifier.a));
#if defined(COLOR_VIBRANCE)
		fragColor = ColorVibrance(color);
#else
		fragColor = color;
#endif
 	}
}


_FBO2ScreenFXAA.vsh
{
	include generic_vertex.vsh
}

_FBO2ScreenFXAA.fsh
{
	uniform sampler2DRect	u_ColorBuffer;
	out	vec3		fragColor;
	uniform	vec4		u_colorModifier;	// rgba = brightness | contrast | saturation | 1.0/gamma
	include	gamma.inc
	include fxaa.inc
#if defined(COLOR_VIBRANCE)
	include colorVibrance.inc
#endif
	void main(void)
	{
		vec3 color = doFXAA(u_ColorBuffer, gl_FragCoord.xy);
		if (any(notEqual(u_colorModifier.rgb, vec3(1.0))))
			BrightnessContrastSaturation(color, u_colorModifier.rgb);
		color = pow(color, vec3(u_colorModifier.a));
#if defined(COLOR_VIBRANCE)
		fragColor = ColorVibrance(color);
#else
		fragColor = color;
#endif
	}
}


_FBO2ScreenDistortedFXAA.vsh
{
	include generic_vertex.vsh
}

_FBO2ScreenDistortedFXAA.fsh
{
	uniform sampler2DRect	u_ColorBuffer0;
	uniform sampler2DRect	u_DistortBuffer;
	uniform sampler2DRect	u_ColorBuffer1;
	uniform sampler2DRect	u_ColorBuffer2;
	uniform sampler2DRect	u_ColorBuffer3;
	uniform sampler2DRect	u_ColorBuffer4;
	uniform sampler2DRect	u_ColorBuffer5;
	uniform sampler2DRect	u_ColorBuffer6;
	uniform sampler2DRect	u_ColorBuffer7;
	uniform vec2		u_Scale;
	out	vec3		fragColor;
	uniform	vec4		u_colorModifier;	// rgba = brightness | contrast | saturation | 1.0/gamma
	uniform	float		u_blurMap;		// 0: no blurMaping
	uniform	float		u_blurMapQuality;	// 0: fast but w/o linear interpolation
	include	gamma.inc
	include fxaa.inc
#if defined(COLOR_VIBRANCE)
	include colorVibrance.inc
#endif
	vec3 GetScreenTexel(in vec3 tc)
	{
		if (u_blurMap == 0.0)
			return doFXAA(u_ColorBuffer0, tc.xy);

		if (u_blurMapQuality == 0.0)
		{
			if (tc.z > 240.0/256.0)
				return doFXAA(u_ColorBuffer0, tc.xy);
			if (tc.z > 224.0/256.0)
				return texture(u_ColorBuffer1, tc.xy * (1.0/2.0)).rgb;
			if (tc.z > 208.0/256.0)
				return texture(u_ColorBuffer2, tc.xy * (1.0/3.0)).rgb;
			if (tc.z > 192.0/256.0)
				return texture(u_ColorBuffer3, tc.xy * (1.0/4.0)).rgb;
			if (tc.z > 176.0/256.0)
				return texture(u_ColorBuffer4, tc.xy * (1.0/5.0)).rgb;
			if (tc.z > 160.0/256.0)
				return texture(u_ColorBuffer5, tc.xy * (1.0/6.0)).rgb;
			if (tc.z > 144.0/256.0)
				return texture(u_ColorBuffer6, tc.xy * (1.0/7.0)).rgb;
		}
		else
		{
			float m;
			vec3 c0, c1;
			if (tc.z > 240.0/256.0)
			{
				c0 = doFXAA(u_ColorBuffer0, tc.xy);
				c1 = texture(u_ColorBuffer1, tc.xy * (1.0/2.0)).rgb;
				m = (tc.z - 240.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 224.0/256.0)
			{
				c0 = texture(u_ColorBuffer1, tc.xy * (1.0/2.0)).rgb;
				c1 = texture(u_ColorBuffer2, tc.xy * (1.0/3.0)).rgb;
				m = (tc.z - 224.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 208.0/256.0)
			{
				c0 = texture(u_ColorBuffer2, tc.xy * (1.0/3.0)).rgb;
				c1 = texture(u_ColorBuffer3, tc.xy * (1.0/4.0)).rgb;
				m = (tc.z - 208.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 192.0/256.0)
			{
				c0 = texture(u_ColorBuffer3, tc.xy * (1.0/4.0)).rgb;
				c1 = texture(u_ColorBuffer4, tc.xy * (1.0/5.0)).rgb;
				m = (tc.z - 192.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 176.0/256.0)
			{
				c0 = texture(u_ColorBuffer4, tc.xy * (1.0/5.0)).rgb;
				c1 = texture(u_ColorBuffer5, tc.xy * (1.0/6.0)).rgb;
				m = (tc.z - 176.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 160.0/256.0)
			{
				c0 = texture(u_ColorBuffer5, tc.xy * (1.0/6.0)).rgb;
				c1 = texture(u_ColorBuffer6, tc.xy * (1.0/7.0)).rgb;
				m = (tc.z - 160.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
			if (tc.z > 144.0/256.0)
			{
				c0 = texture(u_ColorBuffer6, tc.xy * (1.0/7.0)).rgb;
				c1 = texture(u_ColorBuffer7, tc.xy * (1.0/8.0)).rgb;
				m = (tc.z - 144.0/256.0) * 16.0;
				return mix(c1, c0, m);
			}
		}
		return texture(u_ColorBuffer7, tc.xy * (1.0/8.0)).rgb;
	}

	void main(void)
	{
		vec3 tsm = texture(u_DistortBuffer, gl_FragCoord.xy).xyz;
		tsm.xy = gl_FragCoord.xy + (tsm.xy - 0.5) * u_Scale;
		vec3 color = GetScreenTexel(tsm);
		if (any(notEqual(u_colorModifier.rgb, vec3(1.0))))
			BrightnessContrastSaturation(color, u_colorModifier.rgb);
		color = pow(color, vec3(u_colorModifier.a));
#if defined(COLOR_VIBRANCE)
		fragColor = ColorVibrance(color);
#else
		fragColor = color;
#endif
	}
}
