mirror of
https://github.com/minetest/minetest.git
synced 2024-07-02 14:10:33 +02:00
Ambient light and server control for that
This commit is contained in:
parent
728f643ea7
commit
02d0c826fe
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user