Offsetmapping: new "Bias" parameter that sets a custom "null point" instead of always...
authorvortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 29 Aug 2011 19:35:03 +0000 (19:35 +0000)
committervortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 29 Aug 2011 19:35:03 +0000 (19:35 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11309 d7cf8633-e32d-0410-b094-e92efae38249

dpsoftrast.h
gl_rmain.c
model_alias.c
model_brush.c
model_shared.c
model_shared.h
model_sprite.c
shader_glsl.h
shader_hlsl.h

index 37fb94a..e00724e 100644 (file)
@@ -311,6 +311,7 @@ typedef enum DPSOFTRAST_UNIFORM_e
        DPSOFTRAST_UNIFORM_BloomColorSubtract,
        DPSOFTRAST_UNIFORM_NormalmapScrollBlend,
        DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance,
+       DPSOFTRAST_UNIFORM_OffsetMapping_Bias,
        DPSOFTRAST_UNIFORM_TOTAL
 }
 DPSOFTRAST_UNIFORM;
index 48444c9..9f78dcf 100644 (file)
@@ -828,6 +828,7 @@ typedef struct r_glsl_permutation_s
        int loc_LightPosition;
        int loc_OffsetMapping_ScaleSteps;
        int loc_OffsetMapping_LodDistance;
+       int loc_OffsetMapping_Bias;
        int loc_PixelSize;
        int loc_ReflectColor;
        int loc_ReflectFactor;
@@ -1150,6 +1151,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                p->loc_LightPosition              = qglGetUniformLocation(p->program, "LightPosition");
                p->loc_OffsetMapping_ScaleSteps   = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
                p->loc_OffsetMapping_LodDistance  = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
+               p->loc_OffsetMapping_Bias         = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
                p->loc_PixelSize                  = qglGetUniformLocation(p->program, "PixelSize");
                p->loc_ReflectColor               = qglGetUniformLocation(p->program, "ReflectColor");
                p->loc_ReflectFactor              = qglGetUniformLocation(p->program, "ReflectFactor");
@@ -1390,6 +1392,7 @@ typedef enum D3DPSREGISTER_e
        D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
        D3DPSREGISTER_NormalmapScrollBlend = 52,
        D3DPSREGISTER_OffsetMapping_LodDistance = 53,
+       D3DPSREGISTER_OffsetMapping_Bias = 54,
        // next at 54
 }
 D3DPSREGISTER_t;
@@ -2629,6 +2632,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
                        );
                hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer)
+               hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias / 255)
                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);
 
@@ -2790,6 +2794,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                                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_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias / 255);
                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);
                if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
@@ -2935,6 +2940,8 @@ 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_Bias, rsurface.texture->offsetbias / 255);
                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 214c960..d7bbd8b 100644 (file)
