Ambient light and server control for that

This commit is contained in:
Andrey2470T 2024-02-03 20:06:54 +03:00
parent 728f643ea7
commit 02d0c826fe
13 changed files with 92 additions and 17 deletions

@ -8,6 +8,8 @@ uniform float fogShadingParameter;
// The cameraOffset is the current center of the visible world.
uniform highp vec3 cameraOffset;
uniform float animationTimer;
uniform vec3 ambientColor;
#ifdef ENABLE_DYNAMIC_SHADOWS
// shadow texture
uniform sampler2D ShadowMapSampler;
@ -375,7 +377,7 @@ void main(void)
#endif
color = base.rgb;
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
vec4 col = vec4(color.rgb * varColor.rgb * ambientColor.rgb, 1.0);
#ifdef ENABLE_DYNAMIC_SHADOWS
if (f_shadow_strength > 0.0) {

@ -8,6 +8,8 @@ uniform float fogShadingParameter;
// The cameraOffset is the current center of the visible world.
uniform highp vec3 cameraOffset;
uniform float animationTimer;
uniform vec3 ambientColor;
#ifdef ENABLE_DYNAMIC_SHADOWS
// shadow texture
uniform sampler2D ShadowMapSampler;
@ -378,7 +380,7 @@ void main(void)
#endif
color = base.rgb;
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
vec4 col = vec4(color.rgb * varColor.rgb * ambientColor.rgb, 1.0);
col.rgb *= vIDiff;
#ifdef ENABLE_DYNAMIC_SHADOWS

@ -261,7 +261,8 @@ void ClientEnvironment::step(float dtime)
node_at_lplayer = m_map->getNode(p);
u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef());
lplayer->light_color = encode_light(light, 0); // this transfers light.alpha
lplayer->light_color = encode_light(light, 0,
m_client->getEnv().getLocalPlayer()->getLighting().ambient_light.luminance); // this transfers light.alpha
final_color_blend(&lplayer->light_color, light, day_night_ratio);
}

@ -907,7 +907,8 @@ void GenericCAO::updateLight(u32 day_night_ratio)
// Encode light into color, adding a small boost
// based on the entity glow.
if (m_enable_shaders)
light = encode_light(light_at_pos, m_prop.glow);
light = encode_light(light_at_pos, m_prop.glow,
m_client->getEnv().getLocalPlayer()->getLighting().ambient_light.luminance);
else
final_color_blend(&light, light_at_pos, day_night_ratio);

