]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
make sure another way it never calculates 0^0
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 29 Aug 2011 15:23:33 +0000 (15:23 +0000)
committerRudolf Polzer <divVerent@xonotic.org>
Mon, 29 Aug 2011 15:48:48 +0000 (17:48 +0200)
we now avoid too-small exponents instead (alpha 0 now is exponent 1, not 0)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11306 d7cf8633-e32d-0410-b094-e92efae38249
::stable-branch::merge=396cf70d81c18e96fa85b476add470385b7409c3

dpsoftrast.c
gl_rmain.c
shader_glsl.h
shader_hlsl.h

index d1cde7a915720f724a12d8f4bc72495a6b879f4b..0e125a915363c6918f4c019ffb31e71d81856742 100644 (file)
@@ -107,8 +107,6 @@ static void *MM_CALLOC(size_t nmemb, size_t size)
 #define MM_FREE free
 #endif
 
-#define DPSOFTRAST_FLT_MIN 0.000000000000000001f
-
 typedef enum DPSOFTRAST_ARRAY_e
 {
        DPSOFTRAST_ARRAY_POSITION,
@@ -3844,6 +3842,7 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons
                                DPSOFTRAST_Vector3Normalize(eyenormal);
 
                                specular = DPSOFTRAST_Vector3Dot(eyenormal, specularnormal);if (specular < 0.0f) specular = 0.0f;
+                               specular = pow(specular, 0.25f + SpecularPower * glosstex[3]);
                        }
                        else
                        {
@@ -3857,10 +3856,10 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons
                                specularnormal[2] = lightnormal[2] + eyenormal[2];
                                DPSOFTRAST_Vector3Normalize(specularnormal);
 
-                               specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < DPSOFTRAST_FLT_MIN) specular = DPSOFTRAST_FLT_MIN;
+                               specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < 0.0f) specular = 0.0f;
+                               specular = pow(specular, 1.0f + SpecularPower * glosstex[3]);
                        }
 
-                       specular = pow(specular, SpecularPower * glosstex[3]);
                        if (thread->shader_permutation & SHADERPERMUTATION_GLOW)
                        {
                                d[0] = (int)(buffer_texture_glowbgra8[x*4+0] * Color_Glow[0] + diffusetex[0] * Color_Ambient[0] + (diffusetex[0] * Color_Diffuse[0] * diffuse + glosstex[0] * Color_Specular[0] * specular) * LightColor[0]);if (d[0] > 255) d[0] = 255;
@@ -4253,6 +4252,7 @@ void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const D
                                DPSOFTRAST_Vector3Normalize(eyenormal);
 
                                specular = DPSOFTRAST_Vector3Dot(eyenormal, specularnormal);if (specular < 0.0f) specular = 0.0f;
+                               specular = pow(specular, 0.25f + SpecularPower * glosstex[3]);
                        }
                        else
                        {
@@ -4266,9 +4266,9 @@ void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const D
                                specularnormal[2] = lightnormal[2] + eyenormal[2];
                                DPSOFTRAST_Vector3Normalize(specularnormal);
 
-                               specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < DPSOFTRAST_FLT_MIN) specular = DPSOFTRAST_FLT_MIN;
+                               specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < 0.0f) specular = 0.0f;
+                               specular = pow(specular, 1.0f + SpecularPower * glosstex[3]);
                        }
-                       specular = pow(specular, SpecularPower * glosstex[3]);
 
                        if (thread->shader_permutation & SHADERPERMUTATION_CUBEFILTER)
                        {
index 68bfb4aa888dc9bd7072b55618055f7853de3211..bcce7a17c6b8d0a0bbe14b16dbd7d7a771f7410d 100644 (file)
@@ -2553,7 +2553,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
 
                        // additive passes are only darkened by fog, not tinted
                        hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
-                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                }
                else
                {
@@ -2591,7 +2591,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
-                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                        if (mode == SHADERMODE_WATER)
                                hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
                }
@@ -2701,7 +2701,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        // additive passes are only darkened by fog, not tinted
                        if (r_glsl_permutation->loc_FogColor >= 0)
                                qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
-                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                }
                else
                {
@@ -2742,7 +2742,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
-                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                        if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
                }
                if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
@@ -2849,7 +2849,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
        
                        // additive passes are only darkened by fog, not tinted
                        DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
-                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                }
                else
                {
@@ -2887,7 +2887,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
                        DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
                        DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
-                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+                       DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                        DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
                }
                {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
@@ -3028,7 +3028,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
                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));
+               hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, ((r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                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);
 
@@ -3056,7 +3056,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                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_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));
+               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) - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                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);
 
@@ -3080,7 +3080,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
                DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Specular   , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
                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));
