diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 6d7c9a5502..982436b3a3 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -579,6 +579,11 @@ static std::string GenEngineConstants() { AddDefine( str, "r_showLightTiles", 1 ); } + if ( r_floorLight->integer ) + { + AddDefine( str, "r_floorLight", 1 ); + } + if ( r_normalMapping->integer ) { AddDefine( str, "r_normalMapping", 1 ); diff --git a/src/engine/renderer/glsl_source/lightMapping_fp.glsl b/src/engine/renderer/glsl_source/lightMapping_fp.glsl index b8f123a3dd..b6863de749 100644 --- a/src/engine/renderer/glsl_source/lightMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_fp.glsl @@ -41,6 +41,26 @@ IN(smooth) vec4 var_Color; DECLARE_OUTPUT(vec4) +#if defined(r_floorLight) +// returns a pseudo-boolean (1 or 0) vec3 given the component +// is smaller to the given float or not +// for example isSmaller(vec3(1, 2, 3), 2) returns vec3(1, 0, 0) +vec3 isSmaller(vec3 v, float max) +{ + return floor(min(v, max) / max) * -1 + 1; +} + +// shift and rescale a vec3 from any [min1, max1] range to [min2 - max2] range +// for example it can be used to rescale [0, 12] to [6, 32] +vec3 shiftRange(vec3 v, float min1, float max1, float min2, float max2) +{ + v -= min1; + v *= (max2 - min2) / (max1 - min1); + v += min2; + return v; +} +#endif // r_floorLight + void main() { // compute view direction in world space @@ -74,6 +94,24 @@ void main() // compute light color from world space lightmap vec3 lightColor = texture2D(u_LightMap, var_TexLight).xyz; + +#if defined(r_floorLight) + // rescale [min1, max1] to [min2, max2] + // values were chosen the empirical way by testing against some maps on a + // calibrated screen with 100% sRGB coverage, the tested maps were: + // parpax, spacetracks, antares, vega, arachnid2, hangar28 + // those values are for non-sRGB lightmaps + // TODO: find or compute related values for sRGB lightmaps if implemented + float min1 = 0.0; + float max1 = 0.18; + float min2 = 0.06; + float max2 = max1; + // isSmaller() produces a pseudo boolean vec3 + // shiftRange() translates the given range + // shiftRange() - lightColor gives the value of the number to add to lightColor + // this number being 0 if isSmaller() produces a 0 + lightColor += isSmaller(lightColor, max1) * (shiftRange(lightColor, min1, max1, min2, max2) - lightColor); +#endif // r_floorLight vec4 color = vec4( 0.0, 0.0, 0.0, diffuse.a ); diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index a904a8ccfa..908ae9f72e 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -159,6 +159,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *r_offsetFactor; cvar_t *r_offsetUnits; + cvar_t *r_floorLight; + cvar_t *r_specularExponentMin; cvar_t *r_specularExponentMax; cvar_t *r_specularScale; @@ -1191,6 +1193,8 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_offsetFactor = ri.Cvar_Get( "r_offsetFactor", "-1", CVAR_CHEAT ); r_offsetUnits = ri.Cvar_Get( "r_offsetUnits", "-2", CVAR_CHEAT ); + r_floorLight = ri.Cvar_Get( "r_floorLight", "0", CVAR_LATCH ); + r_specularExponentMin = ri.Cvar_Get( "r_specularExponentMin", "0", CVAR_CHEAT ); r_specularExponentMax = ri.Cvar_Get( "r_specularExponentMax", "16", CVAR_CHEAT ); r_specularScale = ri.Cvar_Get( "r_specularScale", "1.0", CVAR_CHEAT | CVAR_SHADER ); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 702f23d072..4ca0519c6e 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2849,6 +2849,8 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) extern cvar_t *r_offsetFactor; extern cvar_t *r_offsetUnits; + extern cvar_t *r_floorLight; + extern cvar_t *r_specularExponentMin; extern cvar_t *r_specularExponentMax; extern cvar_t *r_specularScale;