Skip to content

Commit

Permalink
Improve light curve parameter limits and documentation (#9054)
Browse files Browse the repository at this point in the history
Revert gamma upper limit to 3.0 because that was raised based on
a misunderstanding and had no benefit. A sane upper limit is
needed as players on a competitive server tend to use the maximum.
Set gamma lower limit to 0.33 for consistency with 3.0.
Set sane limits on alpha, beta, boost and enforce these in code
to limit values entered in minetest.conf and to avoid easy cheating
by editing settingtypes.txt.
Improve documentation and 'readable' setting names.
Clarify that gamma does not significantly affect natural night light.
light.cpp: Various codestyle and comment improvements.
  • Loading branch information
paramat committed Oct 24, 2019
1 parent cd35949 commit 1f142ec
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 31 deletions.
39 changes: 24 additions & 15 deletions builtin/settingtypes.txt
Expand Up @@ -639,25 +639,34 @@ vsync (VSync) bool false
# Field of view in degrees.
fov (Field of view) int 72 45 160

# Adjust the gamma encoding for the light tables. Higher numbers are brighter.
# This setting is for the client only and is ignored by the server.
display_gamma (Gamma) float 1.0 0.5 10.0
# Alters the light curve by applying 'gamma correction' to it.
# Higher values make middle and lower light levels brighter.
# Value '1.0' leaves the light curve unaltered.
# This only has significant effect on daylight and artificial
# light, it has very little effect on natural night light.
display_gamma (Light curve gamma) float 1.0 0.33 3.0

# Gradient of light curve at minimum light level.
lighting_alpha (Darkness sharpness) float 0.0 0.0 4.0
# Controls the contrast of the lowest light levels.
lighting_alpha (Light curve low gradient) float 0.0 0.0 3.0

# Gradient of light curve at maximum light level.
lighting_beta (Lightness sharpness) float 1.5 0.0 4.0

# Strength of light curve mid-boost.
lighting_boost (Light curve mid boost) float 0.2 0.0 1.0

# Center of light curve mid-boost.
lighting_boost_center (Light curve mid boost center) float 0.5 0.0 1.0

# Spread of light curve mid-boost.
# Standard deviation of the mid-boost Gaussian.
lighting_boost_spread (Light curve mid boost spread) float 0.2 0.0 1.0
# Controls the contrast of the highest light levels.
lighting_beta (Light curve high gradient) float 1.5 0.0 3.0

# Strength of light curve boost.
# The 3 'boost' parameters define a range of the light
# curve that is boosted in brightness.
lighting_boost (Light curve boost) float 0.2 0.0 0.4

# Center of light curve boost range.
# Where 0.0 is minimum light level, 1.0 is maximum light level.
lighting_boost_center (Light curve boost center) float 0.5 0.0 1.0

# Spread of light curve boost range.
# Controls the width of the range to be boosted.
# Standard deviation of the light curve boost Gaussian.
lighting_boost_spread (Light curve boost spread) float 0.2 0.0 0.4

# Path to texture directory. All textures are first searched from here.
texture_path (Texture path) path
Expand Down
36 changes: 20 additions & 16 deletions src/light.cpp
Expand Up @@ -29,44 +29,48 @@ static u8 light_LUT[LIGHT_SUN + 1];
// The const ref to light_LUT is what is actually used in the code
const u8 *light_decode_table = light_LUT;


struct LightingParams {
float a, b, c; // polynomial coefficients
float boost, center, sigma; // normal boost parameters
float gamma;
float a, b, c; // Lighting curve polynomial coefficients
float boost, center, sigma; // Lighting curve parametric boost
float gamma; // Lighting curve gamma correction
};

static LightingParams params;


float decode_light_f(float x)
{
if (x >= 1.0f) // x is equal to 1.0f half the time
if (x >= 1.0f) // x is often 1.0f
return 1.0f;
x = std::fmax(x, 0.0f);
float brightness = ((params.a * x + params.b) * x + params.c) * x;
brightness += params.boost * std::exp(-0.5f * sqr((x - params.center) / params.sigma));
if (brightness <= 0.0f) // may happen if parameters are insane
brightness += params.boost *
std::exp(-0.5f * sqr((x - params.center) / params.sigma));
if (brightness <= 0.0f) // May happen if parameters are extreme
return 0.0f;
if (brightness >= 1.0f)
return 1.0f;
return powf(brightness, 1.0f / params.gamma);
}


// Initialize or update the light value tables using the specified gamma
void set_light_table(float gamma)
{
// Lighting curve derivatives
const float alpha = g_settings->getFloat("lighting_alpha");
const float beta = g_settings->getFloat("lighting_beta");
// Lighting curve coefficients
// Lighting curve bounding gradients
const float alpha = rangelim(g_settings->getFloat("lighting_alpha"), 0.0f, 3.0f);
const float beta = rangelim(g_settings->getFloat("lighting_beta"), 0.0f, 3.0f);
// Lighting curve polynomial coefficients
params.a = alpha + beta - 2.0f;
params.b = 3.0f - 2.0f * alpha - beta;
params.c = alpha;
// Mid boost
params.boost = g_settings->getFloat("lighting_boost");
params.center = g_settings->getFloat("lighting_boost_center");
params.sigma = g_settings->getFloat("lighting_boost_spread");
// Gamma correction
params.gamma = rangelim(gamma, 0.5f, 10.0f);
// Lighting curve parametric boost
params.boost = rangelim(g_settings->getFloat("lighting_boost"), 0.0f, 0.4f);
params.center = rangelim(g_settings->getFloat("lighting_boost_center"), 0.0f, 1.0f);
params.sigma = rangelim(g_settings->getFloat("lighting_boost_spread"), 0.0f, 0.4f);
// Lighting curve gamma correction
params.gamma = rangelim(gamma, 0.33f, 3.0f);

// Boundary values should be fixed
light_LUT[0] = 0;
Expand Down

0 comments on commit 1f142ec

Please sign in to comment.