diff options
Diffstat (limited to 'shaders/warsow/148.shader_test')
-rw-r--r-- | shaders/warsow/148.shader_test | 2061 |
1 files changed, 2061 insertions, 0 deletions
diff --git a/shaders/warsow/148.shader_test b/shaders/warsow/148.shader_test new file mode 100644 index 0000000..25d520f --- /dev/null +++ b/shaders/warsow/148.shader_test @@ -0,0 +1,2061 @@ +[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 NUM_BONE_INFLUENCES 2 +#define APPLY_RGB_CONST +#define APPLY_ALPHA_CONST +#define APPLY_DIRECTIONAL_LIGHT +#define APPLY_HALFLAMBERT +#define APPLY_ENTITY_DECAL + +#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 NUM_BONE_INFLUENCES 2 +#define APPLY_RGB_CONST +#define APPLY_ALPHA_CONST +#define APPLY_DIRECTIONAL_LIGHT +#define APPLY_HALFLAMBERT +#define APPLY_ENTITY_DECAL + +#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 + |