@ -80,6 +80,7 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
nodedef(data->nodedef),
meshmanip(mm),
blockpos_nodes(data->m_blockpos * MAP_BLOCKSIZE),
player(data->m_client->getEnv().getLocalPlayer()),
enable_mesh_cache(g_settings->getBool("enable_mesh_cache") &&
!data->m_smooth_lighting) // Mesh cache is not supported with smooth lighting
{
@ -92,7 +93,8 @@ void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, boo
else
getTile(index, &cur_node.tile);
if (!data->m_smooth_lighting)
cur_node.color = encode_light(cur_node.light, cur_node.f->light_source);
cur_node.color = encode_light(cur_node.light, cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
for (auto &layer : cur_node.tile.layers) {
layer.material_flags |= set_flags;
@ -301,7 +303,8 @@ LightInfo MapblockMeshGenerator::blendLight(const v3f &vertex_pos)
video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos)
{
LightInfo light = blendLight(vertex_pos);
return encode_light(light.getPair(), cur_node.f->light_source);
return encode_light(light.getPair(), cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
}
video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos,
@ -309,7 +312,8 @@ video::SColor MapblockMeshGenerator::blendLightColor(const v3f &vertex_pos,
{
LightInfo light = blendLight(vertex_pos);
video::SColor color = encode_light(light.getPair(MYMAX(0.0f, vertex_normal.Y)),
cur_node.f->light_source);
cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
if (!cur_node.f->light_source)
applyFacesShading(color, vertex_normal);
return color;
@ -384,7 +388,8 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
for (int j = 0; j < 4; j++) {
video::S3DVertex &vertex = vertices[j];
final_lights[j] = lights[light_indices[face][j]].getPair(MYMAX(0.0f, vertex.Normal.Y));
vertex.Color = encode_light(final_lights[j], cur_node.f->light_source);
vertex.Color = encode_light(final_lights[j], cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
if (!cur_node.f->light_source)
applyFacesShading(vertex.Color, vertex.Normal);
}
@ -394,7 +399,8 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
});
} else {
drawCuboid(box, tiles, tile_count, txc, mask, [&] (int face, video::S3DVertex vertices[4]) {
video::SColor color = encode_light(cur_node.light, cur_node.f->light_source);
video::SColor color = encode_light(cur_node.light, cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
if (!cur_node.f->light_source)
applyFacesShading(color, vertices[0].Normal);
for (int j = 0; j < 4; j++) {
@ -474,7 +480,8 @@ void MapblockMeshGenerator::drawSolidNode()
auto final_lights = lights[face];
for (int j = 0; j < 4; j++) {
video::S3DVertex &vertex = vertices[j];
vertex.Color = encode_light(final_lights[j], cur_node.f->light_source);
vertex.Color = encode_light(final_lights[j], cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
if (!cur_node.f->light_source)
applyFacesShading(vertex.Color, vertex.Normal);
}
@ -484,7 +491,8 @@ void MapblockMeshGenerator::drawSolidNode()
});
} else {
drawCuboid(box, tiles, 6, texture_coord_buf, mask, [&] (int face, video::S3DVertex vertices[4]) {
video::SColor color = encode_light(lights[face], cur_node.f->light_source);
video::SColor color = encode_light(lights[face], cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
if (!cur_node.f->light_source)
applyFacesShading(color, vertices[0].Normal);
for (int j = 0; j < 4; j++) {
@ -566,8 +574,10 @@ void MapblockMeshGenerator::prepareLiquidNodeDrawing()
cur_node.light = LightPair(getInteriorLight(ntop, 0, nodedef));
}
cur_liquid.color_top = encode_light(cur_node.light, cur_node.f->light_source);
cur_node.color = encode_light(cur_node.light, cur_node.f->light_source);
cur_liquid.color_top = encode_light(cur_node.light, cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
cur_node.color = encode_light(cur_node.light, cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
}
void MapblockMeshGenerator::getLiquidNeighborhood()
@ -859,7 +869,8 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
getTile(g_6dirs[face], &tiles[face]);
if (!data->m_smooth_lighting)
cur_node.color = encode_light(cur_node.light, cur_node.f->light_source);
cur_node.color = encode_light(cur_node.light, cur_node.f->light_source,
player->getLighting().ambient_light.luminance);
TileSpec glass_tiles[6];
for (auto &glass_tile : glass_tiles)

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h"
#include <IMeshManipulator.h>
#include "client/localplayer.h"
struct MeshMakeData;
struct MeshCollector;
@ -75,6 +76,7 @@ class MapblockMeshGenerator
const v3s16 blockpos_nodes;
LocalPlayer *player;
// options
const bool enable_mesh_cache;

@ -382,6 +382,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
CachedPixelShaderSetting<float>
m_animation_timer_delta_pixel{"animationTimerDelta"};
CachedPixelShaderSetting<float, 3> m_day_light{"dayLight"};
CachedPixelShaderSetting<float, 3> m_ambient_color{"ambientColor"};
CachedPixelShaderSetting<float, 3> m_minimap_yaw{"yawVec"};
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel{"cameraOffset"};
CachedVertexShaderSetting<float, 3> m_camera_offset_vertex{"cameraOffset"};
@ -473,6 +474,15 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
get_sunlight_color(&sunlight, daynight_ratio);
m_day_light.set(sunlight, services);
video::SColor ambient_color = m_client->getEnv().getLocalPlayer()->getLighting().ambient_light.color;
float ac_f[3] = {
ambient_color.getRed()/255.f,
ambient_color.getGreen()/255.f,
ambient_color.getBlue()/255.f
};
m_ambient_color.set(ac_f, services);
u32 animation_timer = m_client->getEnv().getFrameTime() % 1000000;
float animation_timer_f = (float)animation_timer / 100000.f;
m_animation_timer_vertex.set(&animation_timer_f, services);

@ -295,7 +295,7 @@ void final_color_blend(video::SColor *result,
video::SColorf dayLight;
get_sunlight_color(&dayLight, daynight_ratio);
final_color_blend(result,
encode_light(light, 0), dayLight);
encode_light(light, 0, 0), dayLight);
}
void final_color_blend(video::SColor *result,
@ -949,13 +949,24 @@ void MapBlockMesh::consolidateTransparentBuffers()
}
}
video::SColor encode_light(u16 light, u8 emissive_light)
video::SColor encode_light(u16 light, u8 emissive_light, u8 ambient_light)
{
// Get components
u32 day = (light & 0xff);
u32 night = (light >> 8);
// Add emissive light
night += emissive_light * 2.5f;
f32 ratio = ambient_light/16.f;
u32 ambient_light_32 = ratio * 255;
if (day < ambient_light_32)
day = ambient_light_32;
if (night < ambient_light_32)
night = ambient_light_32;
if (night > 255)
night = 255;
// Since we don't know if the day light is sunlight or

@ -295,8 +295,10 @@ class MapBlockMesh
* the last 8 bits are night light
* \param emissive_light amount of light the surface emits,
* from 0 to LIGHT_SUN.
* \param ambient_light amount of ambient light that the surface should have
* from 0 to LIGHT_SUN.
*/
video::SColor encode_light(u16 light, u8 emissive_light);
video::SColor encode_light(u16 light, u8 emissive_light, u8 ambient_light=0);
// Compute light at node
u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef);

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#pragma once
#include "irrlichttypes_bloated.h"
/**
@ -46,11 +47,25 @@ struct AutoExposure
AutoExposure();
};
/*
* Parameters for adjusting ambient light affecting on colors of map nodes and entities
*/
struct AmbientLight
{
AmbientLight() : luminance(0), color(255, 255, 255, 255) {}
/// @brief Minimal threshold of luminance of ambience. Can be from 0 - 14.
u8 luminance;
/// @brief Color of ambient light. Default is white color.
video::SColor color;
};
/** Describes ambient light settings for a player
*/
struct Lighting
{
AutoExposure exposure;
AmbientLight ambient_light;
float shadow_intensity {0.0f};
float saturation {1.0f};
float volumetric_light_strength {0.0f};

@ -1805,6 +1805,9 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt)
*pkt >> lighting.shadow_intensity;
if (pkt->getRemainingBytes() >= 4)
*pkt >> lighting.saturation;
if (pkt->getRemainingBytes() >= 1)
*pkt >> lighting.ambient_light.luminance
>> lighting.ambient_light.color;
if (pkt->getRemainingBytes() >= 24) {
*pkt >> lighting.exposure.luminance_min
>> lighting.exposure.luminance_max

@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server/player_sao.h"
#include "server/serverinventorymgr.h"
#include "server/unit_sao.h"
#include "light.h"
/*
ObjectRef
@ -2534,6 +2535,18 @@ int ObjectRef::l_set_lighting(lua_State *L)
}
lua_pop(L, 1); // shadows
lua_getfield(L, 2, "ambient_light");
if(lua_istable(L, -1)) {
getintfield(L, -1, "luminance", lighting.ambient_light.luminance);
lighting.ambient_light.luminance = rangelim(lighting.ambient_light.luminance, 0, LIGHT_SUN);
lua_getfield(L, -1, "color");
if (!lua_isnil(L, -1))
read_color(L, -1, &lighting.ambient_light.color);
lua_pop(L, 1);
}
lua_pop(L, 1); // ambient light
getfloatfield(L, -1, "saturation", lighting.saturation);
lua_getfield(L, 2, "exposure");

@ -1885,6 +1885,8 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
pkt << lighting.shadow_intensity;
pkt << lighting.saturation;
pkt << lighting.ambient_light.luminance
<< lighting.ambient_light.color;
pkt << lighting.exposure.luminance_min
<< lighting.exposure.luminance_max