]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
fix two crashes introduced by vortex ( r11822 ) on sprites and nomodels
[xonotic/darkplaces.git] / gl_rmain.c
index 7a97a5c2dd2e7b341f893f2bf4c767ce56c0602a..9499f16c8611554e532c5a09f40c1e1b87a71ede 100644 (file)
@@ -50,8 +50,8 @@ static qboolean r_savedds;
 //
 r_refdef_t r_refdef;
 
-cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "screen motionblur - value represents intensity, somewhere around 0.5 recommended"};
-cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "screen motionblur based on damage - value represents intensity, somewhere around 0.5 recommended"};
+cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "screen motionblur - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
+cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "screen motionblur based on damage - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
 cvar_t r_motionblur_averaging = {CVAR_SAVE, "r_motionblur_averaging", "0.1", "sliding average reaction time for velocity (higher = slower adaption to change)"};
 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
 cvar_t r_motionblur_minblur = {CVAR_SAVE, "r_motionblur_minblur", "0.5", "factor of blur to apply at all times (always have this amount of blur no matter what the other factors are)"};
@@ -77,6 +77,8 @@ cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip pla
 cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
 cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
 cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"};
+cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"};
+cvar_t r_transparent_useplanardistance = {0, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"};
 cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%,  10 = 100%)"};
 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"};
@@ -130,6 +132,8 @@ cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0",
 cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
 cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
 cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
+cvar_t r_celshading = {CVAR_SAVE, "r_celshading", "0", "cartoon-style light shading (OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
+cvar_t r_celoutlines = {CVAR_SAVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred; OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
 
 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
@@ -147,6 +151,7 @@ cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to
 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
 
+cvar_t r_usedepthtextures = {CVAR_SAVE, "r_usedepthtextures", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on hardware"};
 cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"};
 cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
 cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
@@ -198,6 +203,7 @@ cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
+cvar_t r_bloom_scenebrightness = {CVAR_SAVE, "r_bloom_scenebrightness", "1", "global rendering brightness when bloom is enabled"};
 
 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
@@ -221,7 +227,7 @@ cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alon
 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
 cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
 
-cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer."};
+cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."};
 
 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
 
@@ -642,18 +648,17 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
        {"#define USEOFFSETMAPPING\n", " offsetmapping"},
        {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
        {"#define USESHADOWMAP2D\n", " shadowmap2d"},
-       {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"},
-       {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
-       {"#define USESHADOWSAMPLER\n", " shadowsampler"},
-       {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"},
+       {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
        {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
        {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
        {"#define USEALPHAKILL\n", " alphakill"},
        {"#define USEREFLECTCUBE\n", " reflectcube"},
        {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
        {"#define USEBOUNCEGRID\n", " bouncegrid"},
-       {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"},
+       {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
        {"#define USETRIPPY\n", " trippy"},
+       {"#define USEDEPTHRGB\n", " depthrgb"},
+       {"#define USEALPHAGENVERTEX\n", "alphagenvertex"}
 };
 
 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
@@ -737,7 +742,6 @@ typedef struct r_glsl_permutation_s
        int tex_Texture_Reflection;
        int tex_Texture_ShadowMap2D;
        int tex_Texture_CubeProjection;
-       int tex_Texture_ScreenDepth;
        int tex_Texture_ScreenNormalMap;
        int tex_Texture_ScreenDiffuse;
        int tex_Texture_ScreenSpecular;
@@ -768,7 +772,6 @@ typedef struct r_glsl_permutation_s
        int loc_Texture_Reflection;
        int loc_Texture_ShadowMap2D;
        int loc_Texture_CubeProjection;
-       int loc_Texture_ScreenDepth;
        int loc_Texture_ScreenNormalMap;
        int loc_Texture_ScreenDiffuse;
        int loc_Texture_ScreenSpecular;
@@ -850,15 +853,23 @@ enum
        SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5,  ///< postprocess uservec4 is enabled
        SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
        SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7,  ///< LOD for offsetmapping
+       SHADERSTATICPARM_SHADOWMAPPCF_1 = 8, ///< PCF 1
+       SHADERSTATICPARM_SHADOWMAPPCF_2 = 9, ///< PCF 2
+       SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
+       SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
+       SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
 };
-#define SHADERSTATICPARMS_COUNT 8
+#define SHADERSTATICPARMS_COUNT 13
 
 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
 static int shaderstaticparms_count = 0;
 
 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
-static qboolean R_CompileShader_CheckStaticParms(void)
+
+extern qboolean r_shadow_shadowmapsampler;
+extern int r_shadow_shadowmappcf;
+qboolean R_CompileShader_CheckStaticParms(void)
 {
        static int r_compileshader_staticparms_save[1];
        memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
@@ -884,6 +895,18 @@ static qboolean R_CompileShader_CheckStaticParms(void)
        }
        if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
                R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
+
+       if (r_shadow_shadowmapsampler)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWSAMPLER);
+       if (r_shadow_shadowmappcf > 1)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_2);
+       else if (r_shadow_shadowmappcf)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_1);
+       if (r_celshading.integer)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING);
+       if (r_celoutlines.integer)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINES);
+
        return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
 }
 
@@ -905,6 +928,11 @@ static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permu
        R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
        R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
        R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_1, "USESHADOWMAPPCF 1");
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_2, "USESHADOWMAPPCF 2");
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER");
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
 }
 
 /// information about each possible shader permutation
@@ -978,9 +1006,9 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
        int vertstrings_count = 0;
        int geomstrings_count = 0;
        int fragstrings_count = 0;
-       const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
-       const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
-       const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
+       const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
+       const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
 
        if (p->compiled)
                return;
@@ -1091,7 +1119,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                p->loc_Texture_Reflection         = qglGetUniformLocation(p->program, "Texture_Reflection");
                p->loc_Texture_ShadowMap2D        = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
                p->loc_Texture_CubeProjection     = qglGetUniformLocation(p->program, "Texture_CubeProjection");
-               p->loc_Texture_ScreenDepth        = qglGetUniformLocation(p->program, "Texture_ScreenDepth");
                p->loc_Texture_ScreenNormalMap    = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
                p->loc_Texture_ScreenDiffuse      = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
                p->loc_Texture_ScreenSpecular     = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
@@ -1179,7 +1206,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                p->tex_Texture_Reflection = -1;
                p->tex_Texture_ShadowMap2D = -1;
                p->tex_Texture_CubeProjection = -1;
-               p->tex_Texture_ScreenDepth = -1;
                p->tex_Texture_ScreenNormalMap = -1;
                p->tex_Texture_ScreenDiffuse = -1;
                p->tex_Texture_ScreenSpecular = -1;
@@ -1210,7 +1236,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                if (p->loc_Texture_Reflection      >= 0) {p->tex_Texture_Reflection       = sampler;qglUniform1i(p->loc_Texture_Reflection      , sampler);sampler++;}
                if (p->loc_Texture_ShadowMap2D     >= 0) {p->tex_Texture_ShadowMap2D      = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D     , sampler);sampler++;}
                if (p->loc_Texture_CubeProjection  >= 0) {p->tex_Texture_CubeProjection   = sampler;qglUniform1i(p->loc_Texture_CubeProjection  , sampler);sampler++;}
-               if (p->loc_Texture_ScreenDepth     >= 0) {p->tex_Texture_ScreenDepth      = sampler;qglUniform1i(p->loc_Texture_ScreenDepth     , sampler);sampler++;}
                if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap  = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
                if (p->loc_Texture_ScreenDiffuse   >= 0) {p->tex_Texture_ScreenDiffuse    = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse   , sampler);sampler++;}
                if (p->loc_Texture_ScreenSpecular  >= 0) {p->tex_Texture_ScreenSpecular   = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular  , sampler);sampler++;}
