diff options
Diffstat (limited to 'shaders/warsow/31.shader_test')
-rw-r--r-- | shaders/warsow/31.shader_test | 2246 |
1 files changed, 1804 insertions, 442 deletions
diff --git a/shaders/warsow/31.shader_test b/shaders/warsow/31.shader_test index f005219..ce51847 100644 --- a/shaders/warsow/31.shader_test +++ b/shaders/warsow/31.shader_test @@ -1,138 +1,767 @@ [require] GLSL >= 1.10 -[fragment shader] -#define FRAGMENT_SHADER -// Warsow GLSL shader - -#if !defined(__GLSL_CG_DATA_TYPES) +[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 -#define myhalf half -#define myhalf2 half2 -#define myhalf3 half3 -#define myhalf4 half4 +# 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 -varying vec2 TexCoord; -#ifdef APPLY_LIGHTSTYLE0 -varying vec4 LightmapTexCoord01; -#ifdef APPLY_LIGHTSTYLE2 -varying vec4 LightmapTexCoord23; +#ifndef M_PI +#define M_PI 3.14159265358979323846 #endif +#ifndef M_TWOPI +#define M_TWOPI 6.28318530717958647692 #endif -#if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -varying vec3 EyeVector; +#ifndef MAX_UNIFORM_BONES +#define MAX_UNIFORM_BONES 100 #endif -#ifdef APPLY_DIRECTIONAL_LIGHT -varying vec3 LightVector; +#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; +} -varying mat3 strMatrix; // directions of S/T/R texcoords (tangent, binormal, normal) +#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 -// Vertex shader +attribute vec4 a_BonesIndices; +attribute vec4 a_BonesWeights; -uniform vec3 EyeOrigin; +uniform vec4 u_QF_DualQuats[MAX_UNIFORM_BONES*2]; -#ifdef APPLY_DIRECTIONAL_LIGHT -uniform vec3 LightDir; +#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; -void main() +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 1 + +#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 { -gl_FrontColor = gl_Color; + // 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); -TexCoord = vec2 (gl_TextureMatrix[0] * gl_MultiTexCoord0); +#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 -#ifdef APPLY_LIGHTSTYLE0 -LightmapTexCoord01.st = gl_MultiTexCoord4.st; -#ifdef APPLY_LIGHTSTYLE1 -LightmapTexCoord01.pq = gl_MultiTexCoord5.st; -#ifdef APPLY_LIGHTSTYLE2 -LightmapTexCoord23.st = gl_MultiTexCoord6.st; -#ifdef APPLY_LIGHTSTYLE3 -LightmapTexCoord23.pq = gl_MultiTexCoord7.st; +#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 -strMatrix[0] = gl_MultiTexCoord1.xyz; -strMatrix[2] = gl_Normal.xyz; -strMatrix[1] = gl_MultiTexCoord1.w * cross (strMatrix[2], strMatrix[0]); +qf_varying vec3 v_Position; #if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -vec3 EyeVectorWorld = EyeOrigin - gl_Vertex.xyz; -EyeVector = EyeVectorWorld * strMatrix; +qf_varying vec3 v_EyeVector; #endif -#ifdef APPLY_DIRECTIONAL_LIGHT -LightVector = LightDir * strMatrix; +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 -gl_Position = ftransform (); -#ifdef APPLY_CLIPPING -#ifdef __GLSL_CG_DATA_TYPES -gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex; +#ifdef APPLY_DEFORMVERTS + QF_DeformVerts(Position, Normal, TexCoord); #endif + +#ifdef APPLY_INSTANCED_TRANSFORMS + QF_InstancedTransform(Position, Normal); #endif } -#endif // VERTEX_SHADER +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 FRAGMENT_SHADER -// Fragment shader +#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 -#ifdef APPLY_LIGHTSTYLE0 -uniform sampler2D LightmapTexture0; -uniform float DeluxemapOffset0; // s-offset for LightmapTexCoord -uniform myhalf3 lsColor0; // lightstyle color +#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 -#ifdef APPLY_LIGHTSTYLE1 -uniform sampler2D LightmapTexture1; -uniform float DeluxemapOffset1; -uniform myhalf3 lsColor1; +#endif -#ifdef APPLY_LIGHTSTYLE2 -uniform sampler2D LightmapTexture2; -uniform float DeluxemapOffset2; -uniform myhalf3 lsColor2; +#ifdef APPLY_RGB_DISTANCERAMP + Color.rgb *= DISTANCERAMP(u_RGBGenFuncArgs[2], u_RGBGenFuncArgs[3], u_RGBGenFuncArgs[0], u_RGBGenFuncArgs[1]); +#endif -#ifdef APPLY_LIGHTSTYLE3 -uniform sampler2D LightmapTexture3; -uniform float DeluxemapOffset3; -uniform myhalf3 lsColor3; +#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 BaseTexture; -uniform sampler2D NormalmapTexture; -uniform sampler2D GlossTexture; +uniform sampler2D u_BaseTexture; +uniform sampler2D u_NormalmapTexture; +uniform sampler2D u_GlossTexture; #ifdef APPLY_DECAL -uniform sampler2D DecalTexture; +uniform sampler2D u_DecalTexture; +#endif + +#ifdef APPLY_ENTITY_DECAL +uniform sampler2D u_EntityDecalTexture; #endif #if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -uniform float OffsetMappingScale; +uniform float u_OffsetMappingScale; #endif -uniform myhalf3 LightAmbient; -#ifdef APPLY_DIRECTIONAL_LIGHT -uniform myhalf3 LightDiffuse; +#ifdef APPLY_DRAWFLAT +uniform myhalf3 u_WallColor; +uniform myhalf3 u_FloorColor; #endif -uniform myhalf GlossIntensity; // gloss scaling factor -uniform myhalf GlossExponent; // gloss exponent factor +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 @@ -140,342 +769,1023 @@ uniform myhalf GlossExponent; // gloss exponent factor 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(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMappingScale) * vec2(-1, 1), -1); -//vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMappingScale * vec2(-1, 1), -1); -vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMappingScale * vec2(-1, 1), -1); -vec3 RT = vec3(TexCoord, 1); -OffsetVector *= 0.1; -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) - 0.5); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) * 0.5 - 0.25); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) * 0.25 - 0.125); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) * 0.125 - 0.0625); -RT += OffsetVector * (step(texture2D(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(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMappingScale) * vec2(-1, 1)); -//vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMappingScale * vec2(-1, 1)); -vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMappingScale * vec2(-1, 1)); -TexCoord += OffsetVector; -OffsetVector *= 0.5; -TexCoord -= OffsetVector * texture2D(NormalmapTexture, TexCoord).a; -TexCoord -= OffsetVector * texture2D(NormalmapTexture, TexCoord).a; -return TexCoord; -#endif + // 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 +#endif // defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) void main() { #if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -// apply offsetmapping -vec2 TexCoordOffset = OffsetMapping(TexCoord); -#define TexCoord TexCoordOffset + // apply offsetmapping + vec2 TexCoordOffset = OffsetMapping(v_TexCoord); +#define v_TexCoord TexCoordOffset #endif -myhalf3 surfaceNormal; -myhalf3 diffuseNormalModelspace; -myhalf3 diffuseNormal = myhalf3 (0.0, 0.0, -1.0); -float diffuseProduct; -#ifdef APPLY_CELLSHADING -int lightcell; -float diffuseProductPositive; -float diffuseProductNegative; -float hardShadow; + + myhalf3 surfaceNormal; + myhalf3 surfaceNormalModelspace; + myhalf3 diffuseNormalModelspace; + float diffuseProduct; + +#ifdef APPLY_CELSHADING + int lightcell; + float diffuseProductPositive; + float diffuseProductNegative; + float hardShadow; #endif -myhalf3 weightedDiffuseNormal; -myhalf3 specularNormal; -float specularProduct; + myhalf3 weightedDiffuseNormalModelspace; -#if !defined(APPLY_DIRECTIONAL_LIGHT) && !defined(APPLY_LIGHTSTYLE0) -myhalf4 color = myhalf4 (1.0, 1.0, 1.0, 1.0); +#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); + myhalf4 color = myhalf4 (0.0, 0.0, 0.0, 1.0); #endif -// get the surface normal -surfaceNormal = normalize (myhalf3 (texture2D (NormalmapTexture, TexCoord)) - myhalf3 (0.5)); + 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 -diffuseNormal = myhalf3 (LightVector); -weightedDiffuseNormal = diffuseNormal; -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -#ifdef APPLY_CELLSHADING -hardShadow = 0.0; -diffuseProductPositive = max (diffuseProduct, 0.0); -diffuseProductNegative = (-min (diffuseProduct, 0.0) - 0.3); -// smooth the hard shadow edge -lightcell = int(max(diffuseProduct + 0.1, 0.0) * 2.0); -hardShadow += float(lightcell); +#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(max(diffuseProduct + 0.055, 0.0) * 2.0); + hardShadow += float(lightcell); -lightcell = int(diffuseProductPositive * 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); + 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); + // backlight + lightcell = int (diffuseProductNegative * 2.0); + color.rgb += myhalf (float(lightcell) * 0.085 + diffuseProductNegative * 0.085); #else -color.rgb += LightDiffuse.rgb * myhalf(max (diffuseProduct, 0.0)) + LightAmbient.rgb; -#endif +#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 -// deluxemapping using light vectors in modelspace +#endif // APPLY_CELSHADING -#ifdef APPLY_LIGHTSTYLE0 +#endif // APPLY_DIRECTIONAL_LIGHT -// get light normal -diffuseNormalModelspace = myhalf3 (texture2D(LightmapTexture0, vec2(LightmapTexCoord01.s+DeluxemapOffset0,LightmapTexCoord01.t))) - myhalf3 (0.5); -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -// calculate directional shading -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); + // 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 -weightedDiffuseNormal = diffuseNormal; -// apply lightmap color -color.rgb += myhalf3 (max (diffuseProduct, 0.0) * myhalf3 (texture2D (LightmapTexture0, LightmapTexCoord01.st))); + 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 - -weightedDiffuseNormal = lsColor0 * diffuseNormal; -// apply lightmap color -color.rgb += lsColor0 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture0, LightmapTexCoord01.st)); -#endif + 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))) * LightAmbient; + // 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_LIGHTSTYLE1 -diffuseNormalModelspace = myhalf3 (texture2D (LightmapTexture1, vec2(LightmapTexCoord01.p+DeluxemapOffset1,LightmapTexCoord01.q))) - myhalf3 (0.5); -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -weightedDiffuseNormal += lsColor1 * diffuseNormal; -color.rgb += lsColor1 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture1, LightmapTexCoord01.pq)); +#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 -#ifdef APPLY_LIGHTSTYLE2 -diffuseNormalModelspace = myhalf3 (texture2D (LightmapTexture2, vec2(LightmapTexCoord23.s+DeluxemapOffset2,LightmapTexCoord23.t))) - myhalf3 (0.5); -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -weightedDiffuseNormal += lsColor2 * diffuseNormal; -color.rgb += lsColor2 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture2, LightmapTexCoord23.st)); + 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 -#ifdef APPLY_LIGHTSTYLE3 -diffuseNormalModelspace = myhalf3 (texture2D (LightmapTexture3, vec2(LightmapTexCoord23.p+DeluxemapOffset3,LightmapTexCoord23.q))) - myhalf3 (0.5);; -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -weightedDiffuseNormal += lsColor3 * diffuseNormal; -color.rgb += lsColor3 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture3, LightmapTexCoord23.pq)); +#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 -#ifdef APPLY_SPECULAR + qf_FragColor = vec4(color); +} -#ifdef NORMALIZE_DIFFUSE_NORMAL -specularNormal = normalize (myhalf3 (normalize (weightedDiffuseNormal)) + myhalf3 (normalize (EyeVector))); +#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 -specularNormal = normalize (weightedDiffuseNormal + myhalf3 (normalize (EyeVector))); +# 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 -specularProduct = float (dot (surfaceNormal, specularNormal)); -color.rgb += (myhalf3(texture2D(GlossTexture, TexCoord)) * GlossIntensity) * pow(myhalf(max(specularProduct, 0.0)), GlossExponent); +#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]; -#ifdef APPLY_BASETEX_ALPHA_ONLY -color = min(color, myhalf4(texture2D(BaseTexture, TexCoord).a)); +#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 -#ifdef APPLY_COLOR_CLAMPING -color = min(color, myhalf4(1.0)); +void QF_VertexDualQuatsTransform(const int numWeights, inout vec4 Position, inout vec3 Normal) #endif -color = color * myhalf4(texture2D(BaseTexture, TexCoord)); +#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; -#ifdef APPLY_DECAL -#ifdef APPLY_DECAL_ADD -myhalf3 decal = myhalf3(gl_Color.rgb) * myhalf3(texture2D(DecalTexture, TexCoord)); -color.rgb = decal.rgb + color.rgb; -color.a = color.a * myhalf(gl_Color.a); +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 -myhalf4 decal = myhalf4(gl_Color.rgba); -if (decal.a > 0.0) +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) { -decal = decal * myhalf4(texture2D(DecalTexture, TexCoord)); -color.rgb = decal.rgb * decal.a + color.rgb * (1.0-decal.a); +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 -color = color * myhalf4(gl_Color.rgba); +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]; -#ifdef APPLY_GRAYSCALE -float grey = dot(color, myhalf3(0.299, 0.587, 0.114)); -gl_FragColor = vec4(vec3(grey),color.a); +#define a_InstanceQuat u_QF_InstancePoints[gl_InstanceID*2] +#define a_InstancePosAndScale u_QF_InstancePoints[gl_InstanceID*2+1] #else -gl_FragColor = vec4(color); +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 // FRAGMENT_SHADER +#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 1 -[vertex shader] -#define VERTEX_SHADER -// Warsow GLSL shader +#define DRAWFLAT_NORMAL_STEP 0.5 // floor or ceiling if < abs(normal.z) +uniform mat4 u_ModelViewMatrix; +uniform mat4 u_ModelViewProjectionMatrix; -#if !defined(__GLSL_CG_DATA_TYPES) -#define myhalf float -#define myhalf2 vec2 -#define myhalf3 vec3 -#define myhalf4 vec4 +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 -#define myhalf half -#define myhalf2 half2 -#define myhalf3 half3 -#define myhalf4 half4 +myhalf3 DynamicLightsSummaryColor(in vec3 Position) #endif +{ + myhalf3 Color = myhalf3(0.0); -varying vec2 TexCoord; -#ifdef APPLY_LIGHTSTYLE0 -varying vec4 LightmapTexCoord01; -#ifdef APPLY_LIGHTSTYLE2 -varying vec4 LightmapTexCoord23; +#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 defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -varying vec3 EyeVector; +#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; +} + -#ifdef APPLY_DIRECTIONAL_LIGHT -varying vec3 LightVector; #endif -varying mat3 strMatrix; // directions of S/T/R texcoords (tangent, binormal, normal) +#endif +#endif -#ifdef VERTEX_SHADER -// Vertex shader +#ifdef APPLY_FOG +struct Fog +{ + float EyeDist; + vec4 EyePlane, Plane; + myhalf3 Color; + float Scale; +}; -uniform vec3 EyeOrigin; +uniform Fog u_Fog; -#ifdef APPLY_DIRECTIONAL_LIGHT -uniform vec3 LightDir; +#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); -void main() +#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 { -gl_FrontColor = gl_Color; + // 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); -TexCoord = vec2 (gl_TextureMatrix[0] * gl_MultiTexCoord0); +#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 -#ifdef APPLY_LIGHTSTYLE0 -LightmapTexCoord01.st = gl_MultiTexCoord4.st; -#ifdef APPLY_LIGHTSTYLE1 -LightmapTexCoord01.pq = gl_MultiTexCoord5.st; -#ifdef APPLY_LIGHTSTYLE2 -LightmapTexCoord23.st = gl_MultiTexCoord6.st; -#ifdef APPLY_LIGHTSTYLE3 -LightmapTexCoord23.pq = gl_MultiTexCoord7.st; +#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 -strMatrix[0] = gl_MultiTexCoord1.xyz; -strMatrix[2] = gl_Normal.xyz; -strMatrix[1] = gl_MultiTexCoord1.w * cross (strMatrix[2], strMatrix[0]); +qf_varying vec3 v_Position; #if defined(APPLY_SPECULAR) || defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -vec3 EyeVectorWorld = EyeOrigin - gl_Vertex.xyz; -EyeVector = EyeVectorWorld * strMatrix; +qf_varying vec3 v_EyeVector; #endif -#ifdef APPLY_DIRECTIONAL_LIGHT -LightVector = LightDir * strMatrix; +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 -gl_Position = ftransform (); -#ifdef APPLY_CLIPPING -#ifdef __GLSL_CG_DATA_TYPES -gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex; +#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 } -#endif // VERTEX_SHADER +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 FRAGMENT_SHADER -// Fragment shader +#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 -#ifdef APPLY_LIGHTSTYLE0 -uniform sampler2D LightmapTexture0; -uniform float DeluxemapOffset0; // s-offset for LightmapTexCoord -uniform myhalf3 lsColor0; // lightstyle color +#if defined(APPLY_RGB_CONST) && defined(APPLY_ALPHA_CONST) + myhalf4 Color = u_ConstColor; +#else + myhalf4 Color = myhalf4(1.0); -#ifdef APPLY_LIGHTSTYLE1 -uniform sampler2D LightmapTexture1; -uniform float DeluxemapOffset1; -uniform myhalf3 lsColor1; +#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 -#ifdef APPLY_LIGHTSTYLE2 -uniform sampler2D LightmapTexture2; -uniform float DeluxemapOffset2; -uniform myhalf3 lsColor2; +#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 -#ifdef APPLY_LIGHTSTYLE3 -uniform sampler2D LightmapTexture3; -uniform float DeluxemapOffset3; -uniform myhalf3 lsColor3; +#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 BaseTexture; -uniform sampler2D NormalmapTexture; -uniform sampler2D GlossTexture; +uniform sampler2D u_BaseTexture; +uniform sampler2D u_NormalmapTexture; +uniform sampler2D u_GlossTexture; #ifdef APPLY_DECAL -uniform sampler2D DecalTexture; +uniform sampler2D u_DecalTexture; +#endif + +#ifdef APPLY_ENTITY_DECAL +uniform sampler2D u_EntityDecalTexture; #endif #if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -uniform float OffsetMappingScale; +uniform float u_OffsetMappingScale; #endif -uniform myhalf3 LightAmbient; -#ifdef APPLY_DIRECTIONAL_LIGHT -uniform myhalf3 LightDiffuse; +#ifdef APPLY_DRAWFLAT +uniform myhalf3 u_WallColor; +uniform myhalf3 u_FloorColor; #endif -uniform myhalf GlossIntensity; // gloss scaling factor -uniform myhalf GlossExponent; // gloss exponent factor +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 @@ -483,207 +1793,259 @@ uniform myhalf GlossExponent; // gloss exponent factor 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(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMappingScale) * vec2(-1, 1), -1); -//vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMappingScale * vec2(-1, 1), -1); -vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMappingScale * vec2(-1, 1), -1); -vec3 RT = vec3(TexCoord, 1); -OffsetVector *= 0.1; -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * step(texture2D(NormalmapTexture, RT.xy).a, RT.z); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) - 0.5); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) * 0.5 - 0.25); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) * 0.25 - 0.125); -RT += OffsetVector * (step(texture2D(NormalmapTexture, RT.xy).a, RT.z) * 0.125 - 0.0625); -RT += OffsetVector * (step(texture2D(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(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMappingScale) * vec2(-1, 1)); -//vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMappingScale * vec2(-1, 1)); -vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMappingScale * vec2(-1, 1)); -TexCoord += OffsetVector; -OffsetVector *= 0.5; -TexCoord -= OffsetVector * texture2D(NormalmapTexture, TexCoord).a; -TexCoord -= OffsetVector * texture2D(NormalmapTexture, TexCoord).a; -return TexCoord; -#endif + // 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 +#endif // defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) void main() { #if defined(APPLY_OFFSETMAPPING) || defined(APPLY_RELIEFMAPPING) -// apply offsetmapping -vec2 TexCoordOffset = OffsetMapping(TexCoord); -#define TexCoord TexCoordOffset + // apply offsetmapping + vec2 TexCoordOffset = OffsetMapping(v_TexCoord); +#define v_TexCoord TexCoordOffset #endif -myhalf3 surfaceNormal; -myhalf3 diffuseNormalModelspace; -myhalf3 diffuseNormal = myhalf3 (0.0, 0.0, -1.0); -float diffuseProduct; -#ifdef APPLY_CELLSHADING -int lightcell; -float diffuseProductPositive; -float diffuseProductNegative; -float hardShadow; + + myhalf3 surfaceNormal; + myhalf3 surfaceNormalModelspace; + myhalf3 diffuseNormalModelspace; + float diffuseProduct; + +#ifdef APPLY_CELSHADING + int lightcell; + float diffuseProductPositive; + float diffuseProductNegative; + float hardShadow; #endif -myhalf3 weightedDiffuseNormal; -myhalf3 specularNormal; -float specularProduct; + myhalf3 weightedDiffuseNormalModelspace; -#if !defined(APPLY_DIRECTIONAL_LIGHT) && !defined(APPLY_LIGHTSTYLE0) -myhalf4 color = myhalf4 (1.0, 1.0, 1.0, 1.0); +#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); + myhalf4 color = myhalf4 (0.0, 0.0, 0.0, 1.0); #endif -// get the surface normal -surfaceNormal = normalize (myhalf3 (texture2D (NormalmapTexture, TexCoord)) - myhalf3 (0.5)); + 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 -diffuseNormal = myhalf3 (LightVector); -weightedDiffuseNormal = diffuseNormal; -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -#ifdef APPLY_CELLSHADING -hardShadow = 0.0; -diffuseProductPositive = max (diffuseProduct, 0.0); -diffuseProductNegative = (-min (diffuseProduct, 0.0) - 0.3); -// smooth the hard shadow edge -lightcell = int(max(diffuseProduct + 0.1, 0.0) * 2.0); -hardShadow += float(lightcell); +#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 -lightcell = int(max(diffuseProduct + 0.055, 0.0) * 2.0); -hardShadow += float(lightcell); + // smooth the hard shadow edge + lightcell = int(max(diffuseProduct + 0.1, 0.0) * 2.0); + hardShadow += float(lightcell); -lightcell = int(diffuseProductPositive * 2.0); -hardShadow += float(lightcell); + lightcell = int(max(diffuseProduct + 0.055, 0.0) * 2.0); + hardShadow += float(lightcell); -color.rgb += myhalf(0.6 + hardShadow * 0.3333333333 * 0.27 + diffuseProductPositive * 0.14); + lightcell = int(diffuseProductPositive * 2.0); + hardShadow += float(lightcell); -// backlight -lightcell = int (diffuseProductNegative * 2.0); -color.rgb += myhalf (float(lightcell) * 0.085 + diffuseProductNegative * 0.085); + 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 -color.rgb += LightDiffuse.rgb * myhalf(max (diffuseProduct, 0.0)) + LightAmbient.rgb; -#endif +#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 -// deluxemapping using light vectors in modelspace +#endif // APPLY_CELSHADING + +#endif // APPLY_DIRECTIONAL_LIGHT -#ifdef APPLY_LIGHTSTYLE0 + // deluxemapping using light vectors in modelspace -// get light normal -diffuseNormalModelspace = myhalf3 (texture2D(LightmapTexture0, vec2(LightmapTexCoord01.s+DeluxemapOffset0,LightmapTexCoord01.t))) - myhalf3 (0.5); -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -// calculate directional shading -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); +#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 -weightedDiffuseNormal = diffuseNormal; -// apply lightmap color -color.rgb += myhalf3 (max (diffuseProduct, 0.0) * myhalf3 (texture2D (LightmapTexture0, LightmapTexCoord01.st))); + 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 - -weightedDiffuseNormal = lsColor0 * diffuseNormal; -// apply lightmap color -color.rgb += lsColor0 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture0, LightmapTexCoord01.st)); -#endif + 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))) * LightAmbient; -#endif - -#ifdef APPLY_LIGHTSTYLE1 -diffuseNormalModelspace = myhalf3 (texture2D (LightmapTexture1, vec2(LightmapTexCoord01.p+DeluxemapOffset1,LightmapTexCoord01.q))) - myhalf3 (0.5); -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -weightedDiffuseNormal += lsColor1 * diffuseNormal; -color.rgb += lsColor1 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture1, LightmapTexCoord01.pq)); - -#ifdef APPLY_LIGHTSTYLE2 -diffuseNormalModelspace = myhalf3 (texture2D (LightmapTexture2, vec2(LightmapTexCoord23.s+DeluxemapOffset2,LightmapTexCoord23.t))) - myhalf3 (0.5); -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -weightedDiffuseNormal += lsColor2 * diffuseNormal; -color.rgb += lsColor2 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture2, LightmapTexCoord23.st)); - -#ifdef APPLY_LIGHTSTYLE3 -diffuseNormalModelspace = myhalf3 (texture2D (LightmapTexture3, vec2(LightmapTexCoord23.p+DeluxemapOffset3,LightmapTexCoord23.q))) - myhalf3 (0.5);; -diffuseNormal = normalize (myhalf3(dot(diffuseNormalModelspace,myhalf3(strMatrix[0])),dot(diffuseNormalModelspace,myhalf3(strMatrix[1])),dot(diffuseNormalModelspace,myhalf3(strMatrix[2])))); -diffuseProduct = float (dot (surfaceNormal, diffuseNormal)); -weightedDiffuseNormal += lsColor3 * diffuseNormal; -color.rgb += lsColor3 * myhalf(max (diffuseProduct, 0.0)) * myhalf3 (texture2D (LightmapTexture3, LightmapTexCoord23.pq)); - -#endif -#endif -#endif + // 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 -specularNormal = normalize (myhalf3 (normalize (weightedDiffuseNormal)) + myhalf3 (normalize (EyeVector))); + myhalf3 specularNormal = normalize (myhalf3 (normalize (weightedDiffuseNormalModelspace)) + myhalf3 (normalize (u_EntityDist - v_Position))); #else -specularNormal = normalize (weightedDiffuseNormal + myhalf3 (normalize (EyeVector))); + myhalf3 specularNormal = normalize (weightedDiffuseNormalModelspace + myhalf3 (normalize (u_EntityDist - v_Position))); #endif -specularProduct = float (dot (surfaceNormal, specularNormal)); -color.rgb += (myhalf3(texture2D(GlossTexture, TexCoord)) * GlossIntensity) * pow(myhalf(max(specularProduct, 0.0)), GlossExponent); -#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 -#ifdef APPLY_BASETEX_ALPHA_ONLY -color = min(color, myhalf4(texture2D(BaseTexture, TexCoord).a)); +#if defined(APPLY_BASETEX_ALPHA_ONLY) && !defined(APPLY_DRAWFLAT) + color = min(color, myhalf4(qf_texture(u_BaseTexture, v_TexCoord).a)); #else -#ifdef APPLY_COLOR_CLAMPING -color = min(color, myhalf4(1.0)); -#endif -color = color * myhalf4(texture2D(BaseTexture, TexCoord)); + 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 -myhalf3 decal = myhalf3(gl_Color.rgb) * myhalf3(texture2D(DecalTexture, TexCoord)); -color.rgb = decal.rgb + color.rgb; -color.a = color.a * myhalf(gl_Color.a); + 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 -myhalf4 decal = myhalf4(gl_Color.rgba); -if (decal.a > 0.0) -{ -decal = decal * myhalf4(texture2D(DecalTexture, TexCoord)); -color.rgb = decal.rgb * decal.a + color.rgb * (1.0-decal.a); -} -#endif + 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 -color = color * myhalf4(gl_Color.rgba); -#endif -#ifdef APPLY_GRAYSCALE -float grey = dot(color, myhalf3(0.299, 0.587, 0.114)); -gl_FragColor = vec4(vec3(grey),color.a); +#if defined (APPLY_DIRECTIONAL_LIGHT) && defined(APPLY_DIRECTIONAL_LIGHT_MIX) + color = color; #else -gl_FragColor = vec4(color); + 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 - |