From 396cf70d81c18e96fa85b476add470385b7409c3 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 29 Aug 2011 15:23:33 +0000 Subject: [PATCH] make sure another way it never calculates 0^0 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 --- dpsoftrast.c | 12 ++++++------ gl_rmain.c | 18 +++++++++--------- shader_glsl.h | 15 ++++++--------- shader_hlsl.h | 15 ++++++--------- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/dpsoftrast.c b/dpsoftrast.c index d1cde7a9..0e125a91 100644 --- a/dpsoftrast.c +++ b/dpsoftrast.c @@ -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) { diff --git a/gl_rmain.c b/gl_rmain.c index 14d7f104..fd648965 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -2563,7 +2563,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 { @@ -2601,7 +2601,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]); } @@ -2712,7 +2712,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 { @@ -2753,7 +2753,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);} @@ -2861,7 +2861,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 { @@ -2899,7 +2899,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);} @@ -3040,7 +3040,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); @@ -3068,7 +3068,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); @@ -3092,7 +3092,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); diff --git a/shader_glsl.h b/shader_glsl.h index 0c01478e..12cc469e 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -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" @@ -981,10 +978,10 @@ " // 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" @@ -1240,10 +1237,10 @@ " 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" @@ -1335,10 +1332,10 @@ " 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" diff --git a/shader_hlsl.h b/shader_hlsl.h index 73bd7dd8..1016d0e1 100644 --- a/shader_hlsl.h +++ b/shader_hlsl.h @@ -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" @@ -947,10 +944,10 @@ " // 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" @@ -1362,10 +1359,10 @@ " 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" @@ -1484,10 +1481,10 @@ " 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" -- 2.39.2