Skip to content

Commit b4df0d6

Browse files
numberZeroparamat
authored andcommittedJan 12, 2018
Fix ambient occlusion and dark lines at mapblock borders
1 parent f77f19a commit b4df0d6

File tree

1 file changed

+27
-70
lines changed

1 file changed

+27
-70
lines changed
 

‎src/mapblock_mesh.cpp

+27-70
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef)
196196
Both light banks
197197
*/
198198
static u16 getSmoothLightCombined(const v3s16 &p,
199-
const std::array<v3s16,8> &dirs, MeshMakeData *data, bool node_solid)
199+
const std::array<v3s16,8> &dirs, MeshMakeData *data)
200200
{
201201
INodeDefManager *ndef = data->m_client->ndef();
202202

@@ -206,8 +206,14 @@ static u16 getSmoothLightCombined(const v3s16 &p,
206206
u16 light_day = 0;
207207
u16 light_night = 0;
208208

209-
auto add_node = [&] (int i) -> const ContentFeatures& {
209+
auto add_node = [&] (u8 i, bool obstructed = false) -> bool {
210+
if (obstructed) {
211+
ambient_occlusion++;
212+
return false;
213+
}
210214
MapNode n = data->m_vmanip.getNodeNoExNoEmerge(p + dirs[i]);
215+
if (n.getContent() == CONTENT_IGNORE)
216+
return true;
211217
const ContentFeatures &f = ndef->get(n);
212218
if (f.light_source > light_source_max)
213219
light_source_max = f.light_source;
@@ -219,37 +225,24 @@ static u16 getSmoothLightCombined(const v3s16 &p,
219225
} else {
220226
ambient_occlusion++;
221227
}
222-
return f;
228+
return f.light_propagates;
223229
};
224230

225-
if (node_solid) {
226-
ambient_occlusion = 3;
227-
bool corner_obstructed = true;
228-
for (int i = 0; i < 2; ++i) {
229-
if (add_node(i).light_propagates)
230-
corner_obstructed = false;
231-
}
232-
add_node(2);
233-
add_node(3);
234-
if (corner_obstructed)
235-
ambient_occlusion++;
236-
else
237-
add_node(4);
238-
} else {
239-
std::array<bool, 4> obstructed = {{ 1, 1, 1, 1 }};
240-
add_node(0);
241-
bool opaque1 = !add_node(1).light_propagates;
242-
bool opaque2 = !add_node(2).light_propagates;
243-
bool opaque3 = !add_node(3).light_propagates;
244-
obstructed[0] = opaque1 && opaque2;
245-
obstructed[1] = opaque1 && opaque3;
246-
obstructed[2] = opaque2 && opaque3;
247-
for (int k = 0; k < 4; ++k) {
248-
if (obstructed[k])
249-
ambient_occlusion++;
250-
else if (add_node(k + 4).light_propagates)
251-
obstructed[3] = false;
252-
}
231+
std::array<bool, 4> obstructed = {{ 1, 1, 1, 1 }};
232+
add_node(0);
233+
bool opaque1 = !add_node(1);
234+
bool opaque2 = !add_node(2);
235+
bool opaque3 = !add_node(3);
236+
obstructed[0] = opaque1 && opaque2;
237+
obstructed[1] = opaque1 && opaque3;
238+
obstructed[2] = opaque2 && opaque3;
239+
for (u8 k = 0; k < 3; ++k)
240+
if (add_node(k + 4, obstructed[k]))
241+
obstructed[3] = false;
242+
if (add_node(7, obstructed[3])) { // wrap light around nodes
243+
ambient_occlusion -= 3;
244+
for (u8 k = 0; k < 3; ++k)
245+
add_node(k + 4, !obstructed[k]);
253246
}
254247

255248
if (light_count == 0) {
@@ -277,7 +270,7 @@ static u16 getSmoothLightCombined(const v3s16 &p,
277270
g_settings->getFloat("ambient_occlusion_gamma"), 0.25, 4.0);
278271

279272
// Table of gamma space multiply factors.
280-
static const float light_amount[3] = {
273+
static thread_local const float light_amount[3] = {
281274
powf(0.75, 1.0 / ao_gamma),
282275
powf(0.5, 1.0 / ao_gamma),
283276
powf(0.25, 1.0 / ao_gamma)
@@ -304,43 +297,7 @@ static u16 getSmoothLightCombined(const v3s16 &p,
304297
*/
305298
u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data)
306299
{
307-
v3s16 neighbor_offset1, neighbor_offset2;
308-
309-
/*
310-
* face_dir, neighbor_offset1 and neighbor_offset2 define an
311-
* orthonormal basis which is used to define the offsets of the 8
312-
* surrounding nodes and to differentiate the "distance" (by going only
313-
* along directly neighboring nodes) relative to the node at p.
314-
* Apart from the node at p, only the 4 nodes which contain face_dir
315-
* can contribute light.
316-
*/
317-
if (face_dir.X != 0) {
318-
neighbor_offset1 = v3s16(0, corner.Y, 0);
319-
neighbor_offset2 = v3s16(0, 0, corner.Z);
320-
} else if (face_dir.Y != 0) {
321-
neighbor_offset1 = v3s16(0, 0, corner.Z);
322-
neighbor_offset2 = v3s16(corner.X, 0, 0);
323-
} else if (face_dir.Z != 0) {
324-
neighbor_offset1 = v3s16(corner.X,0,0);
325-
neighbor_offset2 = v3s16(0,corner.Y,0);
326-
}
327-
328-
const std::array<v3s16,8> dirs = {{
329-
// Always shine light
330-
neighbor_offset1 + face_dir,
331-
neighbor_offset2 + face_dir,
332-
v3s16(0,0,0),
333-
face_dir,
334-
335-
// Can be obstructed
336-
neighbor_offset1 + neighbor_offset2 + face_dir,
337-
338-
// Do not shine light, only for ambient occlusion
339-
neighbor_offset1,
340-
neighbor_offset2,
341-
neighbor_offset1 + neighbor_offset2
342-
}};
343-
return getSmoothLightCombined(p, dirs, data, true);
300+
return getSmoothLightTransparent(p + face_dir, corner - 2 * face_dir, data);
344301
}
345302

346303
/*
@@ -363,7 +320,7 @@ u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData
363320
v3s16(0,corner.Y,corner.Z),
364321
v3s16(corner.X,corner.Y,corner.Z)
365322
}};
366-
return getSmoothLightCombined(p, dirs, data, false);
323+
return getSmoothLightCombined(p, dirs, data);
367324
}
368325

369326
void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){

0 commit comments

Comments
 (0)
Please sign in to comment.