Skip to content

Commit 0d61896

Browse files
committed
Lighting update
Prevent shadows from being propagated below islands
1 parent 756b808 commit 0d61896

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

cloudlands.lua

+57-4
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,7 @@ local function renderCores(cores, minp, maxp, blockseed)
14481448
local vm, emerge_min, emerge_max = minetest.get_mapgen_object("voxelmanip")
14491449
vm:get_data(data) -- put all nodes except the ground surface in this array
14501450
local area = VoxelArea:new{MinEdge=emerge_min, MaxEdge=emerge_max}
1451+
local overdrawTop = maxp.y + OVERDRAW
14511452

14521453
local currentBiomeId = -1
14531454
local nodeId_dust
@@ -1555,7 +1556,6 @@ local function renderCores(cores, minp, maxp, blockseed)
15551556
local noisyDepthOfFiller = depth_filler;
15561557
if noisyDepthOfFiller >= 3 then noisyDepthOfFiller = noisyDepthOfFiller + math_floor(randomNumbers[(x + z) % 256] * 3) - 1 end
15571558

1558-
local overdrawTop = maxp.y + OVERDRAW
15591559
local yBottom = math_max(minp.y, coreBottom - 4) -- the -4 is for rare instances when density noise pushes the bottom of the island deeper
15601560
local yBottomIndex = dataBufferIndex + area.ystride * (yBottom - minp.y) -- equivalent to yBottomIndex = area:index(x, yBottom, z)
15611561
local topBlockIndex = -1
@@ -1683,9 +1683,62 @@ local function renderCores(cores, minp, maxp, blockseed)
16831683
if nodeAtPos.name == "air" or nodeAtPos.name == "ignore" then minetest.set_node(decoration.pos, decoration.node) end
16841684
end
16851685

1686-
vm:set_lighting({day=4, night=0}) -- Can't do the flags="nolight" trick here as mod is designed to run with other mapgens
1687-
--vm:calc_lighting()
1688-
vm:calc_lighting(nil, nil, false) -- turning off propegation of shadows from the chunk above will only avoid shadows on the land in some circumstances
1686+
-- Lighting is a problem. Two problems really...
1687+
--
1688+
-- Problem 1:
1689+
-- We can't use the usual lua mapgen lighting trick of flags="nolight" e.g.:
1690+
-- minetest.set_mapgen_params({mgname = "singlenode", flags = "nolight"})
1691+
-- (https://forum.minetest.net/viewtopic.php?t=19836)
1692+
--
1693+
-- because the mod is designed to run with other mapgens. So we must set the light
1694+
-- values to zero at islands before calling calc_lighting() to propegate lighting
1695+
-- down from above.
1696+
--
1697+
-- This causes lighting bugs if we zero the whole emerge_min-emerge_max area because
1698+
-- it leaves hard black at the edges of the emerged area (calc_lighting must assume
1699+
-- a value of zero for light outside the region, and be blending that in)
1700+
--
1701+
-- But we can't simply zero only the minp-maxp area instead, because then calc_lighting
1702+
-- reads the daylight values out of the overdraw area and blends those in, cutting
1703+
-- up shadows with lines of daylight along chunk boundaries.
1704+
--
1705+
-- The correct solution is to zero and calculate the whole emerge_min-emerge_max area,
1706+
-- but only write the calculated lighting information from minp-maxp back into the map,
1707+
-- however the API doesn't appear to provide a fast way to do that.
1708+
--
1709+
-- Workaround: zero an area that extends halfway into the overdraw region, then when
1710+
-- calc_lighting is called it will have daylight (or existing values) at the emerge boundary
1711+
-- but not near the chunk boundary. calc_lighting causes the lighting extremes in the
1712+
-- overdraw region to be blend together which reduces obvious bands of lighting running
1713+
-- along boundaries in chunks which get their lighting overwritten. This is not a
1714+
-- perfect solution, but allows shading without glaringly obvious lighting artifacts,
1715+
-- and any ill effects should be limited to the islands and corrected any time lighting
1716+
-- is updated.
1717+
--
1718+
--
1719+
-- Problem 2:
1720+
-- We don't want islands to blacken the landscape below them in shadow.
1721+
--
1722+
-- Workaround 1: Instead of zeroing the lighting before propegating from above, set it
1723+
-- to 2, so that shadows are never pitch black.
1724+
--
1725+
-- Workaround 2: set the bottom of the chunk to full daylight, ensuring that full
1726+
-- daylight is what propegates down below islands. This has the problem of causing a
1727+
-- bright horizontal band of light where islands approach a chunk floor or ceiling,
1728+
-- but Hallelujah Mountains already had that issue due to having propagate_shadow
1729+
-- turned off when calling calc_lighting. This workaround has the same drawback, but
1730+
-- does a much better job of preventing undesired shadows.
1731+
1732+
local shadowOverdraw = math_floor((minp.x - emerge_min.x) / 2.5 + 0.5)
1733+
local brightMin = {x = emerge_min.x + shadowOverdraw, y = minp.y , z = emerge_min.z + shadowOverdraw}
1734+
local brightMax = {x = emerge_max.x - shadowOverdraw, y = minp.y + 1, z = emerge_max.z - shadowOverdraw}
1735+
local darkMin = {x = emerge_min.x + shadowOverdraw, y = minp.y + 1, z = emerge_min.z + shadowOverdraw}
1736+
local darkMax = {x = emerge_max.x - shadowOverdraw, y = maxp.y , z = emerge_max.z - shadowOverdraw}
1737+
1738+
vm:set_lighting({day=2, night=0}, darkMin, darkMax)
1739+
vm:calc_lighting()
1740+
vm:set_lighting({day=15, night=0}, brightMin, brightMax)
1741+
16891742
vm:write_to_map() -- seems to be unnecessary when other mods that use vm are running
16901743
end
16911744
end

0 commit comments

Comments
 (0)