diff --git a/doc/lua_api.md b/doc/lua_api.md index 4340deb4d..8c3bbf850 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8397,6 +8397,7 @@ child will follow movement and rotation of that bone. * `light_definition` is a table with the following optional fields: * `ambient_light` is a ColorSpec controlling lightness & color of ambient light; alpha must be 255 (global lighting; default: `{a = 255, r = 0, g = 0, b = 0}` / last set value). + * It works only if 'enable_shaders' setting is set to true. * `saturation` sets the saturation (vividness; default: `1.0`). * values > 1 increase the saturation * values in [0,1] decrease the saturation diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index fd1b8c39b..fc0e20daa 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -251,10 +251,10 @@ void ClientEnvironment::step(float dtime) // Update the ambient light auto new_ambient_light_clr = getLocalPlayer()->getLighting().ambient_light; - if (new_ambient_light_clr != m_ambient_light) { - getClientMap().forceUpdateLightColor(); + bool enable_shaders = g_settings->getBool("enable_shaders"); + + if (enable_shaders && (new_ambient_light_clr != m_ambient_light)) m_ambient_light = new_ambient_light_clr; - } // Update lighting on local player (used for wield item) u32 day_night_ratio = getDayNightRatio(); @@ -270,7 +270,12 @@ void ClientEnvironment::step(float dtime) u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef()); lplayer->light_color = encode_light(light, 0); // this transfers light.alpha - final_color_blend(&lplayer->light_color, light, day_night_ratio, m_ambient_light); + + video::SColor ambient_light(255, 0, 0, 0); + + if (enable_shaders) + ambient_light = m_ambient_light; + final_color_blend(&lplayer->light_color, light, day_night_ratio, ambient_light); } /* diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index 134b35fac..45995c0ea 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -719,7 +719,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) const float animation_time = m_client->getAnimationTime(); const int crack = m_client->getCrackLevel(); const u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); - const auto ambient_light = m_client->getEnv().getAmbientLight(); const v3f camera_position = m_camera_position; @@ -778,11 +777,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) // Pretty random but this should work somewhat nicely bool faraway = d >= BS * 50; if (block_mesh->isAnimationForced() || !faraway || - mesh_animate_count < (m_control.range_all ? 200 : 50) || - m_force_update_light_color) { + mesh_animate_count < (m_control.range_all ? 200 : 50)) { bool animated = block_mesh->animate(faraway, animation_time, - crack, daynight_ratio, ambient_light); + crack, daynight_ratio); if (animated) mesh_animate_count++; } else { @@ -826,8 +824,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) } } - m_force_update_light_color = false; - // Capture draw order for all solid meshes for (auto &map : grouped_buffers.maps) { for (auto &list : map) { diff --git a/src/client/clientmap.h b/src/client/clientmap.h index bab8418e2..05c33d67c 100644 --- a/src/client/clientmap.h +++ b/src/client/clientmap.h @@ -114,8 +114,6 @@ class ClientMap : public Map, public scene::ISceneNode void onSettingChanged(const std::string &name); - void forceUpdateLightColor() { m_force_update_light_color = true; } - protected: // use drop() instead virtual ~ClientMap(); @@ -197,6 +195,4 @@ class ClientMap : public Map, public scene::ISceneNode bool m_loops_occlusion_culler; bool m_enable_raytraced_culling; - - bool m_force_update_light_color = false; }; diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index d9ff6eede..0044cc16e 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -909,8 +909,7 @@ void GenericCAO::updateLight(u32 day_night_ratio) if (m_enable_shaders) light = encode_light(light_at_pos, m_prop.glow); else - final_color_blend(&light, light_at_pos, day_night_ratio, - m_client->getEnv().getAmbientLight()); + final_color_blend(&light, light_at_pos, day_night_ratio); if (light != m_last_light) { m_last_light = light; diff --git a/src/client/game.cpp b/src/client/game.cpp index b4c385104..773521717 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -382,7 +382,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_animation_timer_delta_pixel{"animationTimerDelta"}; CachedPixelShaderSetting m_day_light{"dayLight"}; - CachedPixelShaderSetting m_ambient_light{"ambientLight"}; + CachedPixelShaderSetting m_ambient_light{"ambientLight"}; CachedPixelShaderSetting m_minimap_yaw{"yawVec"}; CachedPixelShaderSetting m_camera_offset_pixel{"cameraOffset"}; CachedVertexShaderSetting m_camera_offset_vertex{"cameraOffset"}; @@ -474,14 +474,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter get_sunlight_color(&sunlight, daynight_ratio); m_day_light.set(sunlight, services); - auto ambient_light = m_client->getEnv().getAmbientLight(); - - float ambient_light_f[3] = { - ambient_light.getRed() / 255.f, - ambient_light.getGreen() / 255.f, - ambient_light.getBlue() / 255.f - }; - + video::SColorf ambient_light_f(m_client->getEnv().getAmbientLight()); m_ambient_light.set(ambient_light_f, services); u32 animation_timer = m_client->getEnv().getFrameTime() % 1000000; @@ -515,6 +508,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter m_texel_size0_vertex.set(m_texel_size0, services); m_texel_size0_pixel.set(m_texel_size0, services); + auto lighting = m_client->getEnv().getLocalPlayer()->getLighting(); + const AutoExposure &exposure_params = lighting.exposure; std::array exposure_buffer = { std::pow(2.0f, exposure_params.luminance_min), @@ -3536,7 +3531,7 @@ PointedThing Game::updatePointedThing( u32 daynight_ratio = client->getEnv().getDayNightRatio(); video::SColor c; - final_color_blend(&c, light_level, daynight_ratio, client->getEnv().getAmbientLight()); + final_color_blend(&c, light_level, daynight_ratio); // Modify final color a bit with time u32 timer = client->getEnv().getFrameTime() % 5000; diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index c90c597de..2fb303ace 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -725,15 +725,13 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs video::SColorf sunlight; get_sunlight_color(&sunlight, 0); - auto ambientlight = client->getEnv().getAmbientLight(); - std::map colors; const u32 vertex_count = p.vertices.size(); for (u32 j = 0; j < vertex_count; j++) { video::SColor *vc = &p.vertices[j].Color; video::SColor copy = *vc; if (vc->getAlpha() == 0) // No sunlight - no need to animate - final_color_blend(vc, copy, sunlight, ambientlight); // Finalize color + final_color_blend(vc, copy, sunlight); // Finalize color else // Record color to animate colors[j] = copy; @@ -745,17 +743,6 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs m_daynight_diffs[{layer, i}] = std::move(colors); } - // Apply the ambient light to all vertices - /*auto ambient_light = data->m_client->getEnv().getAmbientLight(); - - for (u32 i = 0; i < p.vertices.size(); i++) { - video::SColor &vert_c = p.vertices[i].Color; - - vert_c.setRed(vert_c.getRed() + ambient_light.getRed()); - vert_c.setGreen(vert_c.getGreen() + ambient_light.getGreen()); - vert_c.setBlue(vert_c.getBlue() + ambient_light.getBlue()); - }*/ - // Create material video::SMaterial material; material.Lighting = false; @@ -826,8 +813,7 @@ MapBlockMesh::~MapBlockMesh() delete block; } -bool MapBlockMesh::animate(bool faraway, float time, int crack, - u32 daynight_ratio, video::SColor ambient_light) +bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio) { if (!m_has_animation) { m_animation_force_timer = 100000; @@ -886,11 +872,11 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, } } - video::SColorf day_color; - get_sunlight_color(&day_color, daynight_ratio); - // Day-night transition if (!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio)) { + video::SColorf day_color; + get_sunlight_color(&day_color, daynight_ratio); + for (auto &daynight_diff : m_daynight_diffs) { auto *mesh = m_mesh[daynight_diff.first.first]; mesh->setDirty(scene::EBT_VERTEX); // force reload to VBO @@ -898,25 +884,11 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, getMeshBuffer(daynight_diff.first.second); video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); for (const auto &j : daynight_diff.second) - final_color_blend(&(vertices[j.first].Color), j.second, - day_color, video::SColor(255, 0, 0, 0)); + final_color_blend(&(vertices[j.first].Color), j.second, day_color); } m_last_daynight_ratio = daynight_ratio; } - // Ambient light - if (!m_enable_shaders) { - for (u32 i = 0; i < MAX_TILE_LAYERS; i++) - for (u32 j = 0; j < m_mesh[i]->getMeshBufferCount(); j++) { - scene::IMeshBuffer *buf = m_mesh[i]->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices(); - - for (u32 k = 0; k < buf->getVertexCount(); k++) - final_color_blend(&(vertices[k].Color), vertices[k].Color, - day_color, ambient_light); - } - } - return true; } diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index 52f29e75a..fa90bd551 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -190,7 +190,7 @@ class MapBlockMesh // daynight_ratio: 0 .. 1000 // crack: -1 .. CRACK_ANIMATION_LENGTH-1 (-1 for off) // Returns true if anything has been changed. - bool animate(bool faraway, float time, int crack, u32 daynight_ratio, video::SColor ambient_light); + bool animate(bool faraway, float time, int crack, u32 daynight_ratio); scene::IMesh *getMesh() { @@ -318,7 +318,7 @@ void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); * night light */ void final_color_blend(video::SColor *result, - u16 light, u32 daynight_ratio, video::SColor ambientLight); + u16 light, u32 daynight_ratio, video::SColor ambientLight=video::SColor(255,0,0,0)); /*! * Gives the final SColor shown on screen. @@ -329,7 +329,7 @@ void final_color_blend(video::SColor *result, */ void final_color_blend(video::SColor *result, const video::SColor &data, const video::SColorf &dayLight, - const video::SColor &ambientLight); + const video::SColor &ambientLight=video::SColor(255,0,0,0)); // Retrieves the TileSpec of a face of a node // Adds MATERIAL_FLAG_CRACK if the node is cracked diff --git a/src/lighting.h b/src/lighting.h index 64d5394b3..621adabf9 100644 --- a/src/lighting.h +++ b/src/lighting.h @@ -51,7 +51,7 @@ struct Lighting { AutoExposure exposure; /// @brief Ambient light color & intensity for nodes & entities. Alpha is ignored. - video::SColor ambient_light = {255, 0, 0, 0}; + video::SColor ambient_light {255, 0, 0, 0}; float shadow_intensity {0.0f}; float saturation {1.0f}; float volumetric_light_strength {0.0f};