Redo light.cpp.

Remake the light_decode_table.

The table starts out without pre-filled in values since those
are always discarded by the code apparently. We calculate a
pseudo curve with gamma power function, and then apply a new
adjustment table.

The adjustment table is setup to make the default gamma of 2.2
look decent: not too dark at light level 3 or so, but too dark
at 1 and below to be playable. The curve is much smoother than
before and looks reasonable at the whole range, offering a
pleasant decay of light levels away from lights.

The `display_gamma` setting now actually does something logical:
the game is darker at values below 2.2, and brighter at values
above 2.2. At 3.0, the game is very bright, but still has a good
light scale. At 1.1 or so, the bottom 5 light levels are virtually
black, but you can still see enough detail at light levels 7-8,
so the range and spread is adequate.

I must add that my monitor is somewhat dark to begin with, since
I have a `hc` screen that doesn't dynamic range colors or try to
pull up `black` pixels for me (it is tuned for accurate color and
light levels), so this should look even better on more dynamic
display tunings.
This commit is contained in:
Auke Kok 2016-12-08 17:37:13 -08:00 committed by Auke Kok
parent 5a0a59ad46
commit 094a5a73d3
4 changed files with 28 additions and 331 deletions

@ -442,9 +442,9 @@ fov (Field of view) int 72 30 160
# This requires the "zoom" privilege on the server. # This requires the "zoom" privilege on the server.
zoom_fov (Field of view for zoom) int 15 15 160 zoom_fov (Field of view for zoom) int 15 15 160
# Adjust the gamma encoding for the light tables. Lower numbers are brighter. # 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. # This setting is for the client only and is ignored by the server.
display_gamma (Gamma) float 1.8 1.0 3.0 display_gamma (Gamma) float 2.2 1.0 3.0
# Path to texture directory. All textures are first searched from here. # Path to texture directory. All textures are first searched from here.
texture_path (Texture path) path texture_path (Texture path) path

@ -508,7 +508,7 @@
# Adjust the gamma encoding for the light tables. Lower numbers are brighter. # Adjust the gamma encoding for the light tables. Lower numbers are brighter.
# This setting is for the client only and is ignored by the server. # This setting is for the client only and is ignored by the server.
# type: float min: 1 max: 3 # type: float min: 1 max: 3
# display_gamma = 1.8 # display_gamma = 2.2
# Path to texture directory. All textures are first searched from here. # Path to texture directory. All textures are first searched from here.
# type: path # type: path

@ -112,7 +112,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("leaves_style", "fancy"); settings->setDefault("leaves_style", "fancy");
settings->setDefault("connected_glass", "false"); settings->setDefault("connected_glass", "false");
settings->setDefault("smooth_lighting", "true"); settings->setDefault("smooth_lighting", "true");
settings->setDefault("display_gamma", "1.8"); settings->setDefault("display_gamma", "2.2");
settings->setDefault("texture_path", ""); settings->setDefault("texture_path", "");
settings->setDefault("shader_path", ""); settings->setDefault("shader_path", "");
settings->setDefault("video_driver", "opengl"); settings->setDefault("video_driver", "opengl");

