]> git.lizzy.rs Git - minetest.git/blob - games/devtest/mods/lighting/init.lua
Add dynamic exposure correction (#12959)
[minetest.git] / games / devtest / mods / lighting / init.lua
1 local lighting_sections = {
2         {n = "shadows", d = "Shadows",
3                 entries = {
4                         { n = "intensity", d = "Shadow Intensity", min = 0, max = 1 }
5                 }
6         },
7         {
8                 n = "exposure", d = "Exposure",
9                 entries = {
10                         {n = "luminance_min", d = "Minimum Luminance", min = -10, max = 10},
11                         {n = "luminance_max", d = "Maximum Luminance", min = -10, max = 10},
12                         {n = "exposure_correction", d = "Exposure Correction", min = -10, max = 10},
13                         {n = "speed_dark_bright", d = "Bright light adaptation speed", min = -10, max = 10, type="log2"},
14                         {n = "speed_bright_dark", d = "Dark scene adaptation speed", min = -10, max = 10, type="log2"},
15                         {n = "center_weight_power", d = "Power factor for center-weighting", min = 0.1, max = 10},
16                 }
17         }
18 }
19
20 local function dump_lighting(lighting)
21         local result = "{\n"
22         local section_count = 0
23         for _,section in ipairs(lighting_sections) do
24                 section_count = section_count + 1
25
26                 local parameters = section.entries or {}
27                 local state = lighting[section.n] or {}
28
29                 result = result.."  "..section.n.." = {\n"
30
31                 local count = 0
32                 for _,v in ipairs(parameters) do
33                         count = count + 1
34                         result = result.."    "..v.n.." = "..(math.floor(state[v.n] * 1000)/1000)
35                         if count < #parameters then
36                                 result = result..","
37                         end
38                         result = result.."\n"
39                 end
40
41                 result = result.."  }"
42
43                 if section_count < #lighting_sections then
44                         result = result..","
45                 end
46                 result = result.."\n"
47         end
48         result = result .."}"
49         return result
50 end
51
52 minetest.register_chatcommand("set_lighting", {
53         params = "",
54         description = "Tune lighting parameters",
55         func = function(player_name, param)
56                 local player = minetest.get_player_by_name(player_name);
57                 if not player then return end
58
59                 local lighting = player:get_lighting()
60                 local exposure = lighting.exposure or {}
61
62                 local form = {
63                         "formspec_version[2]",
64                         "size[15,30]",
65                         "position[0.99,0.15]",
66                         "anchor[1,0]",
67                         "padding[0.05,0.1]",
68                         "no_prepend[]"
69                 };
70
71                 local line = 1
72                 for _,section in ipairs(lighting_sections) do
73                         local parameters = section.entries or {}
74                         local state = lighting[section.n] or {}
75
76                         table.insert(form, "label[1,"..line..";"..section.d.."]")
77                         line  = line + 1
78
79                         for _,v in ipairs(parameters) do
80                                 table.insert(form, "label[2,"..line..";"..v.d.."]")
81                                 table.insert(form, "scrollbaroptions[min=0;max=1000;smallstep=10;largestep=100;thumbsize=10]")
82                                 local value = state[v.n]
83                                 if v.type == "log2" then
84                                         value = math.log(value or 1) / math.log(2)
85                                 end
86                                 local sb_scale = math.floor(1000 * (math.max(v.min, value or 0) - v.min) / (v.max - v.min))
87                                 table.insert(form, "scrollbar[2,"..(line+0.7)..";12,1;horizontal;"..section.n.."."..v.n..";"..sb_scale.."]")
88                                 line = line + 2.7
89                         end
90
91                         line = line + 1
92                 end
93
94                 minetest.show_formspec(player_name, "lighting", table.concat(form))
95                 local debug_value = dump_lighting(lighting)
96                 local debug_ui = player:hud_add({type="text", position={x=0.1, y=0.3}, scale={x=1,y=1}, alignment = {x=1, y=1}, text=debug_value, number=0xFFFFFF})
97                 player:get_meta():set_int("lighting_hud", debug_ui)
98         end
99 })
100
101 minetest.register_on_player_receive_fields(function(player, formname, fields)
102         if formname ~= "lighting" then return end
103
104         if not player then return end
105
106         local hud_id = player:get_meta():get_int("lighting_hud")
107
108         if fields.quit then
109                 player:hud_remove(hud_id)
110                 player:get_meta():set_int("lighting_hud", -1)
111                 return
112         end
113
114         local lighting = player:get_lighting()
115         for _,section in ipairs(lighting_sections) do
116                 local parameters = section.entries or {}
117
118                 local state = (lighting[section.n] or {})
119                 lighting[section.n] = state
120
121                 for _,v in ipairs(parameters) do
122                         
123                         if fields[section.n.."."..v.n] then
124                                 local event = minetest.explode_scrollbar_event(fields[section.n.."."..v.n])
125                                 if event.type == "CHG" then
126                                         local value = v.min + (v.max - v.min) * (event.value / 1000);
127                                         if v.type == "log2" then
128                                                 value = math.pow(2, value);
129                                         end
130                                         state[v.n] = value;
131                                 end
132                         end
133                 end
134         end
135
136         local debug_value = dump_lighting(lighting)
137         player:hud_change(hud_id, "text", debug_value)
138
139         player:set_lighting(lighting)
140 end)