Skip to content

Commit

Permalink
Optimize lighting calculation (minetest#12797)
Browse files Browse the repository at this point in the history
  • Loading branch information
TurkeyMcMac committed Oct 9, 2022
1 parent 440d966 commit 9676364
Show file tree
Hide file tree
Showing 18 changed files with 188 additions and 220 deletions.
21 changes: 10 additions & 11 deletions src/client/clientmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,8 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
{
v3s16 p = floatToInt(p0 /*+ dir * 3*BS*/, BS);
MapNode n = map->getNode(p);
if(ndef->get(n).param_type == CPT_LIGHT &&
!ndef->get(n).sunlight_propagates)
if(ndef->getLightingFlags(n).has_light &&
!ndef->getLightingFlags(n).sunlight_propagates)
allow_allowing_non_sunlight_propagates = true;
}
// If would start at CONTENT_IGNORE, start closer
Expand All @@ -549,15 +549,13 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,

v3s16 p = floatToInt(pf, BS);
MapNode n = map->getNode(p);
ContentLightingFlags f = ndef->getLightingFlags(n);
if (allow_allowing_non_sunlight_propagates && i == 0 &&
ndef->get(n).param_type == CPT_LIGHT &&
!ndef->get(n).sunlight_propagates) {
f.has_light && !f.sunlight_propagates) {
allow_non_sunlight_propagates = true;
}

if (ndef->get(n).param_type != CPT_LIGHT ||
(!ndef->get(n).sunlight_propagates &&
!allow_non_sunlight_propagates)){
if (!f.has_light || (!f.sunlight_propagates && !allow_non_sunlight_propagates)){
nonlight_seen = true;
noncount++;
if(noncount >= 4)
Expand All @@ -566,10 +564,10 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
}

if (distance >= sunlight_min_d && !*sunlight_seen && !nonlight_seen)
if (n.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN)
if (n.getLight(LIGHTBANK_DAY, f) == LIGHT_SUN)
*sunlight_seen = true;
noncount = 0;
brightness_sum += decode_light(n.getLightBlend(daylight_factor, ndef));
brightness_sum += decode_light(n.getLightBlend(daylight_factor, f));
brightness_count++;
}
*result = 0;
Expand Down Expand Up @@ -653,8 +651,9 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
int ret = 0;
if(brightness_count == 0){
MapNode n = getNode(floatToInt(m_camera_position, BS));
if(m_nodedef->get(n).param_type == CPT_LIGHT){
ret = decode_light(n.getLightBlend(daylight_factor, m_nodedef));
ContentLightingFlags f = m_nodedef->getLightingFlags(n);
if(f.has_light){
ret = decode_light(n.getLightBlend(daylight_factor, f));
} else {
ret = oldvalue;
}
Expand Down
3 changes: 2 additions & 1 deletion src/client/content_cso.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientenvironment.h"
#include "client.h"
#include "map.h"
#include "nodedef.h"

class SmokePuffCSO: public ClientSimpleObject
{
Expand Down Expand Up @@ -50,7 +51,7 @@ class SmokePuffCSO: public ClientSimpleObject
bool pos_ok;
MapNode n = env->getMap().getNode(floatToInt(pos, BS), &pos_ok);
light = pos_ok ? decode_light(n.getLightBlend(env->getDayNightRatio(),
env->getGameDef()->ndef()))
env->getGameDef()->ndef()->getLightingFlags(n)))
: 64;
video::SColor color(255,light,light,light);
m_spritenode->setColor(color);
Expand Down
2 changes: 1 addition & 1 deletion src/client/content_mapblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ void MapblockMeshGenerator::prepareLiquidNodeDrawing()
// it at what it emits, for an increased effect
u8 e = decode_light(f->light_source);
light = LightPair(std::max(e, light.lightDay), std::max(e, light.lightNight));
} else if (nodedef->get(ntop).param_type == CPT_LIGHT) {
} else if (nodedef->getLightingFlags(ntop).has_light) {
// Otherwise, use the light of the node on top if possible
light = LightPair(getInteriorLight(ntop, 0, nodedef));
}
Expand Down
16 changes: 9 additions & 7 deletions src/client/mapblock_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void MeshMakeData::setSmoothLighting(bool smooth_lighting)
static u8 getInteriorLight(enum LightBank bank, MapNode n, s32 increment,
const NodeDefManager *ndef)
{
u8 light = n.getLight(bank, ndef);
u8 light = n.getLight(bank, ndef->getLightingFlags(n));
if (light > 0)
light = rangelim(light + increment, 0, LIGHT_SUN);
return decode_light(light);
Expand All @@ -126,17 +126,19 @@ u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef)
static u8 getFaceLight(enum LightBank bank, MapNode n, MapNode n2,
v3s16 face_dir, const NodeDefManager *ndef)
{
ContentLightingFlags f1 = ndef->getLightingFlags(n);
ContentLightingFlags f2 = ndef->getLightingFlags(n2);

u8 light;
u8 l1 = n.getLight(bank, ndef);
u8 l2 = n2.getLight(bank, ndef);
u8 l1 = n.getLight(bank, f1);
u8 l2 = n2.getLight(bank, f2);
if(l1 > l2)
light = l1;
else
light = l2;

// Boost light level for light sources
u8 light_source = MYMAX(ndef->get(n).light_source,
ndef->get(n2).light_source);
u8 light_source = MYMAX(f1.light_source, f2.light_source);
if(light_source > light)
light = light_source;

Expand Down Expand Up @@ -184,8 +186,8 @@ static u16 getSmoothLightCombined(const v3s16 &p,
light_source_max = f.light_source;
// Check f.solidness because fast-style leaves look better this way
if (f.param_type == CPT_LIGHT && f.solidness != 2) {
u8 light_level_day = n.getLightNoChecks(LIGHTBANK_DAY, &f);
u8 light_level_night = n.getLightNoChecks(LIGHTBANK_NIGHT, &f);
u8 light_level_day = n.getLight(LIGHTBANK_DAY, f.getLightingFlags());
u8 light_level_night = n.getLight(LIGHTBANK_NIGHT, f.getLightingFlags());
if (light_level_day == LIGHT_SUN)
direct_sunlight = true;
light_day += decode_light(light_level_day);
Expand Down
3 changes: 2 additions & 1 deletion src/client/particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ void Particle::updateLight()
);
MapNode n = m_env->getClientMap().getNode(p, &pos_ok);
if (pos_ok)
light = n.getLightBlend(m_env->getDayNightRatio(), m_gamedef->ndef());
light = n.getLightBlend(m_env->getDayNightRatio(),
m_gamedef->ndef()->getLightingFlags(n));
else
light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0);

Expand Down
21 changes: 11 additions & 10 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,19 +213,19 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
}

// Set the node on the map
const ContentFeatures &cf = m_nodedef->get(n);
const ContentFeatures &oldcf = m_nodedef->get(oldnode);
if (cf.lightingEquivalent(oldcf)) {
ContentLightingFlags f = m_nodedef->getLightingFlags(n);
ContentLightingFlags oldf = m_nodedef->getLightingFlags(oldnode);
if (f == oldf) {
// No light update needed, just copy over the old light.
n.setLight(LIGHTBANK_DAY, oldnode.getLightRaw(LIGHTBANK_DAY, oldcf), cf);
n.setLight(LIGHTBANK_NIGHT, oldnode.getLightRaw(LIGHTBANK_NIGHT, oldcf), cf);
n.setLight(LIGHTBANK_DAY, oldnode.getLightRaw(LIGHTBANK_DAY, oldf), f);
n.setLight(LIGHTBANK_NIGHT, oldnode.getLightRaw(LIGHTBANK_NIGHT, oldf), f);
set_node_in_block(block, relpos, n);

modified_blocks[blockpos] = block;
} else {
// Ignore light (because calling voxalgo::update_lighting_nodes)
n.setLight(LIGHTBANK_DAY, 0, cf);
n.setLight(LIGHTBANK_NIGHT, 0, cf);
n.setLight(LIGHTBANK_DAY, 0, f);
n.setLight(LIGHTBANK_NIGHT, 0, f);
set_node_in_block(block, relpos, n);

// Update lighting
Expand Down Expand Up @@ -780,8 +780,9 @@ void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
}

// Ignore light (because calling voxalgo::update_lighting_nodes)
n0.setLight(LIGHTBANK_DAY, 0, m_nodedef);
n0.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
ContentLightingFlags f0 = m_nodedef->getLightingFlags(n0);
n0.setLight(LIGHTBANK_DAY, 0, f0);
n0.setLight(LIGHTBANK_NIGHT, 0, f0);

// Find out whether there is a suspect for this action
std::string suspect;
Expand Down Expand Up @@ -1122,7 +1123,7 @@ bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
MapNode node = getNode(pos_node, &is_valid_position);

if (is_valid_position &&
!m_nodedef->get(node).light_propagates) {
!m_nodedef->getLightingFlags(node).light_propagates) {
// Cannot see through light-blocking nodes --> occluded
count++;
if (count >= needed_count)
Expand Down
2 changes: 1 addition & 1 deletion src/mapblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void MapBlock::actuallyUpdateDayNightDiff()
if (n == previous_n)
continue;

differs = !n.isLightDayNightEq(nodemgr);
differs = !n.isLightDayNightEq(nodemgr->getLightingFlags(n));
if (differs)
break;
previous_n = n;
Expand Down
6 changes: 3 additions & 3 deletions src/mapgen/mapgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ void Mapgen::lightSpread(VoxelArea &a, std::queue<std::pair<v3s16, u8>> &queue,
// we hit a solid block that light cannot pass through.
if ((light_day <= (n.param1 & 0x0F) &&
light_night <= (n.param1 & 0xF0)) ||
!ndef->get(n).light_propagates)
!ndef->getLightingFlags(n).light_propagates)
return;

// MYMAX still needed here because we only exit early if both banks have
Expand Down Expand Up @@ -500,7 +500,7 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow)

for (int y = a.MaxEdge.Y; y >= a.MinEdge.Y; y--) {
MapNode &n = vm->m_data[i];
if (!ndef->get(n).sunlight_propagates)
if (!ndef->getLightingFlags(n).sunlight_propagates)
break;
n.param1 = LIGHT_SUN;
VoxelArea::add_y(em, i, -1);
Expand All @@ -525,7 +525,7 @@ void Mapgen::spreadLight(const v3s16 &nmin, const v3s16 &nmax)
if (n.getContent() == CONTENT_IGNORE)
continue;

const ContentFeatures &cf = ndef->get(n);
ContentLightingFlags cf = ndef->getLightingFlags(n);
if (!cf.light_propagates)
continue;

Expand Down
2 changes: 1 addition & 1 deletion src/mapgen/mapgen_singlenode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ MapgenSinglenode::MapgenSinglenode(MapgenParams *params, EmergeParams *emerge)
c_node = CONTENT_AIR;

MapNode n_node(c_node);
set_light = (ndef->get(n_node).sunlight_propagates) ? LIGHT_SUN : 0x00;
set_light = (ndef->getLightingFlags(n_node).sunlight_propagates) ? LIGHT_SUN : 0x00;
}


Expand Down
89 changes: 0 additions & 89 deletions src/mapnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,95 +53,6 @@ void MapNode::getColor(const ContentFeatures &f, video::SColor *color) const
*color = f.color;
}

void MapNode::setLight(LightBank bank, u8 a_light, const ContentFeatures &f) noexcept
{
// If node doesn't contain light data, ignore this
if(f.param_type != CPT_LIGHT)
return;
if(bank == LIGHTBANK_DAY)
{
param1 &= 0xf0;
param1 |= a_light & 0x0f;
}
else if(bank == LIGHTBANK_NIGHT)
{
param1 &= 0x0f;
param1 |= (a_light & 0x0f)<<4;
}
else
assert("Invalid light bank" == NULL);
}

void MapNode::setLight(LightBank bank, u8 a_light, const NodeDefManager *nodemgr)
{
setLight(bank, a_light, nodemgr->get(*this));
}

bool MapNode::isLightDayNightEq(const NodeDefManager *nodemgr) const
{
const ContentFeatures &f = nodemgr->get(*this);
bool isEqual;

if (f.param_type == CPT_LIGHT) {
u8 day = MYMAX(f.light_source, param1 & 0x0f);
u8 night = MYMAX(f.light_source, (param1 >> 4) & 0x0f);
isEqual = day == night;
} else {
isEqual = true;
}

return isEqual;
}

u8 MapNode::getLight(LightBank bank, const NodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
const ContentFeatures &f = nodemgr->get(*this);

u8 light;
if(f.param_type == CPT_LIGHT)
light = bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f;
else
light = 0;

return MYMAX(f.light_source, light);
}

u8 MapNode::getLightRaw(LightBank bank, const ContentFeatures &f) const noexcept
{
if(f.param_type == CPT_LIGHT)
return bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f;
return 0;
}

u8 MapNode::getLightNoChecks(LightBank bank, const ContentFeatures *f) const noexcept
{
return MYMAX(f->light_source,
bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f);
}

bool MapNode::getLightBanks(u8 &lightday, u8 &lightnight,
const NodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
const ContentFeatures &f = nodemgr->get(*this);
if(f.param_type == CPT_LIGHT)
{
lightday = param1 & 0x0f;
lightnight = (param1>>4)&0x0f;
}
else
{
lightday = 0;
lightnight = 0;
}
if(f.light_source > lightday)
lightday = f.light_source;
if(f.light_source > lightnight)
lightnight = f.light_source;
return f.param_type == CPT_LIGHT || f.light_source != 0;
}

u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
bool allow_wallmounted) const
{
Expand Down
Loading

0 comments on commit 9676364

Please sign in to comment.