cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
+cvar_t r_glsl_contrastboost = {CVAR_SAVE, "r_glsl_contrastboost", "1", "by how much to multiply the contrast in dark areas (1 is no change)"};
cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites (requires r_lerpmodels 1)"};
cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
"\n"
"uniform myhalf GlowScale;\n"
"uniform myhalf SceneBrightness;\n"
+"#ifdef USECONTRASTBOOST\n"
+"uniform myhalf ContrastBoostCoeff;\n"
+"#endif\n"
"\n"
"uniform float OffsetMapping_Scale;\n"
"uniform float OffsetMapping_Bias;\n"
" color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
"#endif\n"
"\n"
+"#ifdef USECONTRASTBOOST\n"
+" color.rgb = SceneBrightness / (ContrastBoostCoeff + 1 / color.rgb);\n"
+"#else\n"
" color.rgb *= SceneBrightness;\n"
+"#endif\n"
"\n"
" gl_FragColor = vec4(color);\n"
"}\n"
{"#define USEFOG\n", " fog"},
{"#define USECOLORMAPPING\n", " colormapping"},
{"#define USEDIFFUSE\n", " diffuse"},
+ {"#define USECONTRASTBOOST\n", " contrastboost"},
{"#define USESPECULAR\n", " specular"},
{"#define USECUBEFILTER\n", " cubefilter"},
{"#define USEOFFSETMAPPING\n", " offsetmapping"},
p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor");
p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor");
p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
+ p->loc_ContrastBoostCoeff = qglGetUniformLocationARB(p->program, "ContrastBoostCoeff");
// initialize the samplers to refer to the texture units we use
if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal, 0);
if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color, 1);
if (r_glsl_offsetmapping_reliefmapping.integer)
permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
}
+ if(r_glsl_contrastboost.value != 1 && r_glsl_contrastboost.value != 0)
+ permutation |= SHADERPERMUTATION_CONTRASTBOOST;
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
{
if (r_glsl_offsetmapping_reliefmapping.integer)
permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
}
+ if(r_glsl_contrastboost.value != 1 && r_glsl_contrastboost.value != 0)
+ permutation |= SHADERPERMUTATION_CONTRASTBOOST;
}
else if (modellighting)
{
if (r_glsl_offsetmapping_reliefmapping.integer)
permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
}
+ if(r_glsl_contrastboost.value != 1 && r_glsl_contrastboost.value != 0)
+ permutation |= SHADERPERMUTATION_CONTRASTBOOST;
}
else
{
if (r_glsl_offsetmapping_reliefmapping.integer)
permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
}
+ if(r_glsl_contrastboost.value != 1 && r_glsl_contrastboost.value != 0)
+ permutation |= SHADERPERMUTATION_CONTRASTBOOST;
}
if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program)
{
//if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(rsurface.texture->currentskinframe->glow));
if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value);
- if (r_glsl_permutation->loc_SceneBrightness >= 0) qglUniform1fARB(r_glsl_permutation->loc_SceneBrightness, r_view.colorscale);
+ if (r_glsl_permutation->loc_ContrastBoostCoeff >= 0)
+ {
+ // The formula used is actually:
+ // color.rgb *= SceneBrightness;
+ // color.rgb *= ContrastBoost / ((ContrastBoost - 1) * color.rgb + 1);
+ // I simplify that to
+ // color.rgb *= [[SceneBrightness * ContrastBoost]];
+ // color.rgb /= [[(ContrastBoost - 1) / ContrastBoost]] * color.rgb + 1;
+ // and Black:
+ // color.rgb = [[SceneBrightness * ContrastBoost]] / ([[(ContrastBoost - 1) * SceneBrightness]] + 1 / color.rgb);
+ // and do [[calculations]] here in the engine
+ qglUniform1fARB(r_glsl_permutation->loc_ContrastBoostCoeff, (r_glsl_contrastboost.value - 1) * r_view.colorscale);
+ if (r_glsl_permutation->loc_SceneBrightness >= 0) qglUniform1fARB(r_glsl_permutation->loc_SceneBrightness, r_view.colorscale * r_glsl_contrastboost.value);
+ }
+ else
+ if (r_glsl_permutation->loc_SceneBrightness >= 0) qglUniform1fARB(r_glsl_permutation->loc_SceneBrightness, r_view.colorscale);
if (r_glsl_permutation->loc_FogColor >= 0)
{
// additive passes are only darkened by fog, not tinted
Cvar_RegisterVariable(&r_bloom_colorsubtract);
Cvar_RegisterVariable(&r_hdr);
Cvar_RegisterVariable(&r_hdr_scenebrightness);
+ Cvar_RegisterVariable(&r_glsl_contrastboost);
Cvar_RegisterVariable(&r_hdr_glowintensity);
Cvar_RegisterVariable(&r_hdr_range);
Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
#define SHADERPERMUTATION_FOG (1<<5) // tint the color by fog color or black if using additive blend mode
#define SHADERPERMUTATION_COLORMAPPING (1<<6) // indicates this is a colormapped skin
#define SHADERPERMUTATION_DIFFUSE (1<<7) // (lightsource) whether to use directional shading
-#define SHADERPERMUTATION_SPECULAR (1<<8) // (lightsource or deluxemapping) render specular effects
-#define SHADERPERMUTATION_CUBEFILTER (1<<9) // (lightsource) use cubemap light filter
-#define SHADERPERMUTATION_OFFSETMAPPING (1<<10) // adjust texcoords to roughly simulate a displacement mapped surface
-#define SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING (1<<11) // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
+#define SHADERPERMUTATION_CONTRASTBOOST (1<<8) // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma)
+#define SHADERPERMUTATION_SPECULAR (1<<9) // (lightsource or deluxemapping) render specular effects
+#define SHADERPERMUTATION_CUBEFILTER (1<<10) // (lightsource) use cubemap light filter
+#define SHADERPERMUTATION_OFFSETMAPPING (1<<11) // adjust texcoords to roughly simulate a displacement mapped surface
+#define SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING (1<<12) // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
-#define SHADERPERMUTATION_MAX (1<<12) // how many permutations are possible
+#define SHADERPERMUTATION_MAX (1<<13) // how many permutations are possible
#define SHADERPERMUTATION_MASK (SHADERPERMUTATION_MAX - 1) // mask of valid indexing bits for r_glsl_permutations[] array
// these are additional flags used only by R_GLSL_CompilePermutation
int loc_SpecularScale;
int loc_SpecularPower;
int loc_GlowScale;
- int loc_SceneBrightness;
+ int loc_SceneBrightness; // or: Scenebrightness * ContrastBoost
int loc_OffsetMapping_Scale;
int loc_AmbientColor;
int loc_DiffuseColor;
int loc_SpecularColor;
int loc_LightDir;
+ int loc_ContrastBoostCoeff; // 1 - 1/ContrastBoost
}
r_glsl_permutation_t;