summaryrefslogtreecommitdiff
path: root/shaders/warsow/94.shader_test
diff options
context:
space:
mode:
Diffstat (limited to 'shaders/warsow/94.shader_test')
-rw-r--r--shaders/warsow/94.shader_test2059
1 files changed, 2059 insertions, 0 deletions
diff --git a/shaders/warsow/94.shader_test b/shaders/warsow/94.shader_test
new file mode 100644
index 0000000..4cd298b
--- /dev/null
+++ b/shaders/warsow/94.shader_test
@@ -0,0 +1,2059 @@
+[require]
+GLSL >= 1.10
+
+[vertex shader]
+#version 130
+#extension GL_ARB_draw_instanced : enable
+#define QF_GLSL_VERSION 130
+#define VERTEX_SHADER
+#if !defined(myhalf)
+//#if !defined(__GLSL_CG_DATA_TYPES)
+#define myhalf float
+#define myhalf2 vec2
+#define myhalf3 vec3
+#define myhalf4 vec4
+//#else
+//#define myhalf half
+//#define myhalf2 half2
+//#define myhalf3 half3
+//#define myhalf4 half4
+//#endif
+#endif
+
+#if QF_GLSL_VERSION >= 130
+ precision highp float;
+
+# ifdef VERTEX_SHADER
+ out myhalf4 qf_FrontColor;
+# define qf_varying out
+# define qf_attribute in
+# endif
+# ifdef FRAGMENT_SHADER
+ in myhalf4 qf_FrontColor;
+ out myhalf4 qf_FragColor;
+# define qf_varying in
+# define qf_attribute in
+# endif
+
+# define qf_texture texture
+# define qf_textureCube texture
+# define qf_textureLod textureLod
+# define qf_textureOffset(a,b,c,d) textureOffset(a,b,ivec2(c,d))
+# define qf_shadow texture
+#else
+# ifdef VERTEX_SHADER
+# define qf_FrontColor gl_FrontColor
+# define qf_varying varying
+# define qf_attribute attribute
+# endif
+
+# ifdef FRAGMENT_SHADER
+# define qf_FrontColor gl_Color
+# define qf_FragColor gl_FragColor
+# define qf_varying varying
+# define qf_attribute attribute
+# endif
+# define qf_texture texture2D
+# define qf_textureLod texture2DLod
+# define qf_textureCube textureCube
+# define qf_textureOffset(a,b,c,d) texture2DOffset(a,b,ivec2(c,d))
+# define qf_shadow shadow2D
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_TWOPI
+#define M_TWOPI 6.28318530717958647692
+#endif
+
+#ifndef MAX_UNIFORM_BONES
+#define MAX_UNIFORM_BONES 100
+#endif
+
+#ifndef MAX_UNIFORM_INSTANCES
+#define MAX_UNIFORM_INSTANCES 40
+#endif
+uniform vec3 u_QF_ViewOrigin;
+uniform mat3 u_QF_ViewAxis;
+uniform float u_QF_MirrorSide;
+uniform vec3 u_QF_EntityOrigin;
+uniform float u_QF_ShaderTime;
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_TWOPI
+#define M_TWOPI 6.28318530717958647692
+#endif
+
+#ifndef WAVE_SIN
+float QF_WaveFunc_Sin(float x)
+{
+x -= floor(x);
+return sin(x * M_TWOPI);
+}
+float QF_WaveFunc_Triangle(float x)
+{
+x -= floor(x);
+return step(x, 0.25) * x * 4.0 + (2.0 - 4.0 * step(0.25, x) * step(x, 0.75) * x) + ((step(0.75, x) * x - 0.75) * 4.0 - 1.0);
+}
+float QF_WaveFunc_Square(float x)
+{
+x -= floor(x);
+return step(x, 0.5) * 2.0 - 1.0;
+}
+float QF_WaveFunc_Sawtooth(float x)
+{
+x -= floor(x);
+return x;
+}
+float QF_QF_WaveFunc_InverseSawtooth(float x)
+{
+x -= floor(x);
+return 1.0 - x;
+}
+
+#define WAVE_SIN(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Sin((phase)+(time)*(freq))))
+#define WAVE_TRIANGLE(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Triangle((phase)+(time)*(freq))))
+#define WAVE_SQUARE(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Square((phase)+(time)*(freq))))
+#define WAVE_SAWTOOTH(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Sawtooth((phase)+(time)*(freq))))
+#define WAVE_INVERSESAWTOOTH(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_QF_WaveFunc_InverseSawtooth((phase)+(time)*(freq))))
+#endif
+
+#ifdef VERTEX_SHADER
+attribute vec4 a_BonesIndices;
+attribute vec4 a_BonesWeights;
+
+uniform vec4 u_QF_DualQuats[MAX_UNIFORM_BONES*2];
+
+#if defined(DUAL_QUAT_TRANSFORM_NORMALS)
+#if defined(DUAL_QUAT_TRANSFORM_TANGENT)
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal, inout vec3 Tangent)
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal)
+#endif
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position)
+#endif
+{
+int index;
+vec4 Indices = a_BonesIndices;
+vec4 Weights = a_BonesWeights;
+vec4 Indices_2 = Indices * 2.0;
+vec4 DQReal, DQDual;
+
+index = int(Indices_2.x);
+DQReal = u_QF_DualQuats[index+0];
+DQDual = u_QF_DualQuats[index+1];
+
+if (numWeights > 1)
+{
+DQReal *= Weights.x;
+DQDual *= Weights.x;
+
+vec4 DQReal1, DQDual1;
+float scale;
+
+index = int(Indices_2.y);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.y;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 2)
+{
+index = int(Indices_2.z);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.z;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 3)
+{
+index = int(Indices_2.w);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.w;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+}
+}
+}
+
+float len = length(DQReal);
+DQReal /= len;
+DQDual /= len;
+
+Position.xyz = (cross(DQReal.xyz, cross(DQReal.xyz, Position.xyz) + Position.xyz*DQReal.w + DQDual.xyz) + DQDual.xyz*DQReal.w - DQReal.xyz*DQDual.w)*2.0 + Position.xyz;
+
+#ifdef DUAL_QUAT_TRANSFORM_NORMALS
+Normal = cross(DQReal.xyz, cross(DQReal.xyz, Normal) + Normal*DQReal.w)*2.0 + Normal;
+#endif
+
+#ifdef DUAL_QUAT_TRANSFORM_TANGENT
+Tangent = cross(DQReal.xyz, cross(DQReal.xyz, Tangent) + Tangent*DQReal.w)*2.0 + Tangent;
+#endif
+}
+
+// use defines to overload the transform function
+
+#define DUAL_QUAT_TRANSFORM_NORMALS
+#if defined(DUAL_QUAT_TRANSFORM_NORMALS)
+#if defined(DUAL_QUAT_TRANSFORM_TANGENT)
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal, inout vec3 Tangent)
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal)
+#endif
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position)
+#endif
+{
+int index;
+vec4 Indices = a_BonesIndices;
+vec4 Weights = a_BonesWeights;
+vec4 Indices_2 = Indices * 2.0;
+vec4 DQReal, DQDual;
+
+index = int(Indices_2.x);
+DQReal = u_QF_DualQuats[index+0];
+DQDual = u_QF_DualQuats[index+1];
+
+if (numWeights > 1)
+{
+DQReal *= Weights.x;
+DQDual *= Weights.x;
+
+vec4 DQReal1, DQDual1;
+float scale;
+
+index = int(Indices_2.y);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.y;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 2)
+{
+index = int(Indices_2.z);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.z;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 3)
+{
+index = int(Indices_2.w);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.w;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+}
+}
+}
+
+float len = length(DQReal);
+DQReal /= len;
+DQDual /= len;
+
+Position.xyz = (cross(DQReal.xyz, cross(DQReal.xyz, Position.xyz) + Position.xyz*DQReal.w + DQDual.xyz) + DQDual.xyz*DQReal.w - DQReal.xyz*DQDual.w)*2.0 + Position.xyz;
+
+#ifdef DUAL_QUAT_TRANSFORM_NORMALS
+Normal = cross(DQReal.xyz, cross(DQReal.xyz, Normal) + Normal*DQReal.w)*2.0 + Normal;
+#endif
+
+#ifdef DUAL_QUAT_TRANSFORM_TANGENT
+Tangent = cross(DQReal.xyz, cross(DQReal.xyz, Tangent) + Tangent*DQReal.w)*2.0 + Tangent;
+#endif
+}
+
+#define DUAL_QUAT_TRANSFORM_TANGENT
+#if defined(DUAL_QUAT_TRANSFORM_NORMALS)
+#if defined(DUAL_QUAT_TRANSFORM_TANGENT)
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal, inout vec3 Tangent)
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal)
+#endif
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position)
+#endif
+{
+int index;
+vec4 Indices = a_BonesIndices;
+vec4 Weights = a_BonesWeights;
+vec4 Indices_2 = Indices * 2.0;
+vec4 DQReal, DQDual;
+
+index = int(Indices_2.x);
+DQReal = u_QF_DualQuats[index+0];
+DQDual = u_QF_DualQuats[index+1];
+
+if (numWeights > 1)
+{
+DQReal *= Weights.x;
+DQDual *= Weights.x;
+
+vec4 DQReal1, DQDual1;
+float scale;
+
+index = int(Indices_2.y);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.y;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 2)
+{
+index = int(Indices_2.z);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.z;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 3)
+{
+index = int(Indices_2.w);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.w;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+}
+}
+}
+
+float len = length(DQReal);
+DQReal /= len;
+DQDual /= len;
+
+Position.xyz = (cross(DQReal.xyz, cross(DQReal.xyz, Position.xyz) + Position.xyz*DQReal.w + DQDual.xyz) + DQDual.xyz*DQReal.w - DQReal.xyz*DQDual.w)*2.0 + Position.xyz;
+
+#ifdef DUAL_QUAT_TRANSFORM_NORMALS
+Normal = cross(DQReal.xyz, cross(DQReal.xyz, Normal) + Normal*DQReal.w)*2.0 + Normal;
+#endif
+
+#ifdef DUAL_QUAT_TRANSFORM_TANGENT
+Tangent = cross(DQReal.xyz, cross(DQReal.xyz, Tangent) + Tangent*DQReal.w)*2.0 + Tangent;
+#endif
+}
+
+#endif
+#ifdef VERTEX_SHADER
+#ifdef APPLY_INSTANCED_ATTRIB_TRASNFORMS
+attribute vec4 a_InstanceQuat;
+attribute vec4 a_InstancePosAndScale;
+#elif defined(GL_ARB_draw_instanced)
+
+uniform vec4 u_QF_InstancePoints[MAX_UNIFORM_INSTANCES*2];
+
+#define a_InstanceQuat u_QF_InstancePoints[gl_InstanceID*2]
+#define a_InstancePosAndScale u_QF_InstancePoints[gl_InstanceID*2+1]
+#else
+uniform vec4 u_QF_InstancePoints[2];
+#define a_InstanceQuat u_QF_InstancePoints[0]
+#define a_InstancePosAndScale u_QF_InstancePoints[1]
+#endif
+
+void QF_InstancedTransform(inout vec4 Position, inout vec3 Normal)
+{
+Position.xyz = (cross(a_InstanceQuat.xyz, cross(a_InstanceQuat.xyz, Position.xyz) + Position.xyz*a_InstanceQuat.w)*2.0 + Position.xyz) *
+ a_InstancePosAndScale.w + a_InstancePosAndScale.xyz;
+Normal = cross(a_InstanceQuat.xyz, cross(a_InstanceQuat.xyz, Normal) + Normal*a_InstanceQuat.w)*2.0 + Normal;
+}
+
+#endif
+#define QF_LatLong2Norm(ll) vec3(cos((ll).y) * sin((ll).x), sin((ll).y) * sin((ll).x), cos((ll).x))
+
+#define APPLY_RGB_CONST
+#define APPLY_ALPHA_CONST
+#define APPLY_DIRECTIONAL_LIGHT
+#define APPLY_SPECULAR
+#define APPLY_HALFLAMBERT
+
+#define DRAWFLAT_NORMAL_STEP 0.5 // floor or ceiling if < abs(normal.z)
+uniform mat4 u_ModelViewMatrix;
+uniform mat4 u_ModelViewProjectionMatrix;
+
+uniform float u_ShaderTime;
+
+uniform vec3 u_ViewOrigin;
+uniform mat3 u_ViewAxis;
+
+uniform vec3 u_EntityDist;
+uniform vec3 u_EntityOrigin;
+uniform myhalf4 u_EntityColor;
+
+uniform myhalf4 u_ConstColor;
+uniform myhalf4 u_RGBGenFuncArgs, u_AlphaGenFuncArgs;
+uniform myhalf3 u_LightstyleColor[4]; // lightstyle colors
+
+uniform myhalf3 u_LightAmbient;
+uniform myhalf3 u_LightDiffuse;
+uniform vec3 u_LightDir;
+
+uniform myhalf2 u_BlendMix;
+
+uniform vec2 u_TextureMatrix[3];
+#define TextureMatrix2x3Mul(m2x3,tc) vec2(dot((m2x3)[0],(tc)) + (m2x3)[2][0], dot((m2x3)[1],(tc)) + (m2x3)[2][1])
+
+uniform float u_MirrorSide;
+
+uniform float u_ZNear, u_ZFar;
+
+uniform ivec4 u_Viewport; // x, y, width, height
+
+uniform vec4 u_TextureParams;
+
+uniform myhalf u_SoftParticlesScale;
+
+
+#if defined(NUM_DLIGHTS)
+#if defined(FRAGMENT_SHADER)
+#if defined(NUM_DLIGHTS)
+
+struct DynamicLight
+{
+ myhalf Radius;
+ vec3 Position;
+ myhalf3 Diffuse;
+};
+
+uniform DynamicLight u_DynamicLights[NUM_DLIGHTS];
+uniform int u_NumDynamicLights;
+#ifdef DLIGHTS_SURFACE_NORMAL_IN
+myhalf3 DynamicLightsSummaryColor(in vec3 Position, in myhalf3 surfaceNormalModelspace)
+#else
+myhalf3 DynamicLightsSummaryColor(in vec3 Position)
+#endif
+{
+ myhalf3 Color = myhalf3(0.0);
+
+#if QF_GLSL_VERSION >= 330
+ for (int i = 0; i < u_NumDynamicLights; i++)
+#else
+ for (int i = 0; i < NUM_DLIGHTS; i++)
+#endif
+ {
+ myhalf3 STR = myhalf3(u_DynamicLights[i].Position - Position);
+ myhalf distance = length(STR);
+ myhalf falloff = clamp(1.0 - distance / u_DynamicLights[i].Radius, 0.0, 1.0);
+
+ falloff *= falloff;
+
+ #ifdef DLIGHTS_SURFACE_NORMAL_IN
+ falloff *= myhalf(max(dot(normalize(STR), surfaceNormalModelspace), 0.0));
+ #endif
+
+ Color += falloff * u_DynamicLights[i].Diffuse;
+ }
+
+ return Color;
+}
+
+
+#define DLIGHTS_SURFACE_NORMAL_IN
+#ifdef DLIGHTS_SURFACE_NORMAL_IN
+myhalf3 DynamicLightsSummaryColor(in vec3 Position, in myhalf3 surfaceNormalModelspace)
+#else
+myhalf3 DynamicLightsSummaryColor(in vec3 Position)
+#endif
+{
+ myhalf3 Color = myhalf3(0.0);
+
+#if QF_GLSL_VERSION >= 330
+ for (int i = 0; i < u_NumDynamicLights; i++)
+#else
+ for (int i = 0; i < NUM_DLIGHTS; i++)
+#endif
+ {
+ myhalf3 STR = myhalf3(u_DynamicLights[i].Position - Position);
+ myhalf distance = length(STR);
+ myhalf falloff = clamp(1.0 - distance / u_DynamicLights[i].Radius, 0.0, 1.0);
+
+ falloff *= falloff;
+
+ #ifdef DLIGHTS_SURFACE_NORMAL_IN
+ falloff *= myhalf(max(dot(normalize(STR), surfaceNormalModelspace), 0.0));
+ #endif
+
+ Color += falloff * u_DynamicLights[i].Diffuse;
+ }
+
+ return Color;
+}
+
+
+#endif
+
+#endif
+#endif
+
+#ifdef APPLY_FOG
+struct Fog
+{
+ float EyeDist;
+ vec4 EyePlane, Plane;
+ myhalf3 Color;
+ float Scale;
+};
+
+uniform Fog u_Fog;
+
+#define FOG_TEXCOORD_STEP 1.0/256.0
+
+#define FogDensity(coord) sqrt(clamp((coord)[0],0.0,1.0))*step(FOG_TEXCOORD_STEP,(coord)[1])
+
+#define FOG_GEN_OUTPUT_COLOR
+#if defined(FOG_GEN_OUTPUT_COLOR)
+void FogGen(in vec4 Position, inout myhalf4 outColor, in myhalf2 blendMix)
+#elif defined(FOG_GEN_OUTPUT_TEXCOORDS)
+void FogGen(in vec4 Position, inout vec2 outTexCoord)
+#endif
+{
+ // side = vec2(inside, outside)
+ myhalf2 side = myhalf2(step(u_Fog.EyeDist, 0.0), step(0.0, u_Fog.EyeDist));
+ myhalf FDist = dot(Position.xyz, u_Fog.EyePlane.xyz) - u_Fog.EyePlane.w;
+ myhalf FVdist = dot(Position.xyz, u_Fog.Plane.xyz) - u_Fog.Plane.w;
+ myhalf FogDistScale = FVdist / (FVdist - u_Fog.EyeDist);
+
+#if defined(FOG_GEN_OUTPUT_COLOR)
+ myhalf FogDist = FDist * dot(side, myhalf2(1.0, FogDistScale));
+ myhalf FogScale = myhalf(clamp(1.0 - FogDist * u_Fog.Scale, 0.0, 1.0));
+ outColor *= mix(myhalf4(1.0), myhalf4(FogScale), blendMix.xxxy);
+#endif
+
+#if defined(FOG_GEN_OUTPUT_TEXCOORDS)
+ myhalf FogS = FDist * dot(side, myhalf2(1.0, step(FVdist, 0.0) * FogDistScale));
+ myhalf FogT = -FVdist;
+ outTexCoord = vec2(FogS * u_Fog.Scale, FogT * u_Fog.Scale + 1.5*FOG_TEXCOORD_STEP);
+#endif
+}
+
+
+#undef FOG_GEN_OUTPUT_COLOR
+#define FOG_GEN_OUTPUT_TEXCOORDS
+#if defined(FOG_GEN_OUTPUT_COLOR)
+void FogGen(in vec4 Position, inout myhalf4 outColor, in myhalf2 blendMix)
+#elif defined(FOG_GEN_OUTPUT_TEXCOORDS)
+void FogGen(in vec4 Position, inout vec2 outTexCoord)
+#endif
+{
+ // side = vec2(inside, outside)
+ myhalf2 side = myhalf2(step(u_Fog.EyeDist, 0.0), step(0.0, u_Fog.EyeDist));
+ myhalf FDist = dot(Position.xyz, u_Fog.EyePlane.xyz) - u_Fog.EyePlane.w;
+ myhalf FVdist = dot(Position.xyz, u_Fog.Plane.xyz) - u_Fog.Plane.w;
+ myhalf FogDistScale = FVdist / (FVdist - u_Fog.EyeDist);
+
+#if defined(FOG_GEN_OUTPUT_COLOR)
+ myhalf FogDist = FDist * dot(side, myhalf2(1.0, FogDistScale));
+ myhalf FogScale = myhalf(clamp(1.0 - FogDist * u_Fog.Scale, 0.0, 1.0));
+ outColor *= mix(myhalf4(1.0), myhalf4(FogScale), blendMix.xxxy);
+#endif
+
+#if defined(FOG_GEN_OUTPUT_TEXCOORDS)
+ myhalf FogS = FDist * dot(side, myhalf2(1.0, step(FVdist, 0.0) * FogDistScale));
+ myhalf FogT = -FVdist;
+ outTexCoord = vec2(FogS * u_Fog.Scale, FogT * u_Fog.Scale + 1.5*FOG_TEXCOORD_STEP);
+#endif
+}
+
+#endif
+#ifdef APPLY_GREYSCALE
+myhalf3 Greyscale(myhalf3 color)
+{
+ return myhalf3(dot(color, myhalf3(0.299, 0.587, 0.114)));
+}
+
+#endif
+
+qf_varying vec2 v_TexCoord;
+#ifdef NUM_LIGHTMAPS
+qf_varying vec2 v_LightmapTexCoord[NUM_LIGHTMAPS];
+#endif
+
+qf_varying vec3 v_Position;
+
+#if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+qf_varying vec3 v_EyeVector;
+#endif
+
+qf_varying mat3 v_StrMatrix; // directions of S/T/R texcoords (tangent, binormal, normal)
+
+#if defined(APPLY_FOG) && !defined(APPLY_FOG_COLOR)
+qf_varying vec2 v_FogCoord;
+#endif
+
+#ifdef VERTEX_SHADER
+#ifdef VERTEX_SHADER
+qf_attribute vec4 a_Position;
+qf_attribute vec4 a_SVector;
+qf_attribute vec4 a_Normal;
+qf_attribute vec4 a_Color;
+qf_attribute vec2 a_TexCoord;
+qf_attribute vec2 a_LightmapCoord0, a_LightmapCoord1, a_LightmapCoord2, a_LightmapCoord3;
+#endif
+void TransformVerts(inout vec4 Position, inout vec3 Normal, inout vec2 TexCoord)
+{
+#ifdef NUM_BONE_INFLUENCES
+ QF_VertexDualQuatsTransform(NUM_BONE_INFLUENCES, Position, Normal);
+#endif
+
+#ifdef APPLY_DEFORMVERTS
+ QF_DeformVerts(Position, Normal, TexCoord);
+#endif
+
+#ifdef APPLY_INSTANCED_TRANSFORMS
+ QF_InstancedTransform(Position, Normal);
+#endif
+}
+
+void TransformVerts(inout vec4 Position, inout vec3 Normal, inout vec3 Tangent, inout vec2 TexCoord)
+{
+#ifdef NUM_BONE_INFLUENCES
+ QF_VertexDualQuatsTransform(NUM_BONE_INFLUENCES, Position, Normal, Tangent);
+#endif
+
+#ifdef APPLY_DEFORMVERTS
+ QF_DeformVerts(Position, Normal, TexCoord);
+#endif
+
+#ifdef APPLY_INSTANCED_TRANSFORMS
+ QF_InstancedTransform(Position, Normal);
+#endif
+}
+myhalf4 VertexRGBGen(in vec4 Position, in vec3 Normal, in myhalf4 VertexColor)
+{
+#if defined(APPLY_RGB_DISTANCERAMP) || defined(APPLY_ALPHA_DISTANCERAMP)
+#define DISTANCERAMP(x1,x2,y1,y2) ((y2 - y1) / (x2 - x1) * (clamp(myhalf(dot(u_EntityDist - Position.xyz, Normal)),0.0,x2) - x1) + y1)
+#endif
+
+#if defined(APPLY_RGB_CONST) && defined(APPLY_ALPHA_CONST)
+ myhalf4 Color = u_ConstColor;
+#else
+ myhalf4 Color = myhalf4(1.0);
+
+#if defined(APPLY_RGB_CONST)
+ Color.rgb = u_ConstColor.rgb;
+#elif defined(APPLY_RGB_VERTEX)
+ Color.rgb = VertexColor.rgb;
+#elif defined(APPLY_RGB_ONE_MINUS_VERTEX)
+ Color.rgb = myhalf3(1.0) - VertexColor.rgb;
+#elif defined(APPLY_RGB_GEN_DIFFUSELIGHT)
+ Color.rgb = myhalf3(u_LightAmbient + max(dot(u_LightDir, Normal), 0.0) * u_LightDiffuse);
+#endif
+
+#if defined(APPLY_ALPHA_CONST)
+ Color.a = u_ConstColor.a;
+#elif defined(APPLY_ALPHA_VERTEX)
+ Color.a = VertexColor.a;
+#elif defined(APPLY_ALPHA_ONE_MINUS_VERTEX)
+ Color.a = 1.0 - VertexColor.a;
+#endif
+
+#endif
+
+#ifdef APPLY_RGB_DISTANCERAMP
+ Color.rgb *= DISTANCERAMP(u_RGBGenFuncArgs[2], u_RGBGenFuncArgs[3], u_RGBGenFuncArgs[0], u_RGBGenFuncArgs[1]);
+#endif
+
+#ifdef APPLY_ALPHA_DISTANCERAMP
+ Color.a *= DISTANCERAMP(u_AlphaGenFuncArgs[2], u_AlphaGenFuncArgs[3], u_AlphaGenFuncArgs[0], u_AlphaGenFuncArgs[1]);
+#endif
+
+ return Color;
+#if defined(APPLY_RGB_DISTANCERAMP) || defined(APPLY_ALPHA_DISTANCERAMP)
+#undef DISTANCERAMP
+#endif
+}
+
+
+void main()
+{
+ vec4 Position = a_Position;
+ vec3 Normal = a_Normal.xyz;
+ myhalf4 inColor = myhalf4(a_Color);
+ vec2 TexCoord = a_TexCoord;
+ vec3 Tangent = a_SVector.xyz;
+ float TangentDir = a_SVector.w;
+
+ TransformVerts(Position, Normal, Tangent, TexCoord);
+
+ myhalf4 outColor = VertexRGBGen(Position, Normal, inColor);
+
+#ifdef APPLY_FOG
+#if defined(APPLY_FOG_COLOR)
+ FogGen(Position, outColor, u_BlendMix);
+#else
+ FogGen(Position, v_FogCoord);
+#endif
+#endif // APPLY_FOG
+
+ qf_FrontColor = vec4(outColor);
+
+ v_TexCoord = TextureMatrix2x3Mul(u_TextureMatrix, TexCoord);
+
+#ifdef NUM_LIGHTMAPS
+ v_LightmapTexCoord[0] = a_LightmapCoord0;
+#if NUM_LIGHTMAPS >= 2
+ v_LightmapTexCoord[1] = a_LightmapCoord1;
+#if NUM_LIGHTMAPS >= 3
+ v_LightmapTexCoord[2] = a_LightmapCoord2;
+#if NUM_LIGHTMAPS >= 4
+ v_LightmapTexCoord[3] = a_LightmapCoord3;
+#endif // NUM_LIGHTMAPS >= 4
+#endif // NUM_LIGHTMAPS >= 3
+#endif // NUM_LIGHTMAPS >= 2
+#endif // NUM_LIGHTMAPS
+
+ v_StrMatrix[0] = Tangent;
+ v_StrMatrix[2] = Normal;
+ v_StrMatrix[1] = TangentDir * cross(Normal, Tangent);
+
+#if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+ vec3 EyeVectorWorld = u_ViewOrigin - Position.xyz;
+ v_EyeVector = EyeVectorWorld * v_StrMatrix;
+#endif
+
+ v_Position = Position.xyz;
+ gl_Position = u_ModelViewProjectionMatrix * Position;
+}
+
+#endif // VERTEX_SHADER
+
+#ifdef FRAGMENT_SHADER
+// Fragment shader
+
+#ifdef NUM_LIGHTMAPS
+uniform float u_DeluxemapOffset[NUM_LIGHTMAPS]; // s-offset for v_LightmapTexCoord
+uniform sampler2D u_LightmapTexture[NUM_LIGHTMAPS];
+#endif
+
+uniform sampler2D u_BaseTexture;
+uniform sampler2D u_NormalmapTexture;
+uniform sampler2D u_GlossTexture;
+#ifdef APPLY_DECAL
+uniform sampler2D u_DecalTexture;
+#endif
+
+#ifdef APPLY_ENTITY_DECAL
+uniform sampler2D u_EntityDecalTexture;
+#endif
+
+#if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+uniform float u_OffsetMappingScale;
+#endif
+
+#ifdef APPLY_DRAWFLAT
+uniform myhalf3 u_WallColor;
+uniform myhalf3 u_FloorColor;
+#endif
+
+uniform myhalf u_GlossIntensity; // gloss scaling factor
+uniform myhalf u_GlossExponent; // gloss exponent factor
+
+#if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+// The following reliefmapping and offsetmapping routine was taken from DarkPlaces
+// The credit goes to LordHavoc (as always)
+vec2 OffsetMapping(vec2 TexCoord)
+{
+#ifdef APPLY_RELIEFMAPPING
+ // 14 sample relief mapping: linear search and then binary search
+ // this basically steps forward a small amount repeatedly until it finds
+ // itself inside solid, then jitters forward and back using decreasing
+ // amounts to find the impact
+ //vec3 OffsetVector = vec3(v_EyeVector.xy * ((1.0 / v_EyeVector.z) * u_OffsetMappingScale) * vec2(-1, 1), -1);
+ //vec3 OffsetVector = vec3(normalize(v_EyeVector.xy) * u_OffsetMappingScale * vec2(-1, 1), -1);
+ vec3 OffsetVector = vec3(normalize(v_EyeVector).xy * u_OffsetMappingScale * vec2(-1, 1), -1);
+ vec3 RT = vec3(TexCoord, 1);
+ OffsetVector *= 0.1;
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) - 0.5);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.5 - 0.25);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.25 - 0.125);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.125 - 0.0625);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.0625 - 0.03125);
+ return RT.xy;
+#else
+ // 2 sample offset mapping (only 2 samples because of ATI Radeon 9500-9800/X300 limits)
+ // this basically moves forward the full distance, and then backs up based
+ // on height of samples
+ //vec2 OffsetVector = vec2(v_EyeVector.xy * ((1.0 / v_EyeVector.z) * u_OffsetMappingScale) * vec2(-1, 1));
+ //vec2 OffsetVector = vec2(normalize(v_EyeVector.xy) * u_OffsetMappingScale * vec2(-1, 1));
+ vec2 OffsetVector = vec2(normalize(v_EyeVector).xy * u_OffsetMappingScale * vec2(-1, 1));
+ TexCoord += OffsetVector;
+ OffsetVector *= 0.5;
+ TexCoord -= OffsetVector * qf_texture(u_NormalmapTexture, TexCoord).a;
+ TexCoord -= OffsetVector * qf_texture(u_NormalmapTexture, TexCoord).a;
+ return TexCoord;
+#endif // APPLY_RELIEFMAPPING
+}
+#endif // defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+
+void main()
+{
+#if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+ // apply offsetmapping
+ vec2 TexCoordOffset = OffsetMapping(v_TexCoord);
+#define v_TexCoord TexCoordOffset
+#endif
+
+ myhalf3 surfaceNormal;
+ myhalf3 surfaceNormalModelspace;
+ myhalf3 diffuseNormalModelspace;
+ float diffuseProduct;
+
+#ifdef APPLY_CELSHADING
+ int lightcell;
+ float diffuseProductPositive;
+ float diffuseProductNegative;
+ float hardShadow;
+#endif
+
+ myhalf3 weightedDiffuseNormalModelspace;
+
+#if !defined(APPLY_DIRECTIONAL_LIGHT) && !defined(NUM_LIGHTMAPS)
+ myhalf4 color = myhalf4 (1.0, 1.0, 1.0, 1.0);
+#else
+ myhalf4 color = myhalf4 (0.0, 0.0, 0.0, 1.0);
+#endif
+
+ myhalf4 decal = myhalf4 (0.0, 0.0, 0.0, 1.0);
+
+ // get the surface normal
+ surfaceNormal = normalize(myhalf3(qf_texture (u_NormalmapTexture, v_TexCoord)) - myhalf3 (0.5));
+ surfaceNormalModelspace = normalize(v_StrMatrix * surfaceNormal);
+
+#ifdef APPLY_DIRECTIONAL_LIGHT
+
+#ifdef APPLY_DIRECTIONAL_LIGHT_FROM_NORMAL
+ diffuseNormalModelspace = v_StrMatrix[2];
+#else
+ diffuseNormalModelspace = u_LightDir;
+#endif // APPLY_DIRECTIONAL_LIGHT_FROM_NORMAL
+
+ weightedDiffuseNormalModelspace = diffuseNormalModelspace;
+
+#ifdef APPLY_CELSHADING
+ hardShadow = 0.0;
+#ifdef APPLY_HALFLAMBERT
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ diffuseProductPositive = float ( clamp(diffuseProduct, 0.0, 1.0) * 0.5 + 0.5 );
+ diffuseProductPositive *= diffuseProductPositive;
+ diffuseProductNegative = float ( clamp(diffuseProduct, -1.0, 0.0) * 0.5 - 0.5 );
+ diffuseProductNegative *= diffuseProductNegative;
+ diffuseProductNegative -= 0.25;
+ diffuseProduct = diffuseProductPositive;
+#else
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ diffuseProductPositive = max (diffuseProduct, 0.0);
+ diffuseProductNegative = (-min (diffuseProduct, 0.0) - 0.3);
+#endif // APPLY_HALFLAMBERT
+
+ // smooth the hard shadow edge
+ lightcell = int(max(diffuseProduct + 0.1, 0.0) * 2.0);
+ hardShadow += float(lightcell);
+
+ lightcell = int(max(diffuseProduct + 0.055, 0.0) * 2.0);
+ hardShadow += float(lightcell);
+
+ lightcell = int(diffuseProductPositive * 2.0);
+ hardShadow += float(lightcell);
+
+ color.rgb += myhalf(0.6 + hardShadow * 0.3333333333 * 0.27 + diffuseProductPositive * 0.14);
+
+ // backlight
+ lightcell = int (diffuseProductNegative * 2.0);
+ color.rgb += myhalf (float(lightcell) * 0.085 + diffuseProductNegative * 0.085);
+#else
+
+#ifdef APPLY_HALFLAMBERT
+ diffuseProduct = float ( clamp(dot (surfaceNormalModelspace, diffuseNormalModelspace), 0.0, 1.0) * 0.5 + 0.5 );
+ diffuseProduct *= diffuseProduct;
+#else
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+#endif // APPLY_HALFLAMBERT
+
+#ifdef APPLY_DIRECTIONAL_LIGHT_MIX
+ color.rgb += qf_FrontColor.rgb;
+#else
+ color.rgb += u_LightDiffuse.rgb * myhalf(max (diffuseProduct, 0.0)) + u_LightAmbient;
+#endif
+
+#endif // APPLY_CELSHADING
+
+#endif // APPLY_DIRECTIONAL_LIGHT
+
+ // deluxemapping using light vectors in modelspace
+
+#ifdef NUM_LIGHTMAPS
+ // get light normal
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture(u_LightmapTexture[0], vec2(v_LightmapTexCoord[0].s+u_DeluxemapOffset[0],v_LightmapTexCoord[0].t))) - myhalf3 (0.5));
+ // calculate directional shading
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+
+#ifdef APPLY_FBLIGHTMAP
+ weightedDiffuseNormalModelspace = diffuseNormalModelspace;
+ // apply lightmap color
+ color.rgb += myhalf3 (max (diffuseProduct, 0.0) * myhalf3 (qf_texture (u_LightmapTexture[0], v_LightmapTexCoord[0])));
+#else
+#define NORMALIZE_DIFFUSE_NORMAL
+ weightedDiffuseNormalModelspace = u_LightstyleColor[0] * diffuseNormalModelspace;
+ // apply lightmap color
+ color.rgb += u_LightstyleColor[0] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[0], v_LightmapTexCoord[0]));
+#endif // APPLY_FBLIGHTMAP
+
+#ifdef APPLY_AMBIENT_COMPENSATION
+ // compensate for ambient lighting
+ color.rgb += myhalf((1.0 - max (diffuseProduct, 0.0))) * u_LightAmbient;
+#endif
+
+#if NUM_LIGHTMAPS >= 2
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture (u_LightmapTexture[1], vec2(v_LightmapTexCoord[1].s+u_DeluxemapOffset[1],v_LightmapTexCoord[1].t))) - myhalf3 (0.5));
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ weightedDiffuseNormalModelspace += u_LightstyleColor[1] * diffuseNormalModelspace;
+ color.rgb += u_LightstyleColor[1] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[1], v_LightmapTexCoord[1]));
+#if NUM_LIGHTMAPS >= 3
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture (u_LightmapTexture[2], vec2(v_LightmapTexCoord[2].s+u_DeluxemapOffset[2],v_LightmapTexCoord[2].t))) - myhalf3 (0.5));
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ weightedDiffuseNormalModelspace += u_LightstyleColor[2] * diffuseNormalModelspace;
+ color.rgb += u_LightstyleColor[2] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[2], v_LightmapTexCoord[2]));
+#if NUM_LIGHTMAPS >= 4
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture (u_LightmapTexture[3], vec2(v_LightmapTexCoord[3].s+u_DeluxemapOffset[3],v_LightmapTexCoord[3].t))) - myhalf3 (0.5));
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ weightedDiffuseNormalModelspace += u_LightstyleColor[3] * diffuseNormalModelspace;
+ color.rgb += u_LightstyleColor[3] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[3], v_LightmapTexCoord[3]));
+#endif // NUM_LIGHTMAPS >= 4
+#endif // NUM_LIGHTMAPS >= 3
+#endif // NUM_LIGHTMAPS >= 2
+#endif // NUM_LIGHTMAPS
+
+#if defined(NUM_DLIGHTS)
+ color.rgb += DynamicLightsSummaryColor(v_Position, surfaceNormalModelspace);
+#endif
+
+#ifdef APPLY_SPECULAR
+
+#ifdef NORMALIZE_DIFFUSE_NORMAL
+ myhalf3 specularNormal = normalize (myhalf3 (normalize (weightedDiffuseNormalModelspace)) + myhalf3 (normalize (u_EntityDist - v_Position)));
+#else
+ myhalf3 specularNormal = normalize (weightedDiffuseNormalModelspace + myhalf3 (normalize (u_EntityDist - v_Position)));
+#endif
+
+ myhalf specularProduct = myhalf(dot (surfaceNormalModelspace, specularNormal));
+ color.rgb += (myhalf3(qf_texture(u_GlossTexture, v_TexCoord)) * u_GlossIntensity) * pow(myhalf(max(specularProduct, 0.0)), u_GlossExponent);
+#endif // APPLY_SPECULAR
+
+#if defined(APPLY_BASETEX_ALPHA_ONLY) && !defined(APPLY_DRAWFLAT)
+ color = min(color, myhalf4(qf_texture(u_BaseTexture, v_TexCoord).a));
+#else
+ myhalf4 diffuse;
+
+#ifdef APPLY_DRAWFLAT
+ myhalf n = myhalf(step(DRAWFLAT_NORMAL_STEP, abs(v_StrMatrix[2].z)));
+ diffuse = myhalf4(mix(u_WallColor, u_FloorColor, n), myhalf(qf_texture(u_BaseTexture, v_TexCoord).a));
+#else
+ diffuse = myhalf4(qf_texture(u_BaseTexture, v_TexCoord));
+#endif
+
+#ifdef APPLY_ENTITY_DECAL
+
+#ifdef APPLY_ENTITY_DECAL_ADD
+ decal.rgb = myhalf3(qf_texture(u_EntityDecalTexture, v_TexCoord));
+ diffuse.rgb += u_EntityColor.rgb * decal.rgb;
+#else
+ decal = myhalf4(u_EntityColor.rgb, 1.0) * myhalf4(qf_texture(u_EntityDecalTexture, v_TexCoord));
+ diffuse.rgb = mix(diffuse.rgb, decal.rgb, decal.a);
+#endif // APPLY_ENTITY_DECAL_ADD
+
+#endif // APPLY_ENTITY_DECAL
+
+color = color * diffuse;
+#endif // defined(APPLY_BASETEX_ALPHA_ONLY) && !defined(APPLY_DRAWFLAT)
+
+#ifdef APPLY_DECAL
+
+#ifdef APPLY_DECAL_ADD
+ decal.rgb = myhalf3(qf_FrontColor.rgb) * myhalf3(qf_texture(u_DecalTexture, v_TexCoord));
+ color.rgb = decal.rgb + color.rgb;
+ color.a = color.a * myhalf(qf_FrontColor.a);
+#else
+ decal = myhalf4(qf_FrontColor) * myhalf4(qf_texture(u_DecalTexture, v_TexCoord));
+ color.rgb = mix(color.rgb, decal.rgb, decal.a);
+#endif // APPLY_DECAL_ADD
+
+#else
+
+#if defined (APPLY_DIRECTIONAL_LIGHT) && defined(APPLY_DIRECTIONAL_LIGHT_MIX)
+ color = color;
+#else
+ color = color * myhalf4(qf_FrontColor);
+#endif
+
+#endif // APPLY_DECAL
+
+#ifdef APPLY_GREYSCALE
+ color.rgb = Greyscale(color.rgb);
+#endif
+
+#if defined(APPLY_FOG) && !defined(APPLY_FOG_COLOR)
+ myhalf fogDensity = FogDensity(v_FogCoord);
+ color.rgb = mix(color.rgb, u_Fog.Color, fogDensity);
+#endif
+
+ qf_FragColor = vec4(color);
+}
+
+#endif // FRAGMENT_SHADER
+
+[fragment shader]
+#version 130
+
+#define QF_GLSL_VERSION 130
+#define FRAGMENT_SHADER
+#if !defined(myhalf)
+//#if !defined(__GLSL_CG_DATA_TYPES)
+#define myhalf float
+#define myhalf2 vec2
+#define myhalf3 vec3
+#define myhalf4 vec4
+//#else
+//#define myhalf half
+//#define myhalf2 half2
+//#define myhalf3 half3
+//#define myhalf4 half4
+//#endif
+#endif
+
+#if QF_GLSL_VERSION >= 130
+ precision highp float;
+
+# ifdef VERTEX_SHADER
+ out myhalf4 qf_FrontColor;
+# define qf_varying out
+# define qf_attribute in
+# endif
+# ifdef FRAGMENT_SHADER
+ in myhalf4 qf_FrontColor;
+ out myhalf4 qf_FragColor;
+# define qf_varying in
+# define qf_attribute in
+# endif
+
+# define qf_texture texture
+# define qf_textureCube texture
+# define qf_textureLod textureLod
+# define qf_textureOffset(a,b,c,d) textureOffset(a,b,ivec2(c,d))
+# define qf_shadow texture
+#else
+# ifdef VERTEX_SHADER
+# define qf_FrontColor gl_FrontColor
+# define qf_varying varying
+# define qf_attribute attribute
+# endif
+
+# ifdef FRAGMENT_SHADER
+# define qf_FrontColor gl_Color
+# define qf_FragColor gl_FragColor
+# define qf_varying varying
+# define qf_attribute attribute
+# endif
+# define qf_texture texture2D
+# define qf_textureLod texture2DLod
+# define qf_textureCube textureCube
+# define qf_textureOffset(a,b,c,d) texture2DOffset(a,b,ivec2(c,d))
+# define qf_shadow shadow2D
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_TWOPI
+#define M_TWOPI 6.28318530717958647692
+#endif
+
+#ifndef MAX_UNIFORM_BONES
+#define MAX_UNIFORM_BONES 100
+#endif
+
+#ifndef MAX_UNIFORM_INSTANCES
+#define MAX_UNIFORM_INSTANCES 40
+#endif
+uniform vec3 u_QF_ViewOrigin;
+uniform mat3 u_QF_ViewAxis;
+uniform float u_QF_MirrorSide;
+uniform vec3 u_QF_EntityOrigin;
+uniform float u_QF_ShaderTime;
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_TWOPI
+#define M_TWOPI 6.28318530717958647692
+#endif
+
+#ifndef WAVE_SIN
+float QF_WaveFunc_Sin(float x)
+{
+x -= floor(x);
+return sin(x * M_TWOPI);
+}
+float QF_WaveFunc_Triangle(float x)
+{
+x -= floor(x);
+return step(x, 0.25) * x * 4.0 + (2.0 - 4.0 * step(0.25, x) * step(x, 0.75) * x) + ((step(0.75, x) * x - 0.75) * 4.0 - 1.0);
+}
+float QF_WaveFunc_Square(float x)
+{
+x -= floor(x);
+return step(x, 0.5) * 2.0 - 1.0;
+}
+float QF_WaveFunc_Sawtooth(float x)
+{
+x -= floor(x);
+return x;
+}
+float QF_QF_WaveFunc_InverseSawtooth(float x)
+{
+x -= floor(x);
+return 1.0 - x;
+}
+
+#define WAVE_SIN(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Sin((phase)+(time)*(freq))))
+#define WAVE_TRIANGLE(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Triangle((phase)+(time)*(freq))))
+#define WAVE_SQUARE(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Square((phase)+(time)*(freq))))
+#define WAVE_SAWTOOTH(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_WaveFunc_Sawtooth((phase)+(time)*(freq))))
+#define WAVE_INVERSESAWTOOTH(time,base,amplitude,phase,freq) (((base)+(amplitude)*QF_QF_WaveFunc_InverseSawtooth((phase)+(time)*(freq))))
+#endif
+
+#ifdef VERTEX_SHADER
+attribute vec4 a_BonesIndices;
+attribute vec4 a_BonesWeights;
+
+uniform vec4 u_QF_DualQuats[MAX_UNIFORM_BONES*2];
+
+#if defined(DUAL_QUAT_TRANSFORM_NORMALS)
+#if defined(DUAL_QUAT_TRANSFORM_TANGENT)
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal, inout vec3 Tangent)
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal)
+#endif
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position)
+#endif
+{
+int index;
+vec4 Indices = a_BonesIndices;
+vec4 Weights = a_BonesWeights;
+vec4 Indices_2 = Indices * 2.0;
+vec4 DQReal, DQDual;
+
+index = int(Indices_2.x);
+DQReal = u_QF_DualQuats[index+0];
+DQDual = u_QF_DualQuats[index+1];
+
+if (numWeights > 1)
+{
+DQReal *= Weights.x;
+DQDual *= Weights.x;
+
+vec4 DQReal1, DQDual1;
+float scale;
+
+index = int(Indices_2.y);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.y;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 2)
+{
+index = int(Indices_2.z);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.z;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 3)
+{
+index = int(Indices_2.w);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.w;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+}
+}
+}
+
+float len = length(DQReal);
+DQReal /= len;
+DQDual /= len;
+
+Position.xyz = (cross(DQReal.xyz, cross(DQReal.xyz, Position.xyz) + Position.xyz*DQReal.w + DQDual.xyz) + DQDual.xyz*DQReal.w - DQReal.xyz*DQDual.w)*2.0 + Position.xyz;
+
+#ifdef DUAL_QUAT_TRANSFORM_NORMALS
+Normal = cross(DQReal.xyz, cross(DQReal.xyz, Normal) + Normal*DQReal.w)*2.0 + Normal;
+#endif
+
+#ifdef DUAL_QUAT_TRANSFORM_TANGENT
+Tangent = cross(DQReal.xyz, cross(DQReal.xyz, Tangent) + Tangent*DQReal.w)*2.0 + Tangent;
+#endif
+}
+
+// use defines to overload the transform function
+
+#define DUAL_QUAT_TRANSFORM_NORMALS
+#if defined(DUAL_QUAT_TRANSFORM_NORMALS)
+#if defined(DUAL_QUAT_TRANSFORM_TANGENT)
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal, inout vec3 Tangent)
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal)
+#endif
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position)
+#endif
+{
+int index;
+vec4 Indices = a_BonesIndices;
+vec4 Weights = a_BonesWeights;
+vec4 Indices_2 = Indices * 2.0;
+vec4 DQReal, DQDual;
+
+index = int(Indices_2.x);
+DQReal = u_QF_DualQuats[index+0];
+DQDual = u_QF_DualQuats[index+1];
+
+if (numWeights > 1)
+{
+DQReal *= Weights.x;
+DQDual *= Weights.x;
+
+vec4 DQReal1, DQDual1;
+float scale;
+
+index = int(Indices_2.y);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.y;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 2)
+{
+index = int(Indices_2.z);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.z;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 3)
+{
+index = int(Indices_2.w);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.w;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+}
+}
+}
+
+float len = length(DQReal);
+DQReal /= len;
+DQDual /= len;
+
+Position.xyz = (cross(DQReal.xyz, cross(DQReal.xyz, Position.xyz) + Position.xyz*DQReal.w + DQDual.xyz) + DQDual.xyz*DQReal.w - DQReal.xyz*DQDual.w)*2.0 + Position.xyz;
+
+#ifdef DUAL_QUAT_TRANSFORM_NORMALS
+Normal = cross(DQReal.xyz, cross(DQReal.xyz, Normal) + Normal*DQReal.w)*2.0 + Normal;
+#endif
+
+#ifdef DUAL_QUAT_TRANSFORM_TANGENT
+Tangent = cross(DQReal.xyz, cross(DQReal.xyz, Tangent) + Tangent*DQReal.w)*2.0 + Tangent;
+#endif
+}
+
+#define DUAL_QUAT_TRANSFORM_TANGENT
+#if defined(DUAL_QUAT_TRANSFORM_NORMALS)
+#if defined(DUAL_QUAT_TRANSFORM_TANGENT)
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal, inout vec3 Tangent)
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal)
+#endif
+#else
+void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position)
+#endif
+{
+int index;
+vec4 Indices = a_BonesIndices;
+vec4 Weights = a_BonesWeights;
+vec4 Indices_2 = Indices * 2.0;
+vec4 DQReal, DQDual;
+
+index = int(Indices_2.x);
+DQReal = u_QF_DualQuats[index+0];
+DQDual = u_QF_DualQuats[index+1];
+
+if (numWeights > 1)
+{
+DQReal *= Weights.x;
+DQDual *= Weights.x;
+
+vec4 DQReal1, DQDual1;
+float scale;
+
+index = int(Indices_2.y);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.y;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 2)
+{
+index = int(Indices_2.z);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.z;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+
+if (numWeights > 3)
+{
+index = int(Indices_2.w);
+DQReal1 = u_QF_DualQuats[index+0];
+DQDual1 = u_QF_DualQuats[index+1];
+// antipodality handling
+scale = (dot(DQReal1, DQReal) < 0.0 ? -1.0 : 1.0) * Weights.w;
+DQReal += DQReal1 * scale;
+DQDual += DQDual1 * scale;
+}
+}
+}
+
+float len = length(DQReal);
+DQReal /= len;
+DQDual /= len;
+
+Position.xyz = (cross(DQReal.xyz, cross(DQReal.xyz, Position.xyz) + Position.xyz*DQReal.w + DQDual.xyz) + DQDual.xyz*DQReal.w - DQReal.xyz*DQDual.w)*2.0 + Position.xyz;
+
+#ifdef DUAL_QUAT_TRANSFORM_NORMALS
+Normal = cross(DQReal.xyz, cross(DQReal.xyz, Normal) + Normal*DQReal.w)*2.0 + Normal;
+#endif
+
+#ifdef DUAL_QUAT_TRANSFORM_TANGENT
+Tangent = cross(DQReal.xyz, cross(DQReal.xyz, Tangent) + Tangent*DQReal.w)*2.0 + Tangent;
+#endif
+}
+
+#endif
+#ifdef VERTEX_SHADER
+#ifdef APPLY_INSTANCED_ATTRIB_TRASNFORMS
+attribute vec4 a_InstanceQuat;
+attribute vec4 a_InstancePosAndScale;
+#elif defined(GL_ARB_draw_instanced)
+
+uniform vec4 u_QF_InstancePoints[MAX_UNIFORM_INSTANCES*2];
+
+#define a_InstanceQuat u_QF_InstancePoints[gl_InstanceID*2]
+#define a_InstancePosAndScale u_QF_InstancePoints[gl_InstanceID*2+1]
+#else
+uniform vec4 u_QF_InstancePoints[2];
+#define a_InstanceQuat u_QF_InstancePoints[0]
+#define a_InstancePosAndScale u_QF_InstancePoints[1]
+#endif
+
+void QF_InstancedTransform(inout vec4 Position, inout vec3 Normal)
+{
+Position.xyz = (cross(a_InstanceQuat.xyz, cross(a_InstanceQuat.xyz, Position.xyz) + Position.xyz*a_InstanceQuat.w)*2.0 + Position.xyz) *
+ a_InstancePosAndScale.w + a_InstancePosAndScale.xyz;
+Normal = cross(a_InstanceQuat.xyz, cross(a_InstanceQuat.xyz, Normal) + Normal*a_InstanceQuat.w)*2.0 + Normal;
+}
+
+#endif
+#define QF_LatLong2Norm(ll) vec3(cos((ll).y) * sin((ll).x), sin((ll).y) * sin((ll).x), cos((ll).x))
+
+#define APPLY_RGB_CONST
+#define APPLY_ALPHA_CONST
+#define APPLY_DIRECTIONAL_LIGHT
+#define APPLY_SPECULAR
+#define APPLY_HALFLAMBERT
+
+#define DRAWFLAT_NORMAL_STEP 0.5 // floor or ceiling if < abs(normal.z)
+uniform mat4 u_ModelViewMatrix;
+uniform mat4 u_ModelViewProjectionMatrix;
+
+uniform float u_ShaderTime;
+
+uniform vec3 u_ViewOrigin;
+uniform mat3 u_ViewAxis;
+
+uniform vec3 u_EntityDist;
+uniform vec3 u_EntityOrigin;
+uniform myhalf4 u_EntityColor;
+
+uniform myhalf4 u_ConstColor;
+uniform myhalf4 u_RGBGenFuncArgs, u_AlphaGenFuncArgs;
+uniform myhalf3 u_LightstyleColor[4]; // lightstyle colors
+
+uniform myhalf3 u_LightAmbient;
+uniform myhalf3 u_LightDiffuse;
+uniform vec3 u_LightDir;
+
+uniform myhalf2 u_BlendMix;
+
+uniform vec2 u_TextureMatrix[3];
+#define TextureMatrix2x3Mul(m2x3,tc) vec2(dot((m2x3)[0],(tc)) + (m2x3)[2][0], dot((m2x3)[1],(tc)) + (m2x3)[2][1])
+
+uniform float u_MirrorSide;
+
+uniform float u_ZNear, u_ZFar;
+
+uniform ivec4 u_Viewport; // x, y, width, height
+
+uniform vec4 u_TextureParams;
+
+uniform myhalf u_SoftParticlesScale;
+
+
+#if defined(NUM_DLIGHTS)
+#if defined(FRAGMENT_SHADER)
+#if defined(NUM_DLIGHTS)
+
+struct DynamicLight
+{
+ myhalf Radius;
+ vec3 Position;
+ myhalf3 Diffuse;
+};
+
+uniform DynamicLight u_DynamicLights[NUM_DLIGHTS];
+uniform int u_NumDynamicLights;
+#ifdef DLIGHTS_SURFACE_NORMAL_IN
+myhalf3 DynamicLightsSummaryColor(in vec3 Position, in myhalf3 surfaceNormalModelspace)
+#else
+myhalf3 DynamicLightsSummaryColor(in vec3 Position)
+#endif
+{
+ myhalf3 Color = myhalf3(0.0);
+
+#if QF_GLSL_VERSION >= 330
+ for (int i = 0; i < u_NumDynamicLights; i++)
+#else
+ for (int i = 0; i < NUM_DLIGHTS; i++)
+#endif
+ {
+ myhalf3 STR = myhalf3(u_DynamicLights[i].Position - Position);
+ myhalf distance = length(STR);
+ myhalf falloff = clamp(1.0 - distance / u_DynamicLights[i].Radius, 0.0, 1.0);
+
+ falloff *= falloff;
+
+ #ifdef DLIGHTS_SURFACE_NORMAL_IN
+ falloff *= myhalf(max(dot(normalize(STR), surfaceNormalModelspace), 0.0));
+ #endif
+
+ Color += falloff * u_DynamicLights[i].Diffuse;
+ }
+
+ return Color;
+}
+
+
+#define DLIGHTS_SURFACE_NORMAL_IN
+#ifdef DLIGHTS_SURFACE_NORMAL_IN
+myhalf3 DynamicLightsSummaryColor(in vec3 Position, in myhalf3 surfaceNormalModelspace)
+#else
+myhalf3 DynamicLightsSummaryColor(in vec3 Position)
+#endif
+{
+ myhalf3 Color = myhalf3(0.0);
+
+#if QF_GLSL_VERSION >= 330
+ for (int i = 0; i < u_NumDynamicLights; i++)
+#else
+ for (int i = 0; i < NUM_DLIGHTS; i++)
+#endif
+ {
+ myhalf3 STR = myhalf3(u_DynamicLights[i].Position - Position);
+ myhalf distance = length(STR);
+ myhalf falloff = clamp(1.0 - distance / u_DynamicLights[i].Radius, 0.0, 1.0);
+
+ falloff *= falloff;
+
+ #ifdef DLIGHTS_SURFACE_NORMAL_IN
+ falloff *= myhalf(max(dot(normalize(STR), surfaceNormalModelspace), 0.0));
+ #endif
+
+ Color += falloff * u_DynamicLights[i].Diffuse;
+ }
+
+ return Color;
+}
+
+
+#endif
+
+#endif
+#endif
+
+#ifdef APPLY_FOG
+struct Fog
+{
+ float EyeDist;
+ vec4 EyePlane, Plane;
+ myhalf3 Color;
+ float Scale;
+};
+
+uniform Fog u_Fog;
+
+#define FOG_TEXCOORD_STEP 1.0/256.0
+
+#define FogDensity(coord) sqrt(clamp((coord)[0],0.0,1.0))*step(FOG_TEXCOORD_STEP,(coord)[1])
+
+#define FOG_GEN_OUTPUT_COLOR
+#if defined(FOG_GEN_OUTPUT_COLOR)
+void FogGen(in vec4 Position, inout myhalf4 outColor, in myhalf2 blendMix)
+#elif defined(FOG_GEN_OUTPUT_TEXCOORDS)
+void FogGen(in vec4 Position, inout vec2 outTexCoord)
+#endif
+{
+ // side = vec2(inside, outside)
+ myhalf2 side = myhalf2(step(u_Fog.EyeDist, 0.0), step(0.0, u_Fog.EyeDist));
+ myhalf FDist = dot(Position.xyz, u_Fog.EyePlane.xyz) - u_Fog.EyePlane.w;
+ myhalf FVdist = dot(Position.xyz, u_Fog.Plane.xyz) - u_Fog.Plane.w;
+ myhalf FogDistScale = FVdist / (FVdist - u_Fog.EyeDist);
+
+#if defined(FOG_GEN_OUTPUT_COLOR)
+ myhalf FogDist = FDist * dot(side, myhalf2(1.0, FogDistScale));
+ myhalf FogScale = myhalf(clamp(1.0 - FogDist * u_Fog.Scale, 0.0, 1.0));
+ outColor *= mix(myhalf4(1.0), myhalf4(FogScale), blendMix.xxxy);
+#endif
+
+#if defined(FOG_GEN_OUTPUT_TEXCOORDS)
+ myhalf FogS = FDist * dot(side, myhalf2(1.0, step(FVdist, 0.0) * FogDistScale));
+ myhalf FogT = -FVdist;
+ outTexCoord = vec2(FogS * u_Fog.Scale, FogT * u_Fog.Scale + 1.5*FOG_TEXCOORD_STEP);
+#endif
+}
+
+
+#undef FOG_GEN_OUTPUT_COLOR
+#define FOG_GEN_OUTPUT_TEXCOORDS
+#if defined(FOG_GEN_OUTPUT_COLOR)
+void FogGen(in vec4 Position, inout myhalf4 outColor, in myhalf2 blendMix)
+#elif defined(FOG_GEN_OUTPUT_TEXCOORDS)
+void FogGen(in vec4 Position, inout vec2 outTexCoord)
+#endif
+{
+ // side = vec2(inside, outside)
+ myhalf2 side = myhalf2(step(u_Fog.EyeDist, 0.0), step(0.0, u_Fog.EyeDist));
+ myhalf FDist = dot(Position.xyz, u_Fog.EyePlane.xyz) - u_Fog.EyePlane.w;
+ myhalf FVdist = dot(Position.xyz, u_Fog.Plane.xyz) - u_Fog.Plane.w;
+ myhalf FogDistScale = FVdist / (FVdist - u_Fog.EyeDist);
+
+#if defined(FOG_GEN_OUTPUT_COLOR)
+ myhalf FogDist = FDist * dot(side, myhalf2(1.0, FogDistScale));
+ myhalf FogScale = myhalf(clamp(1.0 - FogDist * u_Fog.Scale, 0.0, 1.0));
+ outColor *= mix(myhalf4(1.0), myhalf4(FogScale), blendMix.xxxy);
+#endif
+
+#if defined(FOG_GEN_OUTPUT_TEXCOORDS)
+ myhalf FogS = FDist * dot(side, myhalf2(1.0, step(FVdist, 0.0) * FogDistScale));
+ myhalf FogT = -FVdist;
+ outTexCoord = vec2(FogS * u_Fog.Scale, FogT * u_Fog.Scale + 1.5*FOG_TEXCOORD_STEP);
+#endif
+}
+
+#endif
+#ifdef APPLY_GREYSCALE
+myhalf3 Greyscale(myhalf3 color)
+{
+ return myhalf3(dot(color, myhalf3(0.299, 0.587, 0.114)));
+}
+
+#endif
+
+qf_varying vec2 v_TexCoord;
+#ifdef NUM_LIGHTMAPS
+qf_varying vec2 v_LightmapTexCoord[NUM_LIGHTMAPS];
+#endif
+
+qf_varying vec3 v_Position;
+
+#if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+qf_varying vec3 v_EyeVector;
+#endif
+
+qf_varying mat3 v_StrMatrix; // directions of S/T/R texcoords (tangent, binormal, normal)
+
+#if defined(APPLY_FOG) && !defined(APPLY_FOG_COLOR)
+qf_varying vec2 v_FogCoord;
+#endif
+
+#ifdef VERTEX_SHADER
+#ifdef VERTEX_SHADER
+qf_attribute vec4 a_Position;
+qf_attribute vec4 a_SVector;
+qf_attribute vec4 a_Normal;
+qf_attribute vec4 a_Color;
+qf_attribute vec2 a_TexCoord;
+qf_attribute vec2 a_LightmapCoord0, a_LightmapCoord1, a_LightmapCoord2, a_LightmapCoord3;
+#endif
+void TransformVerts(inout vec4 Position, inout vec3 Normal, inout vec2 TexCoord)
+{
+#ifdef NUM_BONE_INFLUENCES
+ QF_VertexDualQuatsTransform(NUM_BONE_INFLUENCES, Position, Normal);
+#endif
+
+#ifdef APPLY_DEFORMVERTS
+ QF_DeformVerts(Position, Normal, TexCoord);
+#endif
+
+#ifdef APPLY_INSTANCED_TRANSFORMS
+ QF_InstancedTransform(Position, Normal);
+#endif
+}
+
+void TransformVerts(inout vec4 Position, inout vec3 Normal, inout vec3 Tangent, inout vec2 TexCoord)
+{
+#ifdef NUM_BONE_INFLUENCES
+ QF_VertexDualQuatsTransform(NUM_BONE_INFLUENCES, Position, Normal, Tangent);
+#endif
+
+#ifdef APPLY_DEFORMVERTS
+ QF_DeformVerts(Position, Normal, TexCoord);
+#endif
+
+#ifdef APPLY_INSTANCED_TRANSFORMS
+ QF_InstancedTransform(Position, Normal);
+#endif
+}
+myhalf4 VertexRGBGen(in vec4 Position, in vec3 Normal, in myhalf4 VertexColor)
+{
+#if defined(APPLY_RGB_DISTANCERAMP) || defined(APPLY_ALPHA_DISTANCERAMP)
+#define DISTANCERAMP(x1,x2,y1,y2) ((y2 - y1) / (x2 - x1) * (clamp(myhalf(dot(u_EntityDist - Position.xyz, Normal)),0.0,x2) - x1) + y1)
+#endif
+
+#if defined(APPLY_RGB_CONST) && defined(APPLY_ALPHA_CONST)
+ myhalf4 Color = u_ConstColor;
+#else
+ myhalf4 Color = myhalf4(1.0);
+
+#if defined(APPLY_RGB_CONST)
+ Color.rgb = u_ConstColor.rgb;
+#elif defined(APPLY_RGB_VERTEX)
+ Color.rgb = VertexColor.rgb;
+#elif defined(APPLY_RGB_ONE_MINUS_VERTEX)
+ Color.rgb = myhalf3(1.0) - VertexColor.rgb;
+#elif defined(APPLY_RGB_GEN_DIFFUSELIGHT)
+ Color.rgb = myhalf3(u_LightAmbient + max(dot(u_LightDir, Normal), 0.0) * u_LightDiffuse);
+#endif
+
+#if defined(APPLY_ALPHA_CONST)
+ Color.a = u_ConstColor.a;
+#elif defined(APPLY_ALPHA_VERTEX)
+ Color.a = VertexColor.a;
+#elif defined(APPLY_ALPHA_ONE_MINUS_VERTEX)
+ Color.a = 1.0 - VertexColor.a;
+#endif
+
+#endif
+
+#ifdef APPLY_RGB_DISTANCERAMP
+ Color.rgb *= DISTANCERAMP(u_RGBGenFuncArgs[2], u_RGBGenFuncArgs[3], u_RGBGenFuncArgs[0], u_RGBGenFuncArgs[1]);
+#endif
+
+#ifdef APPLY_ALPHA_DISTANCERAMP
+ Color.a *= DISTANCERAMP(u_AlphaGenFuncArgs[2], u_AlphaGenFuncArgs[3], u_AlphaGenFuncArgs[0], u_AlphaGenFuncArgs[1]);
+#endif
+
+ return Color;
+#if defined(APPLY_RGB_DISTANCERAMP) || defined(APPLY_ALPHA_DISTANCERAMP)
+#undef DISTANCERAMP
+#endif
+}
+
+
+void main()
+{
+ vec4 Position = a_Position;
+ vec3 Normal = a_Normal.xyz;
+ myhalf4 inColor = myhalf4(a_Color);
+ vec2 TexCoord = a_TexCoord;
+ vec3 Tangent = a_SVector.xyz;
+ float TangentDir = a_SVector.w;
+
+ TransformVerts(Position, Normal, Tangent, TexCoord);
+
+ myhalf4 outColor = VertexRGBGen(Position, Normal, inColor);
+
+#ifdef APPLY_FOG
+#if defined(APPLY_FOG_COLOR)
+ FogGen(Position, outColor, u_BlendMix);
+#else
+ FogGen(Position, v_FogCoord);
+#endif
+#endif // APPLY_FOG
+
+ qf_FrontColor = vec4(outColor);
+
+ v_TexCoord = TextureMatrix2x3Mul(u_TextureMatrix, TexCoord);
+
+#ifdef NUM_LIGHTMAPS
+ v_LightmapTexCoord[0] = a_LightmapCoord0;
+#if NUM_LIGHTMAPS >= 2
+ v_LightmapTexCoord[1] = a_LightmapCoord1;
+#if NUM_LIGHTMAPS >= 3
+ v_LightmapTexCoord[2] = a_LightmapCoord2;
+#if NUM_LIGHTMAPS >= 4
+ v_LightmapTexCoord[3] = a_LightmapCoord3;
+#endif // NUM_LIGHTMAPS >= 4
+#endif // NUM_LIGHTMAPS >= 3
+#endif // NUM_LIGHTMAPS >= 2
+#endif // NUM_LIGHTMAPS
+
+ v_StrMatrix[0] = Tangent;
+ v_StrMatrix[2] = Normal;
+ v_StrMatrix[1] = TangentDir * cross(Normal, Tangent);
+
+#if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+ vec3 EyeVectorWorld = u_ViewOrigin - Position.xyz;
+ v_EyeVector = EyeVectorWorld * v_StrMatrix;
+#endif
+
+ v_Position = Position.xyz;
+ gl_Position = u_ModelViewProjectionMatrix * Position;
+}
+
+#endif // VERTEX_SHADER
+
+#ifdef FRAGMENT_SHADER
+// Fragment shader
+
+#ifdef NUM_LIGHTMAPS
+uniform float u_DeluxemapOffset[NUM_LIGHTMAPS]; // s-offset for v_LightmapTexCoord
+uniform sampler2D u_LightmapTexture[NUM_LIGHTMAPS];
+#endif
+
+uniform sampler2D u_BaseTexture;
+uniform sampler2D u_NormalmapTexture;
+uniform sampler2D u_GlossTexture;
+#ifdef APPLY_DECAL
+uniform sampler2D u_DecalTexture;
+#endif
+
+#ifdef APPLY_ENTITY_DECAL
+uniform sampler2D u_EntityDecalTexture;
+#endif
+
+#if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+uniform float u_OffsetMappingScale;
+#endif
+
+#ifdef APPLY_DRAWFLAT
+uniform myhalf3 u_WallColor;
+uniform myhalf3 u_FloorColor;
+#endif
+
+uniform myhalf u_GlossIntensity; // gloss scaling factor
+uniform myhalf u_GlossExponent; // gloss exponent factor
+
+#if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+// The following reliefmapping and offsetmapping routine was taken from DarkPlaces
+// The credit goes to LordHavoc (as always)
+vec2 OffsetMapping(vec2 TexCoord)
+{
+#ifdef APPLY_RELIEFMAPPING
+ // 14 sample relief mapping: linear search and then binary search
+ // this basically steps forward a small amount repeatedly until it finds
+ // itself inside solid, then jitters forward and back using decreasing
+ // amounts to find the impact
+ //vec3 OffsetVector = vec3(v_EyeVector.xy * ((1.0 / v_EyeVector.z) * u_OffsetMappingScale) * vec2(-1, 1), -1);
+ //vec3 OffsetVector = vec3(normalize(v_EyeVector.xy) * u_OffsetMappingScale * vec2(-1, 1), -1);
+ vec3 OffsetVector = vec3(normalize(v_EyeVector).xy * u_OffsetMappingScale * vec2(-1, 1), -1);
+ vec3 RT = vec3(TexCoord, 1);
+ OffsetVector *= 0.1;
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) - 0.5);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.5 - 0.25);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.25 - 0.125);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.125 - 0.0625);
+ RT += OffsetVector * (step(qf_texture(u_NormalmapTexture, RT.xy).a, RT.z) * 0.0625 - 0.03125);
+ return RT.xy;
+#else
+ // 2 sample offset mapping (only 2 samples because of ATI Radeon 9500-9800/X300 limits)
+ // this basically moves forward the full distance, and then backs up based
+ // on height of samples
+ //vec2 OffsetVector = vec2(v_EyeVector.xy * ((1.0 / v_EyeVector.z) * u_OffsetMappingScale) * vec2(-1, 1));
+ //vec2 OffsetVector = vec2(normalize(v_EyeVector.xy) * u_OffsetMappingScale * vec2(-1, 1));
+ vec2 OffsetVector = vec2(normalize(v_EyeVector).xy * u_OffsetMappingScale * vec2(-1, 1));
+ TexCoord += OffsetVector;
+ OffsetVector *= 0.5;
+ TexCoord -= OffsetVector * qf_texture(u_NormalmapTexture, TexCoord).a;
+ TexCoord -= OffsetVector * qf_texture(u_NormalmapTexture, TexCoord).a;
+ return TexCoord;
+#endif // APPLY_RELIEFMAPPING
+}
+#endif // defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+
+void main()
+{
+#if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING)
+ // apply offsetmapping
+ vec2 TexCoordOffset = OffsetMapping(v_TexCoord);
+#define v_TexCoord TexCoordOffset
+#endif
+
+ myhalf3 surfaceNormal;
+ myhalf3 surfaceNormalModelspace;
+ myhalf3 diffuseNormalModelspace;
+ float diffuseProduct;
+
+#ifdef APPLY_CELSHADING
+ int lightcell;
+ float diffuseProductPositive;
+ float diffuseProductNegative;
+ float hardShadow;
+#endif
+
+ myhalf3 weightedDiffuseNormalModelspace;
+
+#if !defined(APPLY_DIRECTIONAL_LIGHT) && !defined(NUM_LIGHTMAPS)
+ myhalf4 color = myhalf4 (1.0, 1.0, 1.0, 1.0);
+#else
+ myhalf4 color = myhalf4 (0.0, 0.0, 0.0, 1.0);
+#endif
+
+ myhalf4 decal = myhalf4 (0.0, 0.0, 0.0, 1.0);
+
+ // get the surface normal
+ surfaceNormal = normalize(myhalf3(qf_texture (u_NormalmapTexture, v_TexCoord)) - myhalf3 (0.5));
+ surfaceNormalModelspace = normalize(v_StrMatrix * surfaceNormal);
+
+#ifdef APPLY_DIRECTIONAL_LIGHT
+
+#ifdef APPLY_DIRECTIONAL_LIGHT_FROM_NORMAL
+ diffuseNormalModelspace = v_StrMatrix[2];
+#else
+ diffuseNormalModelspace = u_LightDir;
+#endif // APPLY_DIRECTIONAL_LIGHT_FROM_NORMAL
+
+ weightedDiffuseNormalModelspace = diffuseNormalModelspace;
+
+#ifdef APPLY_CELSHADING
+ hardShadow = 0.0;
+#ifdef APPLY_HALFLAMBERT
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ diffuseProductPositive = float ( clamp(diffuseProduct, 0.0, 1.0) * 0.5 + 0.5 );
+ diffuseProductPositive *= diffuseProductPositive;
+ diffuseProductNegative = float ( clamp(diffuseProduct, -1.0, 0.0) * 0.5 - 0.5 );
+ diffuseProductNegative *= diffuseProductNegative;
+ diffuseProductNegative -= 0.25;
+ diffuseProduct = diffuseProductPositive;
+#else
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ diffuseProductPositive = max (diffuseProduct, 0.0);
+ diffuseProductNegative = (-min (diffuseProduct, 0.0) - 0.3);
+#endif // APPLY_HALFLAMBERT
+
+ // smooth the hard shadow edge
+ lightcell = int(max(diffuseProduct + 0.1, 0.0) * 2.0);
+ hardShadow += float(lightcell);
+
+ lightcell = int(max(diffuseProduct + 0.055, 0.0) * 2.0);
+ hardShadow += float(lightcell);
+
+ lightcell = int(diffuseProductPositive * 2.0);
+ hardShadow += float(lightcell);
+
+ color.rgb += myhalf(0.6 + hardShadow * 0.3333333333 * 0.27 + diffuseProductPositive * 0.14);
+
+ // backlight
+ lightcell = int (diffuseProductNegative * 2.0);
+ color.rgb += myhalf (float(lightcell) * 0.085 + diffuseProductNegative * 0.085);
+#else
+
+#ifdef APPLY_HALFLAMBERT
+ diffuseProduct = float ( clamp(dot (surfaceNormalModelspace, diffuseNormalModelspace), 0.0, 1.0) * 0.5 + 0.5 );
+ diffuseProduct *= diffuseProduct;
+#else
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+#endif // APPLY_HALFLAMBERT
+
+#ifdef APPLY_DIRECTIONAL_LIGHT_MIX
+ color.rgb += qf_FrontColor.rgb;
+#else
+ color.rgb += u_LightDiffuse.rgb * myhalf(max (diffuseProduct, 0.0)) + u_LightAmbient;
+#endif
+
+#endif // APPLY_CELSHADING
+
+#endif // APPLY_DIRECTIONAL_LIGHT
+
+ // deluxemapping using light vectors in modelspace
+
+#ifdef NUM_LIGHTMAPS
+ // get light normal
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture(u_LightmapTexture[0], vec2(v_LightmapTexCoord[0].s+u_DeluxemapOffset[0],v_LightmapTexCoord[0].t))) - myhalf3 (0.5));
+ // calculate directional shading
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+
+#ifdef APPLY_FBLIGHTMAP
+ weightedDiffuseNormalModelspace = diffuseNormalModelspace;
+ // apply lightmap color
+ color.rgb += myhalf3 (max (diffuseProduct, 0.0) * myhalf3 (qf_texture (u_LightmapTexture[0], v_LightmapTexCoord[0])));
+#else
+#define NORMALIZE_DIFFUSE_NORMAL
+ weightedDiffuseNormalModelspace = u_LightstyleColor[0] * diffuseNormalModelspace;
+ // apply lightmap color
+ color.rgb += u_LightstyleColor[0] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[0], v_LightmapTexCoord[0]));
+#endif // APPLY_FBLIGHTMAP
+
+#ifdef APPLY_AMBIENT_COMPENSATION
+ // compensate for ambient lighting
+ color.rgb += myhalf((1.0 - max (diffuseProduct, 0.0))) * u_LightAmbient;
+#endif
+
+#if NUM_LIGHTMAPS >= 2
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture (u_LightmapTexture[1], vec2(v_LightmapTexCoord[1].s+u_DeluxemapOffset[1],v_LightmapTexCoord[1].t))) - myhalf3 (0.5));
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ weightedDiffuseNormalModelspace += u_LightstyleColor[1] * diffuseNormalModelspace;
+ color.rgb += u_LightstyleColor[1] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[1], v_LightmapTexCoord[1]));
+#if NUM_LIGHTMAPS >= 3
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture (u_LightmapTexture[2], vec2(v_LightmapTexCoord[2].s+u_DeluxemapOffset[2],v_LightmapTexCoord[2].t))) - myhalf3 (0.5));
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ weightedDiffuseNormalModelspace += u_LightstyleColor[2] * diffuseNormalModelspace;
+ color.rgb += u_LightstyleColor[2] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[2], v_LightmapTexCoord[2]));
+#if NUM_LIGHTMAPS >= 4
+ diffuseNormalModelspace = normalize(myhalf3 (qf_texture (u_LightmapTexture[3], vec2(v_LightmapTexCoord[3].s+u_DeluxemapOffset[3],v_LightmapTexCoord[3].t))) - myhalf3 (0.5));
+ diffuseProduct = float (dot (surfaceNormalModelspace, diffuseNormalModelspace));
+ weightedDiffuseNormalModelspace += u_LightstyleColor[3] * diffuseNormalModelspace;
+ color.rgb += u_LightstyleColor[3] * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (qf_texture(u_LightmapTexture[3], v_LightmapTexCoord[3]));
+#endif // NUM_LIGHTMAPS >= 4
+#endif // NUM_LIGHTMAPS >= 3
+#endif // NUM_LIGHTMAPS >= 2
+#endif // NUM_LIGHTMAPS
+
+#if defined(NUM_DLIGHTS)
+ color.rgb += DynamicLightsSummaryColor(v_Position, surfaceNormalModelspace);
+#endif
+
+#ifdef APPLY_SPECULAR
+
+#ifdef NORMALIZE_DIFFUSE_NORMAL
+ myhalf3 specularNormal = normalize (myhalf3 (normalize (weightedDiffuseNormalModelspace)) + myhalf3 (normalize (u_EntityDist - v_Position)));
+#else
+ myhalf3 specularNormal = normalize (weightedDiffuseNormalModelspace + myhalf3 (normalize (u_EntityDist - v_Position)));
+#endif
+
+ myhalf specularProduct = myhalf(dot (surfaceNormalModelspace, specularNormal));
+ color.rgb += (myhalf3(qf_texture(u_GlossTexture, v_TexCoord)) * u_GlossIntensity) * pow(myhalf(max(specularProduct, 0.0)), u_GlossExponent);
+#endif // APPLY_SPECULAR
+
+#if defined(APPLY_BASETEX_ALPHA_ONLY) && !defined(APPLY_DRAWFLAT)
+ color = min(color, myhalf4(qf_texture(u_BaseTexture, v_TexCoord).a));
+#else
+ myhalf4 diffuse;
+
+#ifdef APPLY_DRAWFLAT
+ myhalf n = myhalf(step(DRAWFLAT_NORMAL_STEP, abs(v_StrMatrix[2].z)));
+ diffuse = myhalf4(mix(u_WallColor, u_FloorColor, n), myhalf(qf_texture(u_BaseTexture, v_TexCoord).a));
+#else
+ diffuse = myhalf4(qf_texture(u_BaseTexture, v_TexCoord));
+#endif
+
+#ifdef APPLY_ENTITY_DECAL
+
+#ifdef APPLY_ENTITY_DECAL_ADD
+ decal.rgb = myhalf3(qf_texture(u_EntityDecalTexture, v_TexCoord));
+ diffuse.rgb += u_EntityColor.rgb * decal.rgb;
+#else
+ decal = myhalf4(u_EntityColor.rgb, 1.0) * myhalf4(qf_texture(u_EntityDecalTexture, v_TexCoord));
+ diffuse.rgb = mix(diffuse.rgb, decal.rgb, decal.a);
+#endif // APPLY_ENTITY_DECAL_ADD
+
+#endif // APPLY_ENTITY_DECAL
+
+color = color * diffuse;
+#endif // defined(APPLY_BASETEX_ALPHA_ONLY) && !defined(APPLY_DRAWFLAT)
+
+#ifdef APPLY_DECAL
+
+#ifdef APPLY_DECAL_ADD
+ decal.rgb = myhalf3(qf_FrontColor.rgb) * myhalf3(qf_texture(u_DecalTexture, v_TexCoord));
+ color.rgb = decal.rgb + color.rgb;
+ color.a = color.a * myhalf(qf_FrontColor.a);
+#else
+ decal = myhalf4(qf_FrontColor) * myhalf4(qf_texture(u_DecalTexture, v_TexCoord));
+ color.rgb = mix(color.rgb, decal.rgb, decal.a);
+#endif // APPLY_DECAL_ADD
+
+#else
+
+#if defined (APPLY_DIRECTIONAL_LIGHT) && defined(APPLY_DIRECTIONAL_LIGHT_MIX)
+ color = color;
+#else
+ color = color * myhalf4(qf_FrontColor);
+#endif
+
+#endif // APPLY_DECAL
+
+#ifdef APPLY_GREYSCALE
+ color.rgb = Greyscale(color.rgb);
+#endif
+
+#if defined(APPLY_FOG) && !defined(APPLY_FOG_COLOR)
+ myhalf fogDensity = FogDensity(v_FogCoord);
+ color.rgb = mix(color.rgb, u_Fog.Color, fogDensity);
+#endif
+
+ qf_FragColor = vec4(color);
+}
+
+#endif // FRAGMENT_SHADER
+