minetest/src/light.cpp

389 lines
5.4 KiB
C++
Raw Normal View History

/*
2013-02-24 18:40:43 +01:00
Minetest
2013-02-24 19:38:45 +01:00
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
2010-11-27 00:02:21 +01:00
#include "light.h"
2014-12-14 12:28:08 +01:00
#include <math.h>
#include "util/numeric.h"
#ifndef SERVER
2010-11-27 00:02:21 +01:00
// Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
// LIGHT_SUN is read as LIGHT_MAX from here.
2014-12-14 12:28:08 +01:00
u8 light_LUT[LIGHT_MAX+1] =
{
2014-12-14 12:28:08 +01:00
/* 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,
};
2014-12-14 12:28:08 +01:00
const u8 *light_decode_table = light_LUT;
/** Initialize or update the light value tables using the specified \p gamma.
* If \p gamma == 1.0 then the light table is linear. Typically values for
* gamma range between 1.8 and 2.2.
*
* @note The value for gamma will be restricted to the range 1.1 <= gamma <= 3.0.
*
* @note This function is not, currently, a simple linear to gamma encoding
* because adjustments are made so that a gamma of 1.8 gives the same
* results as those hardcoded for use by the server.
*/
void set_light_table(float gamma)
{
static const float brightness_step = 255.0f / (LIGHT_MAX + 1);
/* These are adjustment values that are added to the calculated light value
* after gamma is applied. Currently they are used so that given a gamma
* of 1.8 the light values set by this function are the same as those
* hardcoded in the initalizer list for the declaration of light_LUT.
*/
static const int adjustments[LIGHT_MAX + 1] = {
7,
7,
7,
5,
2,
0,
-7,
-20,
-31,
-39,
-43,
-45,
-40,
-25,
0
};
gamma = rangelim(gamma, 1.0, 3.0);
2014-12-14 12:28:08 +01:00
float brightness = brightness_step;
for (size_t i = 0; i < LIGHT_MAX; i++) {
light_LUT[i] = (u8)(255 * powf(brightness / 255.0f, gamma));
light_LUT[i] = rangelim(light_LUT[i] + adjustments[i], 0, 255);
if (i > 1 && light_LUT[i] < light_LUT[i-1])
light_LUT[i] = light_LUT[i-1] + 1;
brightness += brightness_step;
}
light_LUT[LIGHT_MAX] = 255;
}
#endif
2014-12-14 12:28:08 +01:00
#if 0
2012-01-26 18:57:21 +01:00
/*
Made using this and:
- adding 220 as the second last one
- replacing the third last one (212) with 195
2012-01-26 18:57:21 +01:00
#!/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,
2012-01-26 18:57:21 +01:00
255,
};
#endif
#if 0
// This is good
2011-02-04 00:22:07 +01:00
// 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,
};
2012-01-26 18:57:21 +01:00
#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
};*/
2011-02-04 00:22:07 +01:00
// 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] =
2010-12-19 15:51:45 +01:00
{
2011-02-04 00:22:07 +01:00
8,
11,
14,
17,
21,
27,
42,
53,
66,
83,
104,
130,
163,
204,
255,
2010-12-19 15:51:45 +01:00
};*/
2011-02-04 00:22:07 +01:00
// This was a quick try of more light, manually quickly made
/*u8 light_decode_table[LIGHT_MAX+1] =
2010-11-27 00:02:21 +01:00
{
0,
2011-02-02 17:46:14 +01:00
7,
11,
15,
21,
29,
42,
53,
69,
85,
109,
135,
167,
205,
255,
2011-02-04 00:22:07 +01:00
};*/
// This was used for a long time, manually made
2011-02-02 17:46:14 +01:00
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
2010-12-19 15:51:45 +01:00
6,
8,
11,
14,
2010-12-19 15:51:45 +01:00
19,
26,
34,
45,
61,
81,
108,
143,
191,
2010-11-27 00:02:21 +01:00
255,
2011-02-02 17:46:14 +01:00
};*/
2011-02-04 00:22:07 +01:00
2010-12-19 15:51:45 +01:00
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
3,
6,
10,
18,
25,
35,
50,
75,
95,
120,
150,
185,
215,
255,
2010-11-27 00:02:21 +01:00
};*/
2010-12-19 15:51:45 +01:00
/*u8 light_decode_table[LIGHT_MAX+1] =
{
0,
5,
12,
22,
35,
50,
65,
85,
100,
120,
140,
160,
185,
215,
255,
2010-12-19 15:51:45 +01:00
};*/
// 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,
};*/
2010-11-27 00:02:21 +01:00
#if 0
2010-11-27 00:02:21 +01:00
/*
#!/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
2010-12-13 02:19:12 +01:00
2010-11-27 00:02:21 +01:00