+               DPSOFTRAST_Uniform1f(       DPSOFTRAST_UNIFORM_SpecularPower            , ((r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
                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);
 
index 57ce3d5d26df36c10ac735c621b87c5d31b3fcc1..13ba602b119e98970ec493744fc035ce6954f204 100644 (file)
@@ -43,9 +43,6 @@
 "#define highp\n"
 "#endif\n"
 "\n"
-"// not REALLY the smallest value (2^-62 would be correct), but short and any compiler failing at parsing this is broken\n"
-"#define FLT_MIN 0.000000000000000001\n"
-"\n"
 "#ifdef VERTEX_SHADER\n"
 "dp_attribute vec4 Attrib_Position;  // vertex\n"
 "dp_attribute vec4 Attrib_Color;     // color\n"
 "      // calculate directional shading\n"
 "      vec3 eyevector = position * -1.0;\n"
 "#  ifdef USEEXACTSPECULARMATH\n"
-"      myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, FLT_MIN)), SpecularPower * normalmap.a);\n"
+"      myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), 0.25 + SpecularPower * normalmap.a);\n"
 "#  else\n"
 "      myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(eyevector)));\n"
-"      myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), FLT_MIN)), SpecularPower * normalmap.a);\n"
+"      myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * normalmap.a);\n"
 "#  endif\n"
 "#endif\n"
 "\n"
 "      color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
 "#ifdef USESPECULAR\n"
 "#ifdef USEEXACTSPECULARMATH\n"
-"      myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, FLT_MIN)), SpecularPower * glosstex.a);\n"
+"      myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, 0.0)), 0.25 + SpecularPower * glosstex.a);\n"
 "#else\n"
 "      myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(EyeVectorFogDepth.xyz)));\n"
-"      myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), FLT_MIN)), SpecularPower * glosstex.a);\n"
+"      myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a);\n"
 "#endif\n"
 "      color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
 "#endif\n"
 "      myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
 "#  ifdef USESPECULAR\n"
 "#   ifdef USEEXACTSPECULARMATH\n"
-"      myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, FLT_MIN)), SpecularPower * glosstex.a);\n"
+"      myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, 0.0)), 0.25 + SpecularPower * glosstex.a);\n"
 "#   else\n"
 "      myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(EyeVectorFogDepth.xyz)));\n"
-"      myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), FLT_MIN)), SpecularPower * glosstex.a);\n"
+"      myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a);\n"
 "#   endif\n"
 "      color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
 "#  else\n"
index 2fa3e6d7c0f89f5f46308896444a29a53a6b8fce..9fc3b6e8bdb0c1ae99587bab46d560410f9e8dcb 100644 (file)
@@ -2,9 +2,6 @@
 "// written by Forest 'LordHavoc' Hale\n"
 "// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
 "\n"
-"// not REALLY the smallest value (2^-62 would be correct), but short and any compiler failing at parsing this is broken\n"
-"#define FLT_MIN 0.000000000000000001\n"
-"\n"
 "// FIXME: we need to get rid of ModelViewProjectionPosition to make room for the texcoord for this\n"
 "#if defined(USEREFLECTION)\n"
 "#undef USESHADOWMAPORTHO\n"
 "      // calculate directional shading\n"
 "      float3 eyevector = position * -1.0;\n"
 "#  ifdef USEEXACTSPECULARMATH\n"
-"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, FLT_MIN)), SpecularPower * normalmap.a));\n"
+"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), 0.25 + SpecularPower * normalmap.a));\n"
 "#  else\n"
 "      half3 specularnormal = half3(normalize(lightnormal + half3(normalize(eyevector))));\n"
-"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), FLT_MIN)), SpecularPower * normalmap.a));\n"
+"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * normalmap.a));\n"
 "#  endif\n"
 "#endif\n"
 "\n"
 "      color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
 "#ifdef USESPECULAR\n"
 "#ifdef USEEXACTSPECULARMATH\n"
-"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, FLT_MIN)), SpecularPower * glosstex.a));\n"
+"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), 0.25 + SpecularPower * glosstex.a));\n"
 "#else\n"
 "      half3 specularnormal = half3(normalize(lightnormal + half3(normalize(EyeVector))));\n"
-"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), FLT_MIN)), SpecularPower * glosstex.a));\n"
+"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a));\n"
 "#endif\n"
 "      color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
 "#endif\n"
 "      half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
 "#  ifdef USESPECULAR\n"
 "#   ifdef USEEXACTSPECULARMATH\n"
-"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, FLT_MIN)), SpecularPower * glosstex.a));\n"
+"      half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), 0.25 + SpecularPower * glosstex.a));\n"
 "#   else\n"
 "      half3 specularnormal = half3(normalize(lightnormal + half3(normalize(EyeVector))));\n"
-"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), FLT_MIN)), SpecularPower * glosstex.a));\n"
+"      half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a));\n"
 "#   endif\n"
 "      color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
 "#  else\n"