@@ -787,6 +787,7 @@ static void Mod_BuildAliasSkinFromSkinFrame(texture_t *texture, skinframe_t *ski
        texture->currentmaterialflags = texture->basematerialflags;
        texture->offsetmapping = OFFSETMAPPING_DEFAULT;
        texture->offsetscale = 1;
+       texture->offsetbias = 0;
        texture->specularscalemod = 1;
        texture->specularpowermod = 1;
        texture->surfaceflags = 0;
index 50e961e..d2819eb 100644 (file)
@@ -49,9 +49,9 @@ cvar_t mod_q3bsp_lightmapmergepower = {CVAR_SAVE, "mod_q3bsp_lightmapmergepower"
 cvar_t mod_q3bsp_nolightmaps = {CVAR_SAVE, "mod_q3bsp_nolightmaps", "0", "do not load lightmaps in Q3BSP maps (to save video RAM, but be warned: it looks ugly)"};
 cvar_t mod_q3bsp_tracelineofsight_brushes = {0, "mod_q3bsp_tracelineofsight_brushes", "0", "enables culling of entities behind detail brushes, curves, etc"};
 cvar_t mod_q3shader_default_offsetmapping = {CVAR_SAVE, "mod_q3shader_default_offsetmapping", "1", "use offsetmapping by default on all surfaces that are using q3 shader files"};
+cvar_t mod_q3shader_default_offsetmapping_bias = {CVAR_SAVE, "mod_q3shader_default_offsetmapping_bias", "0", "default bias used for offsetmapping"};
 cvar_t mod_q3shader_default_polygonfactor = {0, "mod_q3shader_default_polygonfactor", "0", "biases depth values of 'polygonoffset' shaders to prevent z-fighting artifacts"};
 cvar_t mod_q3shader_default_polygonoffset = {0, "mod_q3shader_default_polygonoffset", "-2", "biases depth values of 'polygonoffset' shaders to prevent z-fighting artifacts"};
-
 cvar_t mod_q1bsp_polygoncollisions = {0, "mod_q1bsp_polygoncollisions", "0", "disables use of precomputed cliphulls and instead collides with polygons (uses Bounding Interval Hierarchy optimizations)"};
 cvar_t mod_collision_bih = {0, "mod_collision_bih", "1", "enables use of generated Bounding Interval Hierarchy tree instead of compiled bsp tree in collision code"};
 cvar_t mod_recalculatenodeboxes = {0, "mod_recalculatenodeboxes", "1", "enables use of generated node bounding boxes based on BSP tree portal reconstruction, rather than the node boxes supplied by the map compiler"};
@@ -87,6 +87,7 @@ void Mod_BrushInit(void)
        Cvar_RegisterVariable(&mod_q3bsp_nolightmaps);
        Cvar_RegisterVariable(&mod_q3bsp_tracelineofsight_brushes);
        Cvar_RegisterVariable(&mod_q3shader_default_offsetmapping);
+       Cvar_RegisterVariable(&mod_q3shader_default_offsetmapping_bias);
        Cvar_RegisterVariable(&mod_q3shader_default_polygonfactor);
        Cvar_RegisterVariable(&mod_q3shader_default_polygonoffset);
        Cvar_RegisterVariable(&mod_q1bsp_polygoncollisions);
@@ -1661,6 +1662,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                tx->r_water_wateralpha = 1;
                tx->offsetmapping = OFFSETMAPPING_DEFAULT;
                tx->offsetscale = 1;
+               tx->offsetbias = 0;
                tx->specularscalemod = 1;
                tx->specularpowermod = 1;
        }
index ff024b0..8a27c67 100644 (file)
@@ -1623,6 +1623,7 @@ static void Q3Shader_AddToHash (q3shaderinfo_t* shader)
 
 extern cvar_t mod_noshader_default_offsetmapping;
 extern cvar_t mod_q3shader_default_offsetmapping;
+extern cvar_t mod_q3shader_default_offsetmapping_bias;
 extern cvar_t mod_q3shader_default_polygonoffset;
 extern cvar_t mod_q3shader_default_polygonfactor;
 void Mod_LoadQ3Shaders(void)
@@ -1714,6 +1715,7 @@ void Mod_LoadQ3Shaders(void)
                        shader.r_water_wateralpha = 1;
                        shader.offsetmapping = (mod_q3shader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
                        shader.offsetscale = 1;
+                       shader.offsetbias = bound(0, mod_q3shader_default_offsetmapping_bias.integer, 255);
                        shader.specularscalemod = 1;
                        shader.specularpowermod = 1;
                        shader.biaspolygonoffset = mod_q3shader_default_polygonoffset.value;
@@ -2228,17 +2230,20 @@ void Mod_LoadQ3Shaders(void)
                                {
                                        shader.rtlightambient = atof(parameter[1]);
                                }
-                               else if (!strcasecmp(parameter[0], "dpoffsetmapping") && numparameters >= 3)
+                               else if (!strcasecmp(parameter[0], "dpoffsetmapping") && numparameters >= 2)
                                {
                                        if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "off"))
                                                shader.offsetmapping = OFFSETMAPPING_OFF;
-                                       else if (!strcasecmp(parameter[1], "default"))
+                                       else if (!strcasecmp(parameter[1], "default") || !strcasecmp(parameter[1], "normal"))
                                                shader.offsetmapping = OFFSETMAPPING_DEFAULT;
                                        else if (!strcasecmp(parameter[1], "linear"))
                                                shader.offsetmapping = OFFSETMAPPING_LINEAR;
                                        else if (!strcasecmp(parameter[1], "relief"))
                                                shader.offsetmapping = OFFSETMAPPING_RELIEF;
-                                       shader.offsetscale = atof(parameter[2]);
+                                       if (numparameters >= 3)
+                                               shader.offsetscale = atof(parameter[2]);
+                                       if (numparameters >= 4)
+                                               shader.offsetbias = bound(0, atoi(parameter[3]), 255);
                                }
                                else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
                                {
@@ -2362,6 +2367,7 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool
        // unless later loaded from the shader
        texture->offsetmapping = (mod_noshader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
        texture->offsetscale = 1;
+       texture->offsetbias = 0;
        texture->specularscalemod = 1;
        texture->specularpowermod = 1; 
        texture->rtlightambient = 0;
@@ -2512,6 +2518,7 @@ nothing                GL_ZERO GL_ONE
                Vector2Copy(shader->r_water_waterscroll, texture->r_water_waterscroll);
                texture->offsetmapping = shader->offsetmapping;
                texture->offsetscale = shader->offsetscale;
+               texture->offsetbias = shader->offsetbias;
                texture->specularscalemod = shader->specularscalemod;
                texture->specularpowermod = shader->specularpowermod;
                texture->rtlightambient = shader->rtlightambient;
index 09627f7..6396085 100644 (file)
@@ -471,6 +471,7 @@ typedef struct q3shaderinfo_s
        // offsetmapping
        dpoffsetmapping_technique_t offsetmapping;
        float offsetscale;
+       unsigned char offsetbias;
 
        // polygonoffset (only used if Q3TEXTUREFLAG_POLYGONOFFSET)
        float biaspolygonoffset, biaspolygonfactor;
@@ -615,6 +616,7 @@ typedef struct texture_s
        // offsetmapping
        dpoffsetmapping_technique_t offsetmapping;
        float offsetscale;
+       unsigned char offsetbias;
 
        // gloss
        float specularscalemod;
index 4dc97df..9fa98cc 100644 (file)
@@ -63,6 +63,7 @@ static void Mod_SpriteSetupTexture(texture_t *texture, skinframe_t *skinframe, q
                skinframe = R_SkinFrame_LoadMissing();
        texture->offsetmapping = OFFSETMAPPING_OFF;
        texture->offsetscale = 1;
+       texture->offsetbias = 0;
        texture->specularscalemod = 1;
        texture->specularpowermod = 1;
        texture->basematerialflags = MATERIALFLAG_WALL;
index 70afe06..e0060e7 100644 (file)
 "\n"
 "#ifdef USEOFFSETMAPPING\n"
 "uniform mediump vec4 OffsetMapping_ScaleSteps;\n"
+"uniform mediump float OffsetMapping_Bias;\n"
 "#ifdef USEOFFSETMAPPING_LOD\n"
 "uniform mediump float OffsetMapping_LodDistance;\n"
 "#endif\n"
 "      //vec3 OffsetVector = vec3(EyeVectorFogDepth.xy * ((1.0 / EyeVectorFogDepth.z) * ScaleSteps.x) * vec2(-1, 1), -1);\n"
 "      //vec3 OffsetVector = vec3(normalize(EyeVectorFogDepth.xy) * ScaleSteps.x * vec2(-1, 1), -1);\n"
 "      vec3 OffsetVector = vec3(normalize(EyeVectorFogDepth.xyz).xy * ScaleSteps.x * vec2(-1, 1), -1);\n"
-"      vec3 RT = vec3(TexCoord, 1);\n"
+"      vec3 RT = vec3(vec2(TexCoord.xy - OffsetVector.xy*OffsetMapping_Bias), 1);\n"
 "      OffsetVector *= ScaleSteps.z;\n"
 "      for(i = 1.0; i < ScaleSteps.y; ++i)\n"
 "              RT += OffsetVector *  step(dp_textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n"
 "      //vec2 OffsetVector = vec2(EyeVectorFogDepth.xy * ((1.0 / EyeVectorFogDepth.z) * ScaleSteps.x) * vec2(-1, 1));\n"
 "      //vec2 OffsetVector = vec2(normalize(EyeVectorFogDepth.xy) * ScaleSteps.x * vec2(-1, 1));\n"
 "      vec2 OffsetVector = vec2(normalize(EyeVectorFogDepth.xyz).xy * ScaleSteps.x * vec2(-1, 1));\n"
+"      TexCoord.xy = TexCoord.xy - OffsetVector.xy*OffsetMapping_Bias;\n"
 "      OffsetVector *= ScaleSteps.z;\n"
 "      for(i = 0.0; i < ScaleSteps.y; ++i)\n"
 "              TexCoord += OffsetVector * (1.0 - dp_textureGrad(Texture_Normal, TexCoord, dPdx, dPdy).a);\n"
index 1586d05..6524287 100644 (file)
 "#endif\n"
 "\n"
 "#ifdef USEOFFSETMAPPING\n"
-"float2 OffsetMapping(float2 TexCoord, float4 OffsetMapping_ScaleSteps, float OffsetMapping_LodDistance, float3 EyeVector, sampler Texture_Normal, float2 dPdx, float2 dPdy)\n"
+"float2 OffsetMapping(float2 TexCoord, float4 OffsetMapping_ScaleSteps, float OffsetMapping_Bias, float OffsetMapping_LodDistance, float3 EyeVector, sampler Texture_Normal, float2 dPdx, float2 dPdy)\n"
 "{\n"
 "      float i;\n"
 "      // distance-based LOD\n"
 "      //float3 OffsetVector = float3(EyeVector.xy * ((1.0 / EyeVector.z) * ScaleSteps.x) * float2(-1, 1), -1);\n"
 "      //float3 OffsetVector = float3(normalize(EyeVector.xy) * ScaleSteps.x * float2(-1, 1), -1);\n"
 "      float3 OffsetVector = float3(normalize(EyeVector).xy * ScaleSteps.x * float2(-1, 1), -1);\n"
-"      float3 RT = float3(TexCoord, 1);\n"
+"      float3 RT = float3(float2(TexCoord.xy - OffsetVector.xy*OffsetMapping_Bias), 1);\n"
 "      OffsetVector *= ScaleSteps.z;\n"
 "      for(i = 1.0; i < ScaleSteps.y; ++i)\n"
 "              RT += OffsetVector *  step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n"
 "      //float2 OffsetVector = float2(EyeVector.xy * ((1.0 / EyeVector.z) * ScaleSteps.x) * float2(-1, 1));\n"
 "      //float2 OffsetVector = float2(normalize(EyeVector.xy) * ScaleSteps.x * float2(-1, 1));\n"
 "      float2 OffsetVector = float2(normalize(EyeVector).xy * ScaleSteps.x * float2(-1, 1));\n"
+"      TexCoord.xy = TexCoord.xy - OffsetVector.xy*OffsetMapping_Bias;\n"
 "      OffsetVector *= ScaleSteps.z;\n"
 "      for(i = 0.0; i < ScaleSteps.y; ++i)\n"
 "              TexCoord += OffsetVector * (1.0 - tex2Dgrad(Texture_Normal, TexCoord, dPdx, dPdy).a);\n"
 "#ifdef USEOFFSETMAPPING\n"
 "uniform float4 OffsetMapping_ScaleSteps : register(c24),\n"
 "uniform float4 OffsetMapping_LodDistance : register(c53),\n"
+"uniform float OffsetMapping_Bias : register(c54),\n"
 "#endif\n"
 "uniform half SpecularPower : register(c36),\n"
 "#ifdef HLSL\n"
 "      // apply offsetmapping\n"
 "      float2 dPdx = ddx(TexCoord);\n"
 "      float2 dPdy = ddy(TexCoord);\n"
-"      float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_ScaleSteps, OffsetMapping_LodDistance, EyeVector, Texture_Normal, dPdx, dPdy);\n"
+"      float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_ScaleSteps, OffsetMapping_Bias, OffsetMapping_LodDistance, EyeVector, Texture_Normal, dPdx, dPdy);\n"
 "# define offsetMappedTexture2D(t) tex2Dgrad(t, TexCoordOffset, dPdx, dPdy)\n"
 "#else\n"
 "# define offsetMappedTexture2D(t) tex2D(t, TexCoord)\n"
 "\n"
 "#ifdef USEOFFSETMAPPING\n"
 "uniform float4 OffsetMapping_ScaleSteps : register(c24),\n"
+"uniform float OffsetMapping_Bias : register(c54),\n"
 "#endif\n"
 "\n"
 "#ifdef USEDEFERREDLIGHTMAP\n"
 "      // apply offsetmapping\n"
 "      float2 dPdx = ddx(TexCoord);\n"
 "      float2 dPdy = ddy(TexCoord);\n"
-"      float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_ScaleSteps, OffsetMapping_LodDistance, EyeVector, Texture_Normal, dPdx, dPdy);\n"
+"      float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_ScaleSteps, OffsetMapping_Bias, OffsetMapping_LodDistance, EyeVector, Texture_Normal, dPdx, dPdy);\n"
 "# define offsetMappedTexture2D(t) tex2Dgrad(t, TexCoordOffset, dPdx, dPdy)\n"
 "#else\n"
 "# define offsetMappedTexture2D(t) tex2D(t, TexCoord)\n"