@@ -1590,9 +1615,9 @@ static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode
        int vertstrings_count = 0;
        int geomstrings_count = 0;
        int fragstrings_count = 0;
-       const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
-       const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
-       const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
+       const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
+       const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
 
        if (p->compiled)
                return;
@@ -1787,7 +1812,7 @@ static void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int per
        DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
 }
 
-static void R_GLSL_Restart_f(void)
+void R_GLSL_Restart_f(void)
 {
        unsigned int i, limit;
        if (glslshaderstring && glslshaderstring != builtinshaderstring)
@@ -1964,11 +1989,13 @@ void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
        R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
 }
 
-void R_SetupShader_DepthOrShadow(qboolean notrippy)
+void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb)
 {
        unsigned int permutation = 0;
        if (r_trippy.integer && !notrippy)
                permutation |= SHADERPERMUTATION_TRIPPY;
+       if (depthrgb)
+               permutation |= SHADERPERMUTATION_DEPTHRGB;
        if (vid.allowalphatocoverage)
                GL_AlphaToCoverage(false);
        switch (vid.renderpath)
@@ -2038,7 +2065,6 @@ void R_SetupShader_ShowDepth(qboolean notrippy)
 }
 
 extern qboolean r_shadow_usingdeferredprepass;
-extern cvar_t r_shadow_deferred_8bitrange;
 extern rtexture_t *r_shadow_attenuationgradienttexture;
 extern rtexture_t *r_shadow_attenuation2dtexture;
 extern rtexture_t *r_shadow_attenuation3dtexture;
@@ -2047,18 +2073,15 @@ extern qboolean r_shadow_usingshadowmaportho;
 extern float r_shadow_shadowmap_texturescale[2];
 extern float r_shadow_shadowmap_parameters[4];
 extern qboolean r_shadow_shadowmapvsdct;
-extern qboolean r_shadow_shadowmapsampler;
-extern int r_shadow_shadowmappcf;
-extern rtexture_t *r_shadow_shadowmap2dtexture;
-extern rtexture_t *r_shadow_shadowmap2dcolortexture;
+extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
+extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
 extern matrix4x4_t r_shadow_shadowmapmatrix;
 extern int r_shadow_shadowmaplod; // changes for each light based on distance
 extern int r_shadow_prepass_width;
 extern int r_shadow_prepass_height;
-extern rtexture_t *r_shadow_prepassgeometrydepthtexture;
+extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
-extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
 
@@ -2134,6 +2157,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
                {
                        mode = SHADERMODE_WATER;
+                       if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                               permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                        if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
                        {
                                // this is the right thing to do for wateralpha
@@ -2150,15 +2175,17 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
                {
                        mode = SHADERMODE_REFRACTION;
+                       if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                               permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                        blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                }
                else
                {
                        mode = SHADERMODE_GENERIC;
-                       permutation |= SHADERPERMUTATION_DIFFUSE;
-                       GL_BlendFunc(GL_ONE, GL_ZERO);
-                       blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
+                       permutation |= SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_ALPHAKILL;
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                       blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                }
                if (vid.allowalphatocoverage)
                        GL_AlphaToCoverage(false);
@@ -2198,6 +2225,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
                        permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
+               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                       permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                // light source
                mode = SHADERMODE_LIGHTSOURCE;
                if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
@@ -2216,12 +2245,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if(r_shadow_shadowmapvsdct)
                                permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
 
-                       if (r_shadow_shadowmapsampler)
-                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
-                       if (r_shadow_shadowmappcf > 1)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
-                       else if (r_shadow_shadowmappcf)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+                       if (r_shadow_shadowmap2ddepthbuffer)
+                               permutation |= SHADERPERMUTATION_DEPTHRGB;
                }
                if (rsurface.texture->reflectmasktexture)
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
@@ -2244,10 +2269,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
                        permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
+               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                       permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                // unshaded geometry (fullbright or ambient model lighting)
                mode = SHADERMODE_FLATCOLOR;
                ambientscale = diffusescale = specularscale = 0;
-               if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
+               if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
                        permutation |= SHADERPERMUTATION_GLOW;
                if (r_refdef.fogenabled)
                        permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
@@ -2258,12 +2285,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
                        permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
-                       if (r_shadow_shadowmapsampler)
-                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
-                       if (r_shadow_shadowmappcf > 1)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
-                       else if (r_shadow_shadowmappcf)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+                       if (r_shadow_shadowmap2ddepthbuffer)
+                               permutation |= SHADERPERMUTATION_DEPTHRGB;
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
@@ -2297,9 +2320,11 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
                        permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
+               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                       permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                // directional model lighting
                mode = SHADERMODE_LIGHTDIRECTION;
-               if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
+               if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
                        permutation |= SHADERPERMUTATION_GLOW;
                permutation |= SHADERPERMUTATION_DIFFUSE;
                if (specularscale > 0)
@@ -2313,12 +2338,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
                        permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
-                       if (r_shadow_shadowmapsampler)
-                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
-                       if (r_shadow_shadowmappcf > 1)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
-                       else if (r_shadow_shadowmappcf)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+                       if (r_shadow_shadowmap2ddepthbuffer)
+                               permutation |= SHADERPERMUTATION_DEPTHRGB;
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
@@ -2360,9 +2381,11 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
                        permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
+               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                       permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                // ambient model lighting
                mode = SHADERMODE_LIGHTDIRECTION;
-               if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
+               if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
                        permutation |= SHADERPERMUTATION_GLOW;
                if (r_refdef.fogenabled)
                        permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
@@ -2373,12 +2396,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
                        permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
-                       if (r_shadow_shadowmapsampler)
-                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
-                       if (r_shadow_shadowmappcf > 1)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
-                       else if (r_shadow_shadowmappcf)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+                       if (r_shadow_shadowmap2ddepthbuffer)
+                               permutation |= SHADERPERMUTATION_DEPTHRGB;
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
@@ -2420,8 +2439,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
                        permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
+               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+                       permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
                // lightmapped wall
-               if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
+               if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
                        permutation |= SHADERPERMUTATION_GLOW;
                if (r_refdef.fogenabled)
                        permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
@@ -2432,12 +2453,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
                        permutation |= SHADERPERMUTATION_SHADOWMAP2D;
 
-                       if (r_shadow_shadowmapsampler)
-                               permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
-                       if (r_shadow_shadowmappcf > 1)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
-                       else if (r_shadow_shadowmappcf)
-                               permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+                       if (r_shadow_shadowmap2ddepthbuffer)
+                               permutation |= SHADERPERMUTATION_DEPTHRGB;
                }
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
@@ -2560,8 +2577,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
-                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
+                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
                                hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
                        }
@@ -2570,8 +2587,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
-                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
                        }
                        // additive passes are only darkened by fog, not tinted
                        if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
@@ -2612,7 +2629,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
                                max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
                        );
-               hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
+               hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
                hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
                hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
                hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
@@ -2644,13 +2661,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
                }