@ -26,29 +26,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Length of LIGHT_MAX+1 means LIGHT_MAX is the last value. // Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
// LIGHT_SUN is read as LIGHT_MAX from here. // LIGHT_SUN is read as LIGHT_MAX from here.
u8 light_LUT[LIGHT_MAX+1] = u8 light_LUT[LIGHT_MAX+1];
{
/* Middle-raised variation of a_n+1 = a_n * 0.786
* Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
* LIGHT_SUN is read as LIGHT_MAX from here.
*/
8,
11+2,
14+7,
18+10,
22+15,
29+20,
37+20,
47+15,
60+10,
76+7,
97+5,
123+2,
157,
200,
255,
};
// the const ref to light_LUT is what is actually used in the code.
const u8 *light_decode_table = light_LUT; const u8 *light_decode_table = light_LUT;
/** Initialize or update the light value tables using the specified \p gamma. /** Initialize or update the light value tables using the specified \p gamma.
@ -65,26 +45,26 @@ void set_light_table(float gamma)
{ {
static const float brightness_step = 255.0f / (LIGHT_MAX + 1); static const float brightness_step = 255.0f / (LIGHT_MAX + 1);
/* These are adjustment values that are added to the calculated light value // this table is pure arbitrary values, made so that
* after gamma is applied. Currently they are used so that given a gamma // at gamma 2.2 the game looks not too dark at light=1,
* of 1.8 the light values set by this function are the same as those // and mostly linear for the rest of the scale.
* hardcoded in the initalizer list for the declaration of light_LUT. // we could try to inverse the gamma power function, but this
*/ // is simpler and quicker.
static const int adjustments[LIGHT_MAX + 1] = { static const int adjustments[LIGHT_MAX + 1] = {
7, -67,
7, -91,
7, -125,
5, -115,
2, -104,
0, -85,
-7, -70,
-20, -63,
-31, -56,
-39, -49,
-43, -42,
-45, -35,
-40, -28,
-25, -22,
0 0
}; };
@ -93,296 +73,13 @@ void set_light_table(float gamma)
float brightness = brightness_step; float brightness = brightness_step;
for (size_t i = 0; i < LIGHT_MAX; i++) { for (size_t i = 0; i < LIGHT_MAX; i++) {
light_LUT[i] = (u8)(255 * powf(brightness / 255.0f, gamma)); light_LUT[i] = (u8)(255 * powf(brightness / 255.0f, 1.0 / gamma));
light_LUT[i] = rangelim(light_LUT[i] + adjustments[i], 0, 255); light_LUT[i] = rangelim(light_LUT[i] + adjustments[i], 0, 255);
if (i > 1 && light_LUT[i] < light_LUT[i-1]) if (i > 1 && light_LUT[i] < light_LUT[i - 1])
light_LUT[i] = light_LUT[i-1] + 1; light_LUT[i] = light_LUT[i - 1] + 1;
brightness += brightness_step; brightness += brightness_step;
} }
light_LUT[LIGHT_MAX] = 255; light_LUT[LIGHT_MAX] = 255;
} }
#endif #endif
#if 0
/*
Made using this and:
- adding 220 as the second last one
- replacing the third last one (212) with 195
#!/usr/bin/python
from math import *
from sys import stdout
# We want 0 at light=0 and 255 at light=LIGHT_MAX
LIGHT_MAX = 14
#FACTOR = 0.69
#FACTOR = 0.75
FACTOR = 0.83
START_FROM_ZERO = False
L = []
if START_FROM_ZERO:
for i in range(1,LIGHT_MAX+1):
L.append(int(round(255.0 * FACTOR ** (i-1))))
L.append(0)
else:
for i in range(1,LIGHT_MAX+1):
L.append(int(round(255.0 * FACTOR ** (i-1))))
L.append(255)
L.reverse()
for i in L:
stdout.write(str(i)+",\n")
*/
u8 light_decode_table[LIGHT_MAX+1] =
{
23,
27,
33,
40,
48,
57,
69,
83,
100,
121,
146,
176,
195,
220,
255,
};
#endif
#if 0
// This is good
// a_n+1 = a_n * 0.786
// Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
// LIGHT_SUN is read as LIGHT_MAX from here.
u8 light_decode_table[LIGHT_MAX+1] =
{
8,
11,
14,
18,
22,
29,
37,
47,
60,
76,
97,
123,
157,
200,
255,
};
#endif
#if 0
// Use for debugging in dark
u8 light_decode_table[LIGHT_MAX+1] =
{
58,
64,
72,
80,
88,
98,
109,
121,
135,
150,
167,
185,
206,
229,
255,
};
#endif
// This is reasonable with classic lighting with a light source
/*u8 light_decode_table[LIGHT_MAX+1] =
{
2,
3,
4,
6,
9,
13,
18,
25,
32,
35,
45,
57,
69,
79,
255
};*/
// As in minecraft, a_n+1 = a_n * 0.8
// NOTE: This doesn't really work that well because this defines
// LIGHT_MAX as dimmer than LIGHT_SUN
// NOTE: Uh, this has had 34 left out; forget this.
/*u8 light_decode_table[LIGHT_MAX+1] =
{
8,
11,
14,
17,
21,
27,
42,
53,
66,
83,
104,
130,
163,
204,
255,
};*/
// This was a quick try of more light, manually quickly made
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
7,
11,
15,
21,
29,
42,
53,
69,
85,
109,
135,
167,
205,
255,
};*/
// This was used for a long time, manually made
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
6,
8,
11,
14,
19,
26,
34,
45,
61,
81,
108,
143,
191,
255,
};*/
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
3,
6,
10,
18,
25,
35,
50,
75,
95,
120,
150,
185,
215,
255,
};*/
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
5,
12,
22,
35,
50,
65,
85,
100,
120,
140,
160,
185,
215,
255,
};*/
// LIGHT_MAX is 14, 0-14 is 15 values
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
9,
12,
14,
16,
20,
26,
34,
45,
61,
81,
108,
143,
191,
255,
};*/
#if 0
/*
#!/usr/bin/python
from math import *
from sys import stdout
# We want 0 at light=0 and 255 at light=LIGHT_MAX
LIGHT_MAX = 14
#FACTOR = 0.69
FACTOR = 0.75
L = []
for i in range(1,LIGHT_MAX+1):
L.append(int(round(255.0 * FACTOR ** (i-1))))
L.append(0)
L.reverse()
for i in L:
stdout.write(str(i)+",\n")
*/
u8 light_decode_table[LIGHT_MAX+1] =
{
0,
6,
8,
11,
14,
19,
26,
34,
45,
61,
81,
108,
143,
191,
255,
};
#endif