1
0
mirror of https://github.com/moparisthebest/minetest synced 2024-12-22 23:58:48 -05:00

Optimise getTileInfo()

getTileInfo() ~1.5x faster
getSmoothLight ~2.0x faster
This commit is contained in:
Craig Robbins 2014-11-20 13:36:58 +10:00
parent fcdb1a8fc2
commit ea404979e1
2 changed files with 40 additions and 46 deletions

View File

@ -221,11 +221,11 @@ u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef)
/*
Calculate smooth lighting at the XYZ- corner of p.
Single light bank.
Both light banks
*/
static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
static u16 getSmoothLightCombined(v3s16 p, MeshMakeData *data)
{
static v3s16 dirs8[8] = {
static const v3s16 dirs8[8] = {
v3s16(0,0,0),
v3s16(0,0,1),
v3s16(0,1,0),
@ -239,10 +239,12 @@ static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
INodeDefManager *ndef = data->m_gamedef->ndef();
u16 ambient_occlusion = 0;
u16 light = 0;
u16 light_count = 0;
u8 light_source_max = 0;
for(u32 i=0; i<8; i++)
u16 light_day = 0;
u16 light_night = 0;
for(u32 i = 0; i < 8; i++)
{
MapNode n = data->m_vmanip.getNodeNoEx(p - dirs8[i]);
@ -256,48 +258,44 @@ static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
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)
{
light += decode_light(n.getLight(bank, ndef));
if (f.param_type == CPT_LIGHT && f.solidness != 2) {
light_day += decode_light(n.getLight(LIGHTBANK_DAY, ndef));
light_night += decode_light(n.getLight(LIGHTBANK_NIGHT, ndef));
light_count++;
}
else {
} else {
ambient_occlusion++;
}
}
if(light_count == 0)
return 255;
return 0xffff;
light /= light_count;
light_day /= light_count;
light_night /= light_count;
// Boost brightness around light sources
if(decode_light(light_source_max) >= light)
//return decode_light(undiminish_light(light_source_max));
return decode_light(light_source_max);
bool skip_ambient_occlusion = false;
if(decode_light(light_source_max) >= light_day) {
light_day = decode_light(light_source_max);
skip_ambient_occlusion = true;
}
if(decode_light(light_source_max) >= light_night) {
light_night = decode_light(light_source_max);
skip_ambient_occlusion = true;
}
if(ambient_occlusion > 4)
if(ambient_occlusion > 4 && !skip_ambient_occlusion)
{
//calculate table index for gamma space multiplier
ambient_occlusion -= 5;
//table of precalculated gamma space multiply factors
//light^2.2 * factor (0.75, 0.5, 0.25, 0.0), so table holds factor ^ (1 / 2.2)
const float light_amount[4] = {0.877424315, 0.729740053, 0.532520545, 0.0};
light = core::clamp(core::round32(light*light_amount[ambient_occlusion]), 0, 255);
static const float light_amount[4] = {0.877424315, 0.729740053, 0.532520545, 0.0};
light_day = rangelim(core::round32(light_day*light_amount[ambient_occlusion]), 0, 255);
light_night = rangelim(core::round32(light_night*light_amount[ambient_occlusion]), 0, 255);
}
return light;
}
/*
Calculate smooth lighting at the XYZ- corner of p.
Both light banks.
*/
static u16 getSmoothLight(v3s16 p, MeshMakeData *data)
{
u16 day = getSmoothLight(LIGHTBANK_DAY, p, data);
u16 night = getSmoothLight(LIGHTBANK_NIGHT, p, data);
return day | (night << 8);
return light_day | (light_night << 8);
}
/*
@ -307,13 +305,13 @@ static u16 getSmoothLight(v3s16 p, MeshMakeData *data)
u16 getSmoothLight(v3s16 p, v3s16 corner, MeshMakeData *data)
{
if(corner.X == 1) p.X += 1;
else assert(corner.X == -1);
// else corner.X == -1
if(corner.Y == 1) p.Y += 1;
else assert(corner.Y == -1);
// else corner.Y == -1
if(corner.Z == 1) p.Z += 1;
else assert(corner.Z == -1);
// else corner.Z == -1
return getSmoothLight(p, data);
return getSmoothLightCombined(p, data);
}
/*

View File

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h" // For ser_ver_supported
#include "util/serialize.h"
#include "log.h"
#include "util/numeric.h"
#include <string>
#include <sstream>
@ -77,19 +78,14 @@ u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
const ContentFeatures &f = nodemgr->get(*this);
u8 light = 0;
u8 light;
if(f.param_type == CPT_LIGHT)
{
if(bank == LIGHTBANK_DAY)
light = param1 & 0x0f;
else if(bank == LIGHTBANK_NIGHT)
light = (param1>>4)&0x0f;
else
assert(0);
}
if(f.light_source > light)
light = f.light_source;
return light;
light = bank == LIGHTBANK_DAY ? param1 & 0x0f : (param1 >> 4) & 0x0f;
else
light = 0;
return MYMAX(f.light_source, light);
}
bool MapNode::getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const