]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
add a hack to support fog on premultiplied alpha surfaces too
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 6 Mar 2011 18:42:35 +0000 (18:42 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 6 Mar 2011 18:42:35 +0000 (18:42 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10901 d7cf8633-e32d-0410-b094-e92efae38249

dpsoftrast.h
fogeval.pl
gl_rmain.c
shader_glsl.h
shader_hlsl.h

index d05ce2a4db7f8c3f60946c91ea1282f52d46916c..302d5cf28da625ad51bf29a3109815ce0cd9a229 100644 (file)
@@ -171,28 +171,29 @@ typedef enum shaderpermutation_e
        SHADERPERMUTATION_FOGINSIDE = 1<<5, ///< tint the color by fog color or black if using additive blend mode
        SHADERPERMUTATION_FOGOUTSIDE = 1<<6, ///< tint the color by fog color or black if using additive blend mode
        SHADERPERMUTATION_FOGHEIGHTTEXTURE = 1<<7, ///< fog color and density determined by texture mapped on vertical axis
-       SHADERPERMUTATION_GAMMARAMPS = 1<<8, ///< gamma (postprocessing only)
-       SHADERPERMUTATION_CUBEFILTER = 1<<9, ///< (lightsource) use cubemap light filter
-       SHADERPERMUTATION_GLOW = 1<<10, ///< (lightmap) blend in an additive glow texture
-       SHADERPERMUTATION_BLOOM = 1<<11, ///< bloom (postprocessing only)
-       SHADERPERMUTATION_SPECULAR = 1<<12, ///< (lightsource or deluxemapping) render specular effects
-       SHADERPERMUTATION_POSTPROCESSING = 1<<13, ///< user defined postprocessing (postprocessing only)
-       SHADERPERMUTATION_REFLECTION = 1<<14, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
-       SHADERPERMUTATION_OFFSETMAPPING = 1<<15, ///< adjust texcoords to roughly simulate a displacement mapped surface
-       SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<16, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
-       SHADERPERMUTATION_SHADOWMAP2D = 1<<17, ///< (lightsource) use shadowmap texture as light filter
-       SHADERPERMUTATION_SHADOWMAPPCF = 1<<18, ///< (lightsource) use percentage closer filtering on shadowmap test results
-       SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<19, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
-       SHADERPERMUTATION_SHADOWSAMPLER = 1<<20, ///< (lightsource) use hardware shadowmap test
-       SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<21, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
-       SHADERPERMUTATION_SHADOWMAPORTHO = 1<<22, ///< (lightsource) use orthographic shadowmap projection
-       SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<23, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
-       SHADERPERMUTATION_ALPHAKILL = 1<<24, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
-       SHADERPERMUTATION_REFLECTCUBE = 1<<25, ///< fake reflections using global cubemap (not HDRI light probe)
-       SHADERPERMUTATION_NORMALMAPSCROLLBLEND = 1<<26, ///< (water) counter-direction normalmaps scrolling
-       SHADERPERMUTATION_BOUNCEGRID = 1<<27, ///< (lightmap) use Texture_BounceGrid as an additional source of ambient light
-       SHADERPERMUTATION_LIMIT = 1<<28, ///< size of permutations array
-       SHADERPERMUTATION_COUNT = 28 ///< size of shaderpermutationinfo array
+       SHADERPERMUTATION_FOGALPHAHACK = 1<<8, ///< fog color and density determined by texture mapped on vertical axis
+       SHADERPERMUTATION_GAMMARAMPS = 1<<9, ///< gamma (postprocessing only)
+       SHADERPERMUTATION_CUBEFILTER = 1<<10, ///< (lightsource) use cubemap light filter
+       SHADERPERMUTATION_GLOW = 1<<11, ///< (lightmap) blend in an additive glow texture
+       SHADERPERMUTATION_BLOOM = 1<<12, ///< bloom (postprocessing only)
+       SHADERPERMUTATION_SPECULAR = 1<<13, ///< (lightsource or deluxemapping) render specular effects
+       SHADERPERMUTATION_POSTPROCESSING = 1<<14, ///< user defined postprocessing (postprocessing only)
+       SHADERPERMUTATION_REFLECTION = 1<<15, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
+       SHADERPERMUTATION_OFFSETMAPPING = 1<<16, ///< adjust texcoords to roughly simulate a displacement mapped surface
+       SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<17, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
+       SHADERPERMUTATION_SHADOWMAP2D = 1<<18, ///< (lightsource) use shadowmap texture as light filter
+       SHADERPERMUTATION_SHADOWMAPPCF = 1<<19, ///< (lightsource) use percentage closer filtering on shadowmap test results
+       SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<20, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
+       SHADERPERMUTATION_SHADOWSAMPLER = 1<<21, ///< (lightsource) use hardware shadowmap test
+       SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<22, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
+       SHADERPERMUTATION_SHADOWMAPORTHO = 1<<23, ///< (lightsource) use orthographic shadowmap projection
+       SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
+       SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
+       SHADERPERMUTATION_REFLECTCUBE = 1<<26, ///< fake reflections using global cubemap (not HDRI light probe)
+       SHADERPERMUTATION_NORMALMAPSCROLLBLEND = 1<<27, ///< (water) counter-direction normalmaps scrolling
+       SHADERPERMUTATION_BOUNCEGRID = 1<<28, ///< (lightmap) use Texture_BounceGrid as an additional source of ambient light
+       SHADERPERMUTATION_LIMIT = 1<<29, ///< size of permutations array
+       SHADERPERMUTATION_COUNT = 29 ///< size of shaderpermutationinfo array
 }
 shaderpermutation_t;
 
index a3633203fbcab438ba6b9edf79934589c3658c62..e6262bd119b67f58179b3c5f00df3400f3120166 100644 (file)
@@ -47,7 +47,7 @@ sub isfogfriendly($$$$$)
        # 1. blend(fog(s), sa, fog(d), da)
        # 2. fog(blend(s, sa, d, da))
 
-       my ($out1, $out1a) = evalblend $fs, $fd, $s + ((defined $foghack ? $foghack < 0 ? $s : $foghack : $fogcolor) - $s) * $fogamount, $sa, $d + ($fogcolor - $d) * $fogamount, $da;
+       my ($out1, $out1a) = evalblend $fs, $fd, $s + ((defined $foghack ? $foghack eq 'ALPHA' ? $fogcolor*$sa : $foghack : $fogcolor) - $s) * $fogamount, $sa, $d + ($fogcolor - $d) * $fogamount, $da;
        my ($out2, $out2a) = evalblend $fs, $fd, $s, $sa, $d, $da;
                $out2 = $out2 + ($fogcolor - $out2) * $fogamount;
 
@@ -82,7 +82,7 @@ sub willitfog($$)
        my ($fs, $fd) = @_;
 
        FOGHACK:
-       for my $foghack(undef, 0, 1, -1)
+       for my $foghack(undef, 0, 'ALPHA')
        {
                for my $s(0, 0.25, 0.5, 0.75, 1)
                {
index 9b973e5748f7793eeb9d05cf4bd7ad2eccc93e34..9d43f08875cd41d7667c667ac303151a420332cf 100644 (file)
@@ -633,6 +633,7 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
        {"#define USEFOGINSIDE\n", " foginside"},
        {"#define USEFOGOUTSIDE\n", " fogoutside"},
        {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
+       {"#define USEFOGALPHAHACK\n", " fogalphahack"},
        {"#define USEGAMMARAMPS\n", " gammaramps"},
        {"#define USECUBEFILTER\n", " cubefilter"},
        {"#define USEGLOW\n", " glow"},
@@ -1988,10 +1989,11 @@ extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
 
-#define BLENDFUNC_ALLOWS_COLORMOD     1
-#define BLENDFUNC_ALLOWS_FOG          2
-#define BLENDFUNC_ALLOWS_FOG_HACK0    4
-#define BLENDFUNC_ALLOWS_ANYFOG       6
+#define BLENDFUNC_ALLOWS_COLORMOD      1
+#define BLENDFUNC_ALLOWS_FOG           2
+#define BLENDFUNC_ALLOWS_FOG_HACK0     4
+#define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
+#define BLENDFUNC_ALLOWS_ANYFOG        (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
 static int R_BlendFuncFlags(int src, int dst)
 {
        int r = 0;
@@ -2016,6 +2018,7 @@ static int R_BlendFuncFlags(int src, int dst)
        if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
        if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
        if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+       if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
        if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
        if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
        if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
@@ -2388,6 +2391,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                colormod = dummy_colormod;
        if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
                permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
+       if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
+               permutation |= SHADERPERMUTATION_FOGALPHAHACK;
        switch(vid.renderpath)
        {
        case RENDERPATH_D3D9:
index 419908beaa52a8a2cd6fc37f738114ea0e3a8110..614fbf4e943716424dcad191c507f640d2a7fe9c 100644 (file)
 "uniform highp float FogRangeRecip;\n"
 "uniform highp float FogPlaneViewDist;\n"
 "uniform highp float FogHeightFade;\n"
-"vec3 FogVertex(vec3 surfacecolor)\n"
+"vec3 FogVertex(vec4 surfacecolor)\n"
 "{\n"
 "      vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n"
 "      float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n"
 "      float fogfrac;\n"
+"       vec3 fc = FogColor;\n"
+"#ifdef USEFOGALPHAHACK\n"
+"      fc *= surfacecolor.a;\n"
+"#endif\n"
 "#ifdef USEFOGHEIGHTTEXTURE\n"
 "      vec4 fogheightpixel = texture2D(Texture_FogHeightTexture, vec2(1,1) + vec2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
 "      fogfrac = fogheightpixel.a;\n"
-"      return mix(fogheightpixel.rgb * FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
+"      return mix(fogheightpixel.rgb * fc, surfacecolor.rgb, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
 "#else\n"
 "# ifdef USEFOGOUTSIDE\n"
 "      fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
 "# else\n"
 "      fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
 "# endif\n"
-"      return mix(FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
+"      return mix(fc, surfacecolor.rgb, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
 "#endif\n"
 "}\n"
 "#endif\n"
 "#endif\n"
 "\n"
 "#ifdef USEFOG\n"
-"      color.rgb = FogVertex(color.rgb);\n"
+"      color.rgb = FogVertex(color);\n"
 "#endif\n"
 "\n"
 "      // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
index 74a02eef4ab69e705b2d8f01956caebdc4010ff8..19bf6b8290461d30661c4b7049bf05d0522fd467 100644 (file)
 "#ifdef FRAGMENT_SHADER\n"
 "\n"
 "#ifdef USEFOG\n"
-"float3 FogVertex(float3 surfacecolor, float3 FogColor, float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler Texture_FogMask, sampler Texture_FogHeightTexture)\n"
+"float3 FogVertex(float4 surfacecolor, float3 FogColor, float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler Texture_FogMask, sampler Texture_FogHeightTexture)\n"
 "{\n"
 "      float fogfrac;\n"
+"      float3 fc = Fogcolor;\n"
+"#ifdef USEFOGALPHAHACK\n"
+"      fc *= surfacecolor.a;\n"
+"#endif\n"
 "#ifdef USEFOGHEIGHTTEXTURE\n"
 "      float4 fogheightpixel = tex2D(Texture_FogHeightTexture, float2(1,1) + float2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
 "      fogfrac = fogheightpixel.a;\n"
-"      return lerp(fogheightpixel.rgb * FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
+"      return lerp(fogheightpixel.rgb * fc, surfacecolor.rgb, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
 "#else\n"
 "# ifdef USEFOGOUTSIDE\n"
 "      fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
 "# else\n"
 "      fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
 "# endif\n"
-"      return lerp(FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
+"      return lerp(fc, surfacecolor.rgb, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
 "#endif\n"
 "}\n"
 "#endif\n"
 "#endif\n"
 "\n"
 "#ifdef USEFOG\n"
-"      color.rgb = FogVertex(color.rgb, FogColor, EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask, Texture_FogHeightTexture);\n"
+"      color.rgb = FogVertex(color, FogColor, EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask, Texture_FogHeightTexture);\n"
 "#endif\n"
 "\n"
 "      // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"