@@ -29,33 +29,58 @@ static u8 light_LUT[LIGHT_SUN + 1];
29
29
// The const ref to light_LUT is what is actually used in the code
30
30
const u8 *light_decode_table = light_LUT;
31
31
32
+ struct LightingParams {
33
+ float a, b, c; // polynomial coefficients
34
+ float boost, center, sigma; // normal boost parameters
35
+ float gamma;
36
+ };
37
+
38
+ static LightingParams params;
39
+
40
+ float decode_light_f (float x)
41
+ {
42
+ if (x >= 1 .0f ) // x is equal to 1.0f half the time
43
+ return 1 .0f ;
44
+ x = std::fmax (x, 0 .0f );
45
+ float brightness = ((params.a * x + params.b ) * x + params.c ) * x;
46
+ brightness += params.boost * std::exp (-0 .5f * sqr ((x - params.center ) / params.sigma ));
47
+ if (brightness <= 0 .0f ) // may happen if parameters are insane
48
+ return 0 .0f ;
49
+ if (brightness >= 1 .0f )
50
+ return 1 .0f ;
51
+ return powf (brightness, 1 .0f / params.gamma );
52
+ }
53
+
32
54
// Initialize or update the light value tables using the specified gamma
33
55
void set_light_table (float gamma)
34
56
{
35
57
// Lighting curve derivatives
36
58
const float alpha = g_settings->getFloat (" lighting_alpha" );
37
59
const float beta = g_settings->getFloat (" lighting_beta" );
38
60
// Lighting curve coefficients
39
- const float a = alpha + beta - 2 .0f ;
40
- const float b = 3 .0f - 2 .0f * alpha - beta;
41
- const float c = alpha;
61
+ params. a = alpha + beta - 2 .0f ;
62
+ params. b = 3 .0f - 2 .0f * alpha - beta;
63
+ params. c = alpha;
42
64
// Mid boost
43
- const float d = g_settings->getFloat (" lighting_boost" );
44
- const float e = g_settings->getFloat (" lighting_boost_center" );
45
- const float f = g_settings->getFloat (" lighting_boost_spread" );
65
+ params. boost = g_settings->getFloat (" lighting_boost" );
66
+ params. center = g_settings->getFloat (" lighting_boost_center" );
67
+ params. sigma = g_settings->getFloat (" lighting_boost_spread" );
46
68
// Gamma correction
47
- gamma = rangelim (gamma , 0 .5f , 3 .0f );
48
-
49
- for (size_t i = 0 ; i < LIGHT_SUN; i++) {
50
- float x = i;
51
- x /= LIGHT_SUN;
52
- float brightness = a * x * x * x + b * x * x + c * x;
53
- float boost = d * std::exp (-((x - e) * (x - e)) / (2 .0f * f * f));
54
- brightness = powf (brightness + boost, 1 .0f / gamma );
55
- light_LUT[i] = rangelim ((u32)(255 .0f * brightness), 0 , 255 );
69
+ params.gamma = rangelim (gamma , 0 .5f , 3 .0f );
70
+
71
+ // Boundary values should be fixed
72
+ light_LUT[0 ] = 0 ;
73
+ light_LUT[LIGHT_SUN] = 255 ;
74
+
75
+ for (size_t i = 1 ; i < LIGHT_SUN; i++) {
76
+ float brightness = decode_light_f ((float )i / LIGHT_SUN);
77
+ // Strictly speaking, rangelim is not necessary here—if the implementation
78
+ // is conforming. But we don’t want problems in any case.
79
+ light_LUT[i] = rangelim ((s32)(255 .0f * brightness), 0 , 255 );
80
+ // Ensure light brightens with each level
56
81
if (i > 1 && light_LUT[i] <= light_LUT[i - 1 ])
57
82
light_LUT[i] = light_LUT[i - 1 ] + 1 ;
58
83
}
59
- light_LUT[LIGHT_SUN] = 255 ;
60
84
}
85
+
61
86
#endif
0 commit comments