-//             if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENDEPTH       , r_shadow_prepassgeometrydepthtexture                );
 //             if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
                if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
                if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
                if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
                {
-                       R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
+                       R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
                        if (rsurface.rtlight)
                        {
                                if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
@@ -2710,8 +2726,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
                                if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
                                if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
-                               if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
+                               if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
                                if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
                                if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
                        }
@@ -2720,8 +2736,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
                                if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
                                if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
-                               if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+                               if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
                        }
                        // additive passes are only darkened by fog, not tinted
                        if (r_glsl_permutation->loc_FogColor >= 0)
@@ -2774,7 +2790,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
                                max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
                        );
-               if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
+               if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
                if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
                if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
                if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
@@ -2811,13 +2827,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
                }
-               if (r_glsl_permutation->tex_Texture_ScreenDepth     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth       , r_shadow_prepassgeometrydepthtexture                );
                if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap   , r_shadow_prepassgeometrynormalmaptexture            );
                if (r_glsl_permutation->tex_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse     , r_shadow_prepasslightingdiffusetexture              );
                if (r_glsl_permutation->tex_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular    , r_shadow_prepasslightingspeculartexture             );
                if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
                {
-                       if (r_glsl_permutation->tex_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2dtexture                         );
+                       if (r_glsl_permutation->tex_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture                           );
                        if (rsurface.rtlight)
                        {
                                if (r_glsl_permutation->tex_Texture_Cube            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube              , rsurface.rtlight->currentcubemap                    );
@@ -2860,8 +2875,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
-                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
+                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
                        }
@@ -2870,8 +2885,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
                                DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
-                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+                               DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
                        }
                        // additive passes are only darkened by fog, not tinted
                        if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
@@ -2921,7 +2936,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
                                max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
                        );
-               DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
+               DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
                DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias);
                DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
                DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
@@ -2953,13 +2968,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
                }
-//             if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENDEPTH       , r_shadow_prepassgeometrydepthtexture                );
 //             if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
                if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
                if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
                if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
                {
-                       R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
+                       R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
                        if (rsurface.rtlight)
                        {
                                if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
@@ -2988,7 +3002,6 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
        matrix4x4_t viewtolight;
        matrix4x4_t lighttoview;
        float viewtolight16f[16];
-       float range = 1.0f / r_shadow_deferred_8bitrange.value;
        // light source
        mode = SHADERMODE_DEFERREDLIGHTSOURCE;
        if (rtlight->currentcubemap != r_texture_whitecube)
@@ -3003,12 +3016,8 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                if (r_shadow_shadowmapvsdct)
                        permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
 
-               if (r_shadow_shadowmapsampler)
-                       permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
-               if (r_shadow_shadowmappcf > 1)
-                       permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
-               else if (r_shadow_shadowmappcf)
-                       permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
+               if (r_shadow_shadowmap2ddepthbuffer)
+                       permutation |= SHADERPERMUTATION_DEPTHRGB;
        }
        if (vid.allowalphatocoverage)
                GL_AlphaToCoverage(false);
@@ -3023,9 +3032,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                R_SetupShader_SetPermutationHLSL(mode, permutation);
                hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
                hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
-               hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale  * range, lightcolorbase[1] * ambientscale  * range, lightcolorbase[2] * ambientscale  * range);
-               hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale  * range, lightcolorbase[1] * diffusescale  * range, lightcolorbase[2] * diffusescale  * range);
-               hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
+               hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
+               hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
+               hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
                hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
                hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
@@ -3033,10 +3042,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
 
                R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
-               R_Mesh_TexBind(GL20TU_SCREENDEPTH        , r_shadow_prepassgeometrydepthcolortexture           );
                R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
                R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
-               R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2dcolortexture                    );
+               R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2ddepthtexture                    );
                R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
 #endif
                break;
@@ -3051,9 +3059,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                R_SetupShader_SetPermutationGLSL(mode, permutation);
                if (r_glsl_permutation->loc_LightPosition             >= 0) qglUniform3f(       r_glsl_permutation->loc_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
                if (r_glsl_permutation->loc_ViewToLight               >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight              , 1, false, viewtolight16f);
-               if (r_glsl_permutation->loc_DeferredColor_Ambient     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale  * range, lightcolorbase[1] * ambientscale  * range, lightcolorbase[2] * ambientscale  * range);
-               if (r_glsl_permutation->loc_DeferredColor_Diffuse     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale  * range, lightcolorbase[1] * diffusescale  * range, lightcolorbase[2] * diffusescale  * range);
-               if (r_glsl_permutation->loc_DeferredColor_Specular    >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Specular   , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
+               if (r_glsl_permutation->loc_DeferredColor_Ambient     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
+               if (r_glsl_permutation->loc_DeferredColor_Diffuse     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
+               if (r_glsl_permutation->loc_DeferredColor_Specular    >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Specular   , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
                if (r_glsl_permutation->loc_ShadowMap_TextureScale    >= 0) qglUniform2f(       r_glsl_permutation->loc_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                if (r_glsl_permutation->loc_ShadowMap_Parameters      >= 0) qglUniform4f(       r_glsl_permutation->loc_ShadowMap_Parameters     , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
                if (r_glsl_permutation->loc_SpecularPower             >= 0) qglUniform1f(       r_glsl_permutation->loc_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
@@ -3061,10 +3069,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                if (r_glsl_permutation->loc_PixelToScreenTexCoord     >= 0) qglUniform2f(       r_glsl_permutation->loc_PixelToScreenTexCoord    , 1.0f/vid.width, 1.0f/vid.height);
 
                if (r_glsl_permutation->tex_Texture_Attenuation       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation        , r_shadow_attenuationgradienttexture                 );
-               if (r_glsl_permutation->tex_Texture_ScreenDepth       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth        , r_shadow_prepassgeometrydepthtexture                );
                if (r_glsl_permutation->tex_Texture_ScreenNormalMap   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap    , r_shadow_prepassgeometrynormalmaptexture            );
                if (r_glsl_permutation->tex_Texture_Cube              >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube               , rsurface.rtlight->currentcubemap                    );
-               if (r_glsl_permutation->tex_Texture_ShadowMap2D       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D        , r_shadow_shadowmap2dtexture                         );
+               if (r_glsl_permutation->tex_Texture_ShadowMap2D       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D        , r_shadow_shadowmap2ddepthtexture                    );
                if (r_glsl_permutation->tex_Texture_CubeProjection    >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection     , r_shadow_shadowmapvsdcttexture                      );
                break;
        case RENDERPATH_GL11:
@@ -3075,9 +3082,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                R_SetupShader_SetPermutationGLSL(mode, permutation);
                DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
                DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1            , 1, false, viewtolight16f);
-               DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale  * range, lightcolorbase[1] * ambientscale  * range, lightcolorbase[2] * ambientscale  * range);
-               DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale  * range, lightcolorbase[1] * diffusescale  * range, lightcolorbase[2] * diffusescale  * range);
-               DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Specular   , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
+               DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
+               DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
+               DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Specular   , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
                DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
                DPSOFTRAST_Uniform4f(       DPSOFTRAST_UNIFORM_ShadowMap_Parameters     , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
                DPSOFTRAST_Uniform1f(       DPSOFTRAST_UNIFORM_SpecularPower            , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
@@ -3085,10 +3092,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
 
                R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
-               R_Mesh_TexBind(GL20TU_SCREENDEPTH        , r_shadow_prepassgeometrydepthtexture                );
                R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
                R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
-               R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2dtexture                         );
+               R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2ddepthtexture                    );
                R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
                break;
        }
@@ -3305,7 +3311,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        Image_StripImageExtension(name, basename, sizeof(basename));
 
        // check for DDS texture file first
-       if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", basename), vid.sRGB3D, textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
+       if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", basename), vid.sRGB3D, textureflags, &ddshasalpha, ddsavgcolor, miplevel, false)))
        {
                basepixels = loadimagepixelsbgra(name, complain, true, false, &miplevel);
                if (basepixels == NULL)
@@ -3339,7 +3345,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                skinframe->hasalpha = ddshasalpha;
                VectorCopy(ddsavgcolor, skinframe->avgcolor);
                if (r_loadfog && skinframe->hasalpha)
-                       skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), false, textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
+                       skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), false, textureflags | TEXF_ALPHA, NULL, NULL, miplevel, true);
                //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
        }
        else
@@ -3386,13 +3392,13 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        {
                mymiplevel = savemiplevel;
                if (r_loadnormalmap)
-                       skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), false, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel);
-               skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+                       skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), false, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel, true);
+               skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
                if (r_loadgloss)
-                       skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
-               skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
-               skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
-               skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel);
+                       skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
+               skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
+               skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
+               skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
        }
 
        // _norm is the name used by tenebrae and has been adopted as standard
@@ -3506,7 +3512,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
 
        // if already loaded just return it, otherwise make a new skinframe
        skinframe = R_SkinFrame_Find(name, textureflags, width, height, (textureflags & TEXF_FORCE_RELOAD) ? -1 : skindata ? CRC_Block(skindata, width*height*4) : 0, true);
-       if (skinframe && skinframe->base)
+       if (skinframe->base)
                return skinframe;
        textureflags &= ~TEXF_FORCE_RELOAD;
 
@@ -3576,9 +3582,9 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i
 
        // if already loaded just return it, otherwise make a new skinframe
        skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
-       if (skinframe && skinframe->base)
+       if (skinframe->base)
                return skinframe;
-       textureflags &= ~TEXF_FORCE_RELOAD;
+       //textureflags &= ~TEXF_FORCE_RELOAD;
 
        skinframe->stain = NULL;
        skinframe->merged = NULL;
@@ -3700,7 +3706,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co
 
        // if already loaded just return it, otherwise make a new skinframe
        skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
-       if (skinframe && skinframe->base)
+       if (skinframe->base)
                return skinframe;
        textureflags &= ~TEXF_FORCE_RELOAD;
 
@@ -4184,6 +4190,8 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_deformvertexes);
        Cvar_RegisterVariable(&r_transparent);
        Cvar_RegisterVariable(&r_transparent_alphatocoverage);
+       Cvar_RegisterVariable(&r_transparent_sortsurfacesbynearest);
+       Cvar_RegisterVariable(&r_transparent_useplanardistance);
        Cvar_RegisterVariable(&r_showoverdraw);
        Cvar_RegisterVariable(&r_showbboxes);
        Cvar_RegisterVariable(&r_showsurfaces);
@@ -4238,6 +4246,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_texture_dds_save);
        Cvar_RegisterVariable(&r_textureunits);
        Cvar_RegisterVariable(&gl_combine);
+       Cvar_RegisterVariable(&r_usedepthtextures);
        Cvar_RegisterVariable(&r_viewfbo);
        Cvar_RegisterVariable(&r_viewscale);
        Cvar_RegisterVariable(&r_viewscale_fpsscaling);
@@ -4265,6 +4274,8 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_glsl_postprocess_uservec2_enable);
        Cvar_RegisterVariable(&r_glsl_postprocess_uservec3_enable);
        Cvar_RegisterVariable(&r_glsl_postprocess_uservec4_enable);
+       Cvar_RegisterVariable(&r_celshading);
+       Cvar_RegisterVariable(&r_celoutlines);
 
        Cvar_RegisterVariable(&r_water);
        Cvar_RegisterVariable(&r_water_resolutionmultiplier);
@@ -4287,6 +4298,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_bloom_resolution);
        Cvar_RegisterVariable(&r_bloom_colorexponent);
        Cvar_RegisterVariable(&r_bloom_colorsubtract);
+       Cvar_RegisterVariable(&r_bloom_scenebrightness);
        Cvar_RegisterVariable(&r_hdr_scenebrightness);
        Cvar_RegisterVariable(&r_hdr_glowintensity);
        Cvar_RegisterVariable(&r_hdr_irisadaptation);
@@ -4733,12 +4745,12 @@ static void R_View_UpdateEntityLighting (void)
        {
                ent = r_refdef.scene.entities[i];
 
-               // skip unseen models and models that updated by CSQC
-               if ((!r_refdef.viewcache.entityvisible[i] && skipunseen) || ent->flags & RENDER_CUSTOMIZEDMODELLIGHT)
+               // skip unseen models
+               if ((!r_refdef.viewcache.entityvisible[i] && skipunseen))
                        continue;
 
                // skip bsp models
-               if (ent->model && ent->model->brush.num_leafs)
+               if (ent->model && ent->model == cl.worldmodel)
                {
                        // TODO: use modellight for r_ambient settings on world?
                        VectorSet(ent->modellight_ambient, 0, 0, 0);
@@ -4746,74 +4758,83 @@ static void R_View_UpdateEntityLighting (void)
                        VectorSet(ent->modellight_lightdir, 0, 0, 1);
                        continue;
                }
-
-               // fetch the lighting from the worldmodel data
-               VectorClear(ent->modellight_ambient);
-               VectorClear(ent->modellight_diffuse);
-               VectorClear(tempdiffusenormal);
-               if (ent->flags & RENDER_LIGHT)
+               
+               if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT)
                {
-                       vec3_t org;
-                       Matrix4x4_OriginFromMatrix(&ent->matrix, org);
-
-                       // complete lightning for lit sprites
-                       // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
-                       if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
+                       // aleady updated by CSQC
+                       // TODO: force modellight on BSP models in this case?
+                       VectorCopy(ent->modellight_lightdir, tempdiffusenormal); 
+               }
+               else
+               {
+                       // fetch the lighting from the worldmodel data
+                       VectorClear(ent->modellight_ambient);
+                       VectorClear(ent->modellight_diffuse);
+                       VectorClear(tempdiffusenormal);
+                       if (ent->flags & RENDER_LIGHT)
                        {
-                               if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
-                                       org[2] = org[2] + r_overheadsprites_pushback.value;
-                               R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
-                       }
-                       else
-                               R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP);
+                               vec3_t org;
+                               Matrix4x4_OriginFromMatrix(&ent->matrix, org);
 
-                       if(ent->flags & RENDER_EQUALIZE)
-                       {
-                               // first fix up ambient lighting...
-                               if(r_equalize_entities_minambient.value > 0)
+                               // complete lightning for lit sprites
+                               // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
+                               if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
                                {
-                                       fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
-                                       if(fd > 0)
+                                       if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
+                                               org[2] = org[2] + r_overheadsprites_pushback.value;
+                                       R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
+                               }
+                               else
+                                       R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP);
+
+                               if(ent->flags & RENDER_EQUALIZE)
+                               {
+                                       // first fix up ambient lighting...
+                                       if(r_equalize_entities_minambient.value > 0)
                                        {
-                                               fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
-                                               if(fa < r_equalize_entities_minambient.value * fd)
+                                               fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
+                                               if(fd > 0)
                                                {
-                                                       // solve:
-                                                       //   fa'/fd' = minambient
-                                                       //   fa'+0.25*fd' = fa+0.25*fd
-                                                       //   ...
-                                                       //   fa' = fd' * minambient
-                                                       //   fd'*(0.25+minambient) = fa+0.25*fd
-                                                       //   ...
-                                                       //   fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
-                                                       //   fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
-                                                       //   ...
-                                                       fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
-                                                       f = fdd / fd; // f>0 because all this is additive; f<1 because fdd<fd because this follows from fa < r_equalize_entities_minambient.value * fd
-                                                       VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
-                                                       VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
+                                                       fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
+                                                       if(fa < r_equalize_entities_minambient.value * fd)
+                                                       {
+                                                               // solve:
+                                                               //   fa'/fd' = minambient
+                                                               //   fa'+0.25*fd' = fa+0.25*fd
+                                                               //   ...
+                                                               //   fa' = fd' * minambient
+                                                               //   fd'*(0.25+minambient) = fa+0.25*fd
+                                                               //   ...
+                                                               //   fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
+                                                               //   fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
+                                                               //   ...
+                                                               fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
+                                                               f = fdd / fd; // f>0 because all this is additive; f<1 because fdd<fd because this follows from fa < r_equalize_entities_minambient.value * fd
+                                                               VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
+                                                               VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
+                                                       }
                                                }
                                        }
-                               }
 
-                               if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
-                               {
-                                       fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
-                                       fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
-                                       f = fa + 0.25 * fd;
-                                       if(f > 0)
+                                       if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
                                        {
-                                               // adjust brightness and saturation to target
-                                               avg[0] = avg[1] = avg[2] = fa / f;
-                                               VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
-                                               avg[0] = avg[1] = avg[2] = fd / f;
-                                               VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
+                                               fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
+                                               fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
+                                               f = fa + 0.25 * fd;
+                                               if(f > 0)
+                                               {
+                                                       // adjust brightness and saturation to target
+                                                       avg[0] = avg[1] = avg[2] = fa / f;
+                                                       VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
+                                                       avg[0] = avg[1] = avg[2] = fd / f;
+                                                       VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
+                                               }
                                        }
                                }
                        }
+                       else // highly rare
+                               VectorSet(ent->modellight_ambient, 1, 1, 1);
                }
-               else // highly rare
-                       VectorSet(ent->modellight_ambient, 1, 1, 1);
 
                // move the light direction into modelspace coordinates for lighting code
                Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
@@ -5274,7 +5295,6 @@ static void R_View_UpdateWithScissor(const int *myscissor)
        R_View_WorldVisibility(r_refdef.view.useclipplane);
        R_View_UpdateEntityVisible();
        R_View_UpdateEntityLighting();
-       R_AnimCache_CacheVisibleEntities();
 }
 
 static void R_View_Update(void)
@@ -5284,7 +5304,6 @@ static void R_View_Update(void)
        R_View_WorldVisibility(r_refdef.view.useclipplane);
        R_View_UpdateEntityVisible();
        R_View_UpdateEntityLighting();
-       R_AnimCache_CacheVisibleEntities();
 }
 
 float viewscalefpsadjusted = 1.0f;
@@ -5383,13 +5402,14 @@ void R_EntityMatrix(const matrix4x4_t *matrix)
        }
 }
 
-void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+void R_ResetViewRendering2D_Common(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, float x2, float y2)
 {
        r_viewport_t viewport;
-       DrawQ_Finish();
+
+       CHECKGLERROR
 
        // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom
-       R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, 1, 1, -10, 100, NULL);
+       R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, x2, y2, -10, 100, NULL);
        R_Mesh_SetRenderTargets(fbo, depthtexture, colortexture, NULL, NULL, NULL);
        R_SetViewport(&viewport);
        GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
@@ -5421,6 +5441,15 @@ void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *color
                break;
        }
        GL_CullFace(GL_NONE);
+
+       CHECKGLERROR
+}
+
+void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+{
+       DrawQ_Finish();
+
+       R_ResetViewRendering2D_Common(fbo, depthtexture, colortexture, 1, 1);
 }
 
 void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
@@ -5464,7 +5493,7 @@ void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *color
 R_RenderView_UpdateViewVectors
 ================
 */
-static void R_RenderView_UpdateViewVectors(void)
+void R_RenderView_UpdateViewVectors(void)
 {
        // break apart the view matrix into vectors for various purposes
        // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong
@@ -5738,7 +5767,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                        if (usewaterfbo)
                        {
                                if (r_fb.water.depthtexture == NULL)
-                                       r_fb.water.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, 24, false, vid.support.ext_packed_depth_stencil);
+                                       r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
                                if (p->fbo_refraction == 0)
                                        p->fbo_refraction = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_refraction, NULL, NULL, NULL);
                        }
@@ -5752,7 +5781,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                        if (usewaterfbo)
                        {
                                if (r_fb.water.depthtexture == NULL)
-                                       r_fb.water.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, 24, false, vid.support.ext_packed_depth_stencil);
+                                       r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
                                if (p->fbo_camera == 0)
                                        p->fbo_camera = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_camera, NULL, NULL, NULL);
                        }
@@ -5767,7 +5796,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                        if (usewaterfbo)
                        {
                                if (r_fb.water.depthtexture == NULL)
-                                       r_fb.water.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, 24, false, vid.support.ext_packed_depth_stencil);
+                                       r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
                                if (p->fbo_reflection == 0)
                                        p->fbo_reflection = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_reflection, NULL, NULL, NULL);
                        }
@@ -5818,6 +5847,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                                R_View_UpdateWithScissor(myscissor);
                        else
                                R_View_Update();
+                       R_AnimCache_CacheVisibleEntities();
                        if(r_water_scissormode.integer & 1)
                                GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
                        R_RenderScene(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection);
@@ -5866,6 +5896,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                                R_View_UpdateWithScissor(myscissor);
                        else
                                R_View_Update();
+                       R_AnimCache_CacheVisibleEntities();
                        if(r_water_scissormode.integer & 1)
                                GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
                        R_RenderScene(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction);
@@ -5920,6 +5951,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                        R_ResetViewRendering3D(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera);
                        R_ClearScreen(r_refdef.fogenabled);
                        R_View_Update();
+                       R_AnimCache_CacheVisibleEntities();
                        R_RenderScene(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera);
 
                        if (!p->fbo_camera)
@@ -5935,6 +5967,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
        if (!r_fb.water.depthtexture)
                R_ClearScreen(r_refdef.fogenabled);
        R_View_Update();
+       R_AnimCache_CacheVisibleEntities();
        goto finish;
 error:
        r_refdef.view = originalview;
@@ -5971,7 +6004,7 @@ static void R_Bloom_StartFrame(void)
        switch (vid.renderpath)
        {
        case RENDERPATH_GL20:
-       case RENDERPATH_GLES2:
+               r_fb.usedepthtextures = r_usedepthtextures.integer != 0;
                if (vid.support.ext_framebuffer_object)
                {
                        if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F;
@@ -5981,10 +6014,14 @@ static void R_Bloom_StartFrame(void)
        case RENDERPATH_GL11:
        case RENDERPATH_GL13:
        case RENDERPATH_GLES1:
+       case RENDERPATH_GLES2:
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
+               r_fb.usedepthtextures = false;
+               break;
        case RENDERPATH_SOFT:
+               r_fb.usedepthtextures = true;
                break;
        }
 
@@ -6024,7 +6061,7 @@ static void R_Bloom_StartFrame(void)
 
        // set bloomwidth and bloomheight to the bloom resolution that will be
        // used (often less than the screen resolution for faster rendering)
-       r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, vid.height);
+       r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, vid.width);
        r_fb.bloomheight = r_fb.bloomwidth * vid.height / vid.width;
        r_fb.bloomheight = bound(1, r_fb.bloomheight, vid.height);
        r_fb.bloomwidth = bound(1, r_fb.bloomwidth, (int)vid.maxtexturesize_2d);
@@ -6112,22 +6149,9 @@ static void R_Bloom_StartFrame(void)
                        r_fb.colortexture = R_LoadTexture2D(r_main_texturepool, "framebuffercolor", r_fb.screentexturewidth, r_fb.screentextureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
                        if (useviewfbo)
                        {
-                               // FIXME: choose depth bits based on a cvar
-                               r_fb.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "framebufferdepth", r_fb.screentexturewidth, r_fb.screentextureheight, 24, false, vid.support.ext_packed_depth_stencil);
+                               r_fb.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "framebufferdepth", r_fb.screentexturewidth, r_fb.screentextureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
                                r_fb.fbo = R_Mesh_CreateFramebufferObject(r_fb.depthtexture, r_fb.colortexture, NULL, NULL, NULL);
                                R_Mesh_SetRenderTargets(r_fb.fbo, r_fb.depthtexture, r_fb.colortexture, NULL, NULL, NULL);
-#ifndef USE_GLES2
-                               // render depth into one texture and color into the other
-                               if (qglDrawBuffer)
-                               {
-                                       int status;
-                                       qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
-                                       qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
-                                       status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR
-                                       if (status != GL_FRAMEBUFFER_COMPLETE)
-                                               Con_Printf("R_Bloom_StartFrame: glCheckFramebufferStatusEXT returned %i\n", status);
-                               }
-#endif
                        }
                }
 
@@ -6143,7 +6167,7 @@ static void R_Bloom_StartFrame(void)
        }
 
        // bloom texture is a different resolution
-       r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, r_refdef.view.height);
+       r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, r_refdef.view.width);
        r_fb.bloomheight = r_fb.bloomwidth * r_refdef.view.height / r_refdef.view.width;
        r_fb.bloomheight = bound(1, r_fb.bloomheight, r_refdef.view.height);
        r_fb.bloomwidth = bound(1, r_fb.bloomwidth, r_fb.bloomtexturewidth);
@@ -6160,6 +6184,14 @@ static void R_Bloom_StartFrame(void)
        r_fb.screentexcoord2f[6] = 0;
        r_fb.screentexcoord2f[7] = 0;
 
+       if(r_fb.fbo) 
+       {
+               for (i = 1;i < 8;i += 2)
+               {
+                       r_fb.screentexcoord2f[i] += 1 - (float)(viewheight + r_refdef.view.y) / (float)r_fb.screentextureheight;
+               }
+       }
+
        // set up a texcoord array for the reduced resolution bloom image
        // (which will be additive blended over the screen image)
        r_fb.bloomtexcoord2f[0] = 0;
@@ -6183,20 +6215,17 @@ static void R_Bloom_StartFrame(void)
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
+               for (i = 0;i < 4;i++)
                {
-                       int i;
-                       for (i = 0;i < 4;i++)
-                       {
-                               r_fb.screentexcoord2f[i*2+0] += 0.5f / (float)r_fb.screentexturewidth;
-                               r_fb.screentexcoord2f[i*2+1] += 0.5f / (float)r_fb.screentextureheight;
-                               r_fb.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_fb.bloomtexturewidth;
-                               r_fb.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_fb.bloomtextureheight;
-                       }
+                       r_fb.screentexcoord2f[i*2+0] += 0.5f / (float)r_fb.screentexturewidth;
+                       r_fb.screentexcoord2f[i*2+1] += 0.5f / (float)r_fb.screentextureheight;
+                       r_fb.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_fb.bloomtexturewidth;
+                       r_fb.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_fb.bloomtextureheight;
                }
                break;
        }
 
-       R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, r_refdef.view.x, (r_fb.bloomfbo[0] ? r_fb.bloomtextureheight : vid.height) - r_fb.bloomheight - r_refdef.view.y, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL);
+       R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, 0, 0, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL);
 
        if (r_fb.fbo)
                r_refdef.view.clear = true;
@@ -6210,18 +6239,22 @@ static void R_Bloom_MakeTexture(void)
        float colorscale = r_bloom_colorscale.value;
 
        r_refdef.stats.bloom++;
-
+    
+#if 0
+    // this copy is unnecessary since it happens in R_BlendView already
        if (!r_fb.fbo)
        {
                R_Mesh_CopyToTexture(r_fb.colortexture, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
                r_refdef.stats.bloom_copypixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
        }
+#endif
 
        // scale down screen texture to the bloom texture size
        CHECKGLERROR
        r_fb.bloomindex = 0;
        R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL);
        R_SetViewport(&r_fb.bloomviewport);
+       GL_DepthTest(false);
        GL_BlendFunc(GL_ONE, GL_ZERO);
        GL_Color(colorscale, colorscale, colorscale, 1);
        // D3D has upside down Y coords, the easiest way to flip this is to flip the screen vertices rather than the texcoords, so we just use a different array for that...
@@ -6261,9 +6294,19 @@ static void R_Bloom_MakeTexture(void)
                r_fb.bloomindex ^= 1;
                R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL);
                x *= 2;
-               r = bound(0, r_bloom_colorexponent.value / x, 1);
-               GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
-               GL_Color(r,r,r,1);
+               r = bound(0, r_bloom_colorexponent.value / x, 1); // always 0.5 to 1
+               if (!r_fb.bloomfbo[r_fb.bloomindex])
+               {
+                       GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); // square it and multiply by two
+                       GL_Color(r,r,r,1); // apply fix factor
+               }
+               else
+               {
+                       if(x <= 2)
+                               GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
+                       GL_BlendFunc(GL_SRC_COLOR, GL_ZERO); // square it
+                       GL_Color(1,1,1,1); // no fix factor supported here
+               }
                R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_fb.bloomtexcoord2f);
                R_SetupShader_Generic(intex, NULL, GL_MODULATE, 1, false, true, false);
                R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
@@ -6300,14 +6343,14 @@ static void R_Bloom_MakeTexture(void)
                        xoffset /= (float)r_fb.bloomtexturewidth;
                        yoffset /= (float)r_fb.bloomtextureheight;
                        // compute a texcoord array with the specified x and y offset
-                       r_fb.offsettexcoord2f[0] = xoffset+0;
-                       r_fb.offsettexcoord2f[1] = yoffset+(float)r_fb.bloomheight / (float)r_fb.bloomtextureheight;
-                       r_fb.offsettexcoord2f[2] = xoffset+(float)r_fb.bloomwidth / (float)r_fb.bloomtexturewidth;
-                       r_fb.offsettexcoord2f[3] = yoffset+(float)r_fb.bloomheight / (float)r_fb.bloomtextureheight;
-                       r_fb.offsettexcoord2f[4] = xoffset+(float)r_fb.bloomwidth / (float)r_fb.bloomtexturewidth;
-                       r_fb.offsettexcoord2f[5] = yoffset+0;
-                       r_fb.offsettexcoord2f[6] = xoffset+0;
-                       r_fb.offsettexcoord2f[7] = yoffset+0;
+                       r_fb.offsettexcoord2f[0] = xoffset+r_fb.bloomtexcoord2f[0];
+                       r_fb.offsettexcoord2f[1] = yoffset+r_fb.bloomtexcoord2f[1];
+                       r_fb.offsettexcoord2f[2] = xoffset+r_fb.bloomtexcoord2f[2];
+                       r_fb.offsettexcoord2f[3] = yoffset+r_fb.bloomtexcoord2f[3];
+                       r_fb.offsettexcoord2f[4] = xoffset+r_fb.bloomtexcoord2f[4];
+                       r_fb.offsettexcoord2f[5] = yoffset+r_fb.bloomtexcoord2f[5];
+                       r_fb.offsettexcoord2f[6] = xoffset+r_fb.bloomtexcoord2f[6];
+                       r_fb.offsettexcoord2f[7] = yoffset+r_fb.bloomtexcoord2f[7];
                        // this r value looks like a 'dot' particle, fading sharply to
                        // black at the edges
                        // (probably not realistic but looks good enough)
@@ -6674,6 +6717,10 @@ void R_UpdateVariables(void)
        {
                r_refdef.lightmapintensity *= r_fakelight_intensity.value;
        }
+       else if (r_refdef.scene.worldmodel)
+       {
+               r_refdef.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale;
+       }
        if (r_showsurfaces.integer)
        {
                r_refdef.scene.rtworld = false;
@@ -6863,11 +6910,21 @@ void R_RenderView(void)
 
        r_refdef.view.colorscale = r_hdr_scenebrightness.value * r_hdr_irisadaptation_value.value;
 
+       if(vid_sRGB.integer && vid_sRGB_fallback.integer && !vid.sRGB3D)
+               // in sRGB fallback, behave similar to true sRGB: convert this
+               // value from linear to sRGB
+               r_refdef.view.colorscale = Image_sRGBFloatFromLinearFloat(r_refdef.view.colorscale);
+
        R_RenderView_UpdateViewVectors();
 
        R_Shadow_UpdateWorldLightSelection();
 
        R_Bloom_StartFrame();
+
+       // apply bloom brightness offset
+       if(r_fb.bloomtexture[0])
+               r_refdef.view.colorscale *= r_bloom_scenebrightness.value;
+
        R_Water_StartFrame();
 
        // now we probably have an fbo to render into
@@ -6895,6 +6952,10 @@ void R_RenderView(void)
        if (r_timereport_active)
                R_TimeReport("visibility");
 
+       R_AnimCache_CacheVisibleEntities();
+       if (r_timereport_active)
+               R_TimeReport("animcache");
+
        R_Shadow_UpdateBounceGridTexture();
        if (r_timereport_active && r_shadow_bouncegrid.integer)
                R_TimeReport("bouncegrid");
@@ -7263,6 +7324,7 @@ static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtligh
                        case SOLID_BBOX:     Vector4Set(color, 0, 1, 0, 0.10);break;
                        case SOLID_SLIDEBOX: Vector4Set(color, 1, 0, 0, 0.10);break;
                        case SOLID_BSP:      Vector4Set(color, 0, 0, 1, 0.05);break;
+                       case SOLID_CORPSE:   Vector4Set(color, 1, 0.5, 0, 0.05);break;
                        default:             Vector4Set(color, 0, 0, 0, 0.50);break;
                }
                color[3] *= r_showbboxes.value;
@@ -7295,7 +7357,7 @@ static void R_DrawEntityBBoxes(void)
                if(PRVM_serveredictedict(edict, viewmodelforclient) != 0)
                        continue;
                VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
-               R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
+               R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
        }
 }
 
@@ -7403,12 +7465,12 @@ void R_DrawNoModel(entity_render_t *ent)
        vec3_t org;
        Matrix4x4_OriginFromMatrix(&ent->matrix, org);
        if ((ent->flags & RENDER_ADDITIVE) || (ent->alpha < 1))
-               R_MeshQueue_AddTransparent(ent->flags & RENDER_NODEPTHTEST ? r_refdef.view.origin : org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight);
+               R_MeshQueue_AddTransparent((ent->flags & RENDER_NODEPTHTEST) ? TRANSPARENTSORT_HUD : TRANSPARENTSORT_DISTANCE, org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight);
        else
                R_DrawNoModel_TransparentCallback(ent, rsurface.rtlight, 0, NULL);
 }
 
-void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
+void R_CalcBeam_Vertex3f (float *vert, const float *org1, const float *org2, float width)
 {
        vec3_t right1, right2, diff, normal;
 
@@ -7711,15 +7773,15 @@ texture_t *R_GetCurrentTexture(texture_t *t)
 {
        int i;
        const entity_render_t *ent = rsurface.entity;
-       dp_model_t *model = ent->model;
+       dp_model_t *model = ent->model; // when calling this, ent must not be NULL
        q3shaderinfo_layer_tcmod_t *tcmod;
 
-       if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent)
+       if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent && !rsurface.forcecurrenttextureupdate)
                return t->currentframe;
        t->update_lastrenderframe = r_textureframe;
        t->update_lastrenderentity = (void *)ent;
 
-       if(ent && ent->entitynumber >= MAX_EDICTS && ent->entitynumber < 2 * MAX_EDICTS)
+       if(ent->entitynumber >= MAX_EDICTS && ent->entitynumber < 2 * MAX_EDICTS)
                t->camera_entity = ent->entitynumber;
        else
                t->camera_entity = 0;
@@ -7787,7 +7849,7 @@ texture_t *R_GetCurrentTexture(texture_t *t)
        {
                // no modellight if using fakelight for the map
        }
-       else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
+       else if ((rsurface.modeltexcoordlightmap2f == NULL || (rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT))) && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
        {
                // pick a model lighting mode
                if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f))
@@ -7863,6 +7925,11 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                t->backgroundglowtexture = t->backgroundcurrentskinframe->glow;
                if (!t->backgroundnmaptexture)
                        t->backgroundnmaptexture = r_texture_blanknormalmap;
+               // make sure that if glow is going to be used, both textures are not NULL
+               if (!t->backgroundglowtexture && t->glowtexture)
+                       t->backgroundglowtexture = r_texture_black;
+               if (!t->glowtexture && t->backgroundglowtexture)
+                       t->glowtexture = r_texture_black;
        }
        else
        {
@@ -7946,7 +8013,7 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                        blendfunc2 = GL_ZERO;
                }
                // don't colormod evilblend textures
-               if(!R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD)
+               if(!(R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD))
                        VectorSet(t->lightmapcolor, 1, 1, 1);
                depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
                if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
@@ -8124,6 +8191,7 @@ void RSurf_ActiveWorldEntity(void)
        rsurface.passcolor4f = NULL;
        rsurface.passcolor4f_vertexbuffer = NULL;
        rsurface.passcolor4f_bufferoffset = 0;
+       rsurface.forcecurrenttextureupdate = false;
 }
 
 void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass)
@@ -8297,6 +8365,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
        rsurface.passcolor4f = NULL;
        rsurface.passcolor4f_vertexbuffer = NULL;
        rsurface.passcolor4f_bufferoffset = 0;
+       rsurface.forcecurrenttextureupdate = false;
 }
 
 void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents)
@@ -8420,6 +8489,7 @@ void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inve
        rsurface.passcolor4f = NULL;
        rsurface.passcolor4f_vertexbuffer = NULL;
        rsurface.passcolor4f_bufferoffset = 0;
+       rsurface.forcecurrenttextureupdate = true;
 
        if (rsurface.modelnumvertices && rsurface.modelelement3i)
        {
@@ -9430,7 +9500,7 @@ static void RSurf_DrawBatch_GL11_ApplyFog(void)
                rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
                rsurface.passcolor4f_vertexbuffer = 0;
                rsurface.passcolor4f_bufferoffset = 0;
-               for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4, c2 += 4)
+               for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4, c2 += 4)
                {
                        f = RSurf_FogVertex(v);
                        c2[0] = c[0] * f;
@@ -9724,7 +9794,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_
                R_Mesh_ResetTextureState();
                if (skyrendermasked)
                {
-                       R_SetupShader_DepthOrShadow(false);
+                       R_SetupShader_DepthOrShadow(false, false);
                        // depth-only (masking)
                        GL_ColorMask(0,0,0,0);
                        // just to make sure that braindead drivers don't draw
@@ -9908,8 +9978,8 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface
                        R_Mesh_TexBind(1, 0);
                        R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
                        // generate a color array for the fog pass
-                       R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
                        RSurf_DrawBatch_GL11_MakeFogColor(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
+                       R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
                        RSurf_DrawBatch();
                        break;
                default:
@@ -9951,7 +10021,7 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface
                switch (layer->type)
                {
                case TEXTURELAYERTYPE_LITTEXTURE:
-                       if (layer->blendfunc1 == GL_ONE && layer->blendfunc2 == GL_ZERO)
+                       if (layer->blendfunc1 == GL_ONE && layer->blendfunc2 == GL_ZERO && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))
                        {
                                // two-pass lit texture with 2x rgbscale
                                // first the lightmap pass
@@ -9984,6 +10054,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface
                                R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
                                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
                                        RSurf_DrawBatch_GL11_VertexShade(layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
+                               else if (FAKELIGHT_ENABLED)
+                                       RSurf_DrawBatch_GL11_FakeLight(layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
                                else
                                        RSurf_DrawBatch_GL11_VertexColor(layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
                        }
@@ -10011,8 +10083,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface
                                R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
                        }
                        // generate a color array for the fog pass
-                       R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
                        RSurf_DrawBatch_GL11_MakeFogColor(layer->color[0], layer->color[1], layer->color[2], layer->color[3]);
+                       R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
                        RSurf_DrawBatch();
                        break;
                default:
@@ -10342,7 +10414,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const
                                GL_BlendFunc(GL_ONE, GL_ZERO);
                                GL_DepthMask(true);
 //                             R_Mesh_ResetTextureState();
-                               R_SetupShader_DepthOrShadow(false);
+                               R_SetupShader_DepthOrShadow(false, false);
                        }
                        RSurf_SetupDepthAndCulling();
                        RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
@@ -10401,7 +10473,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 }
 
-static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity)
+static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist)
 {
        // transparent surfaces get pushed off into the transparent queue
        int surfacelistindex;
@@ -10410,17 +10482,26 @@ static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const
        for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++)
        {
                surface = texturesurfacelist[surfacelistindex];
-               tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
-               tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
-               tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
+               if (r_transparent_sortsurfacesbynearest.integer)
+               {
+                       tempcenter[0] = bound(surface->mins[0], rsurface.localvieworigin[0], surface->maxs[0]);
+                       tempcenter[1] = bound(surface->mins[1], rsurface.localvieworigin[1], surface->maxs[1]);
+                       tempcenter[2] = bound(surface->mins[2], rsurface.localvieworigin[2], surface->maxs[2]);
+               }
+               else
+               {
+                       tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
+                       tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
+                       tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
+               }
                Matrix4x4_Transform(&rsurface.matrix, tempcenter, center);
-               if (queueentity->transparent_offset) // transparent offset
+               if (rsurface.entity->transparent_offset) // transparent offset
                {
-                       center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset;
-                       center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset;
-                       center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset;
+                       center[0] += r_refdef.view.forward[0]*rsurface.entity->transparent_offset;
+                       center[1] += r_refdef.view.forward[1]*rsurface.entity->transparent_offset;
+                       center[2] += r_refdef.view.forward[2]*rsurface.entity->transparent_offset;
                }
-               R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight);
+               R_MeshQueue_AddTransparent((rsurface.entity->flags & RENDER_WORLDOBJECT) ? TRANSPARENTSORT_SKY : (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? TRANSPARENTSORT_HUD : rsurface.texture->transparentsort, center, R_DrawSurface_TransparentCallback, rsurface.entity, surface - rsurface.modelsurfaces, rsurface.rtlight);
        }
 }
 
@@ -10441,7 +10522,6 @@ static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msu
 
 static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
 {
-       const entity_render_t *queueentity = r_refdef.scene.worldentity;
        CHECKGLERROR
        if (depthonly)
                R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
@@ -10450,7 +10530,7 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf
                if (!rsurface.texture->currentnumlayers)
                        return;
                if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
-                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
                else
                        R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
        }
@@ -10458,11 +10538,11 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf
                R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
        else if (!rsurface.texture->currentnumlayers)
                return;
-       else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
+       else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))))
        {
                // in the deferred case, transparent surfaces were queued during prepass
                if (!r_shadow_usingdeferredprepass)
-                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
        }
        else
        {
@@ -10518,7 +10598,7 @@ static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacel
        R_FrameData_ReturnToMark();
 }
 
-static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, const entity_render_t *queueentity, qboolean prepass)
+static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
 {
        CHECKGLERROR
        if (depthonly)
@@ -10528,7 +10608,7 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf
                if (!rsurface.texture->currentnumlayers)
                        return;
                if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
-                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
                else
                        R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
        }
@@ -10536,11 +10616,11 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf
                R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
        else if (!rsurface.texture->currentnumlayers)
                return;
-       else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
+       else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))))
        {
                // in the deferred case, transparent surfaces were queued during prepass
                if (!r_shadow_usingdeferredprepass)
-                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
        }
        else
        {
@@ -10591,7 +10671,7 @@ static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const
                                ;
                }
                // render the range of surfaces
-               R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass);
+               R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass);
        }
        R_FrameData_ReturnToMark();
 }
@@ -10668,7 +10748,7 @@ void R_DrawLocs(void)
        for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++)
        {
                VectorLerp(loc->mins, 0.5f, loc->maxs, center);
-               R_MeshQueue_AddTransparent(center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL);
+               R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL);
        }
 }
 
@@ -11113,7 +11193,6 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
        else
                frametime = 0;
        decalsystem->lastupdatetime = r_refdef.scene.time;
-       decal = decalsystem->decals;
        numdecals = decalsystem->numdecals;
 
        for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
@@ -11190,7 +11269,6 @@ static void R_DrawModelDecals_Entity(entity_render_t *ent)
                RSurf_ActiveModelEntity(ent, false, false, false);
 
        decalsystem->lastupdatetime = r_refdef.scene.time;
-       decal = decalsystem->decals;
 
        faderate = 1.0f / max(0.001f, cl_decals_fadetime.value);
 
@@ -11379,13 +11457,12 @@ static void R_DrawDebugModel(void)
        {
                int triangleindex;
                int bihleafindex;
-               qboolean cullbox = ent == r_refdef.scene.worldentity;
+               qboolean cullbox = false;
                const q3mbrush_t *brush;
                const bih_t *bih = &model->collision_bih;
                const bih_leaf_t *bihleaf;
                float vertex3f[3][3];
                GL_PolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);
-               cullbox = false;
                for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
                {
                        if (cullbox && R_CullBox(bihleaf->mins, bihleaf->maxs))
@@ -11758,10 +11835,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr
                        }
                }
        }
-       if (update)
-               for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
-                       if (update[j])
-                               R_BuildLightMap(ent, surfaces + j);
+
        R_QueueModelSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
 
        // add to stats if desired