diff options
author | x2048 <codeforsmile@gmail.com> | 2022-03-26 16:58:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-26 16:58:26 +0100 |
commit | 0f25fa7af655b98fa401176a523f269c843d1943 (patch) | |
tree | 1fa8762f53941d6c1250c0c3a7dc6b8557995a40 /src/client | |
parent | 8d55702d139db739f8bf43eaa600f41446b29a16 (diff) | |
download | minetest-0f25fa7af655b98fa401176a523f269c843d1943.tar.gz minetest-0f25fa7af655b98fa401176a523f269c843d1943.tar.bz2 minetest-0f25fa7af655b98fa401176a523f269c843d1943.zip |
Add API to control shadow intensity from the game/mod (#11944)
* Also Disable shadows when sun/moon is hidden. Fixes #11972.
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/client.h | 1 | ||||
-rw-r--r-- | src/client/game.cpp | 7 | ||||
-rw-r--r-- | src/client/localplayer.h | 4 | ||||
-rw-r--r-- | src/client/shadows/dynamicshadowsrender.cpp | 95 | ||||
-rw-r--r-- | src/client/shadows/dynamicshadowsrender.h | 10 | ||||
-rw-r--r-- | src/client/sky.h | 2 |
6 files changed, 90 insertions, 29 deletions
diff --git a/src/client/client.h b/src/client/client.h index 84c85471d..0e29fdbe2 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -227,6 +227,7 @@ public: void handleCommand_PlayerSpeed(NetworkPacket *pkt); void handleCommand_MediaPush(NetworkPacket *pkt); void handleCommand_MinimapModes(NetworkPacket *pkt); + void handleCommand_SetLighting(NetworkPacket *pkt); void ProcessData(NetworkPacket *pkt); diff --git a/src/client/game.cpp b/src/client/game.cpp index 7450fb91c..edc69dcc2 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -4037,7 +4037,12 @@ void Game::updateShadows() float in_timeofday = fmod(runData.time_of_day_smooth, 1.0f); - float timeoftheday = fmod(getWickedTimeOfDay(in_timeofday) + 0.75f, 0.5f) + 0.25f; + float timeoftheday = getWickedTimeOfDay(in_timeofday); + bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75; + bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible(); + shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f); + + timeoftheday = fmod(timeoftheday + 0.75f, 0.5f) + 0.25f; const float offset_constant = 10000.0f; v3f light(0.0f, 0.0f, -1.0f); diff --git a/src/client/localplayer.h b/src/client/localplayer.h index 577be2803..3d0072fc1 100644 --- a/src/client/localplayer.h +++ b/src/client/localplayer.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "environment.h" #include "constants.h" #include "settings.h" +#include "lighting.h" #include <list> class Client; @@ -158,6 +159,8 @@ public: added_velocity += vel; } + inline Lighting& getLighting() { return m_lighting; } + private: void accelerate(const v3f &target_speed, const f32 max_increase_H, const f32 max_increase_V, const bool use_pitch); @@ -209,4 +212,5 @@ private: GenericCAO *m_cao = nullptr; Client *m_client; + Lighting m_lighting; }; diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp index 528415aaf..24adb21e2 100644 --- a/src/client/shadows/dynamicshadowsrender.cpp +++ b/src/client/shadows/dynamicshadowsrender.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include <cstring> +#include <cmath> #include "client/shadows/dynamicshadowsrender.h" #include "client/shadows/shadowsScreenQuad.h" #include "client/shadows/shadowsshadercallbacks.h" @@ -33,9 +34,13 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) : m_device(device), m_smgr(device->getSceneManager()), m_driver(device->getVideoDriver()), m_client(client), m_current_frame(0) { + m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize m_shadows_enabled = true; - m_shadow_strength = g_settings->getFloat("shadow_strength"); + m_shadow_strength_gamma = g_settings->getFloat("shadow_strength_gamma"); + if (std::isnan(m_shadow_strength_gamma)) + m_shadow_strength_gamma = 1.0f; + m_shadow_strength_gamma = core::clamp(m_shadow_strength_gamma, 0.1f, 10.0f); m_shadow_map_max_distance = g_settings->getFloat("shadow_map_max_distance"); @@ -49,6 +54,9 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) : ShadowRenderer::~ShadowRenderer() { + // call to disable releases dynamically allocated resources + disable(); + if (m_shadow_depth_cb) delete m_shadow_depth_cb; if (m_shadow_mix_cb) @@ -72,15 +80,25 @@ ShadowRenderer::~ShadowRenderer() m_driver->removeTexture(shadowMapClientMapFuture); } +void ShadowRenderer::disable() +{ + m_shadows_enabled = false; + if (shadowMapTextureFinal) { + m_driver->setRenderTarget(shadowMapTextureFinal, true, true, + video::SColor(255, 255, 255, 255)); + m_driver->setRenderTarget(0, true, true); + } +} + void ShadowRenderer::initialize() { auto *gpu = m_driver->getGPUProgrammingServices(); // we need glsl - if (m_shadows_enabled && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) { + if (m_shadows_supported && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) { createShaders(); } else { - m_shadows_enabled = false; + m_shadows_supported = false; warningstream << "Shadows: GLSL Shader not supported on this system." << std::endl; @@ -94,6 +112,8 @@ void ShadowRenderer::initialize() m_texture_format_color = m_shadow_map_texture_32bit ? video::ECOLOR_FORMAT::ECF_G32R32F : video::ECOLOR_FORMAT::ECF_G16R16F; + + m_shadows_enabled &= m_shadows_supported; } @@ -124,6 +144,16 @@ f32 ShadowRenderer::getMaxShadowFar() const return 0.0f; } +void ShadowRenderer::setShadowIntensity(float shadow_intensity) +{ + m_shadow_strength = pow(shadow_intensity, 1.0f / m_shadow_strength_gamma); + if (m_shadow_strength > 1E-2) + enable(); + else + disable(); +} + + void ShadowRenderer::addNodeToShadowList( scene::ISceneNode *node, E_SHADOW_MODE shadowMode) { @@ -153,6 +183,7 @@ void ShadowRenderer::updateSMTextures() shadowMapTextureDynamicObjects = getSMTexture( std::string("shadow_dynamic_") + itos(m_shadow_map_texture_size), m_texture_format, true); + assert(shadowMapTextureDynamicObjects != nullptr); } if (!shadowMapClientMap) { @@ -161,6 +192,7 @@ void ShadowRenderer::updateSMTextures() std::string("shadow_clientmap_") + itos(m_shadow_map_texture_size), m_shadow_map_colored ? m_texture_format_color : m_texture_format, true); + assert(shadowMapClientMap != nullptr); } if (!shadowMapClientMapFuture && m_map_shadow_update_frames > 1) { @@ -168,6 +200,7 @@ void ShadowRenderer::updateSMTextures() std::string("shadow_clientmap_bb_") + itos(m_shadow_map_texture_size), m_shadow_map_colored ? m_texture_format_color : m_texture_format, true); + assert(shadowMapClientMapFuture != nullptr); } if (m_shadow_map_colored && !shadowMapTextureColors) { @@ -175,6 +208,7 @@ void ShadowRenderer::updateSMTextures() std::string("shadow_colored_") + itos(m_shadow_map_texture_size), m_shadow_map_colored ? m_texture_format_color : m_texture_format, true); + assert(shadowMapTextureColors != nullptr); } // The merge all shadowmaps texture @@ -194,6 +228,7 @@ void ShadowRenderer::updateSMTextures() shadowMapTextureFinal = getSMTexture( std::string("shadowmap_final_") + itos(m_shadow_map_texture_size), frt, true); + assert(shadowMapTextureFinal != nullptr); } if (!m_shadow_node_array.empty() && !m_light_list.empty()) { @@ -270,6 +305,10 @@ void ShadowRenderer::update(video::ITexture *outputTarget) updateSMTextures(); + if (shadowMapTextureFinal == nullptr) { + return; + } + if (!m_shadow_node_array.empty() && !m_light_list.empty()) { for (DirectionalLight &light : m_light_list) { @@ -307,19 +346,23 @@ void ShadowRenderer::drawDebug() /* this code just shows shadows textures in screen and in ONLY for debugging*/ #if 0 // this is debug, ignore for now. - m_driver->draw2DImage(shadowMapTextureFinal, - core::rect<s32>(0, 50, 128, 128 + 50), - core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize())); + if (shadowMapTextureFinal) + m_driver->draw2DImage(shadowMapTextureFinal, + core::rect<s32>(0, 50, 128, 128 + 50), + core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize())); - m_driver->draw2DImage(shadowMapClientMap, - core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128), - core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize())); - m_driver->draw2DImage(shadowMapTextureDynamicObjects, - core::rect<s32>(0, 128 + 50 + 128, 128, - 128 + 50 + 128 + 128), - core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize())); + if (shadowMapClientMap) + m_driver->draw2DImage(shadowMapClientMap, + core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128), + core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize())); + + if (shadowMapTextureDynamicObjects) + m_driver->draw2DImage(shadowMapTextureDynamicObjects, + core::rect<s32>(0, 128 + 50 + 128, 128, + 128 + 50 + 128 + 128), + core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize())); - if (m_shadow_map_colored) { + if (m_shadow_map_colored && shadowMapTextureColors) { m_driver->draw2DImage(shadowMapTextureColors, core::rect<s32>(128,128 + 50 + 128 + 128, @@ -469,13 +512,13 @@ void ShadowRenderer::createShaders() if (depth_shader == -1) { std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl"); if (depth_shader_vs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error shadow mapping vs shader not found." << std::endl; return; } std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl"); if (depth_shader_fs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error shadow mapping fs shader not found." << std::endl; return; } @@ -490,7 +533,7 @@ void ShadowRenderer::createShaders() if (depth_shader == -1) { // upsi, something went wrong loading shader. delete m_shadow_depth_cb; - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error compiling shadow mapping shader." << std::endl; return; } @@ -506,13 +549,13 @@ void ShadowRenderer::createShaders() if (depth_shader_entities == -1) { std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl"); if (depth_shader_vs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error shadow mapping vs shader not found." << std::endl; return; } std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl"); if (depth_shader_fs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error shadow mapping fs shader not found." << std::endl; return; } @@ -525,7 +568,7 @@ void ShadowRenderer::createShaders() if (depth_shader_entities == -1) { // upsi, something went wrong loading shader. - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl; return; } @@ -539,14 +582,14 @@ void ShadowRenderer::createShaders() if (mixcsm_shader == -1) { std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass2_vertex.glsl"); if (depth_shader_vs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error cascade shadow mapping fs shader not found." << std::endl; return; } std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass2_fragment.glsl"); if (depth_shader_fs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error cascade shadow mapping fs shader not found." << std::endl; return; } @@ -565,7 +608,7 @@ void ShadowRenderer::createShaders() // upsi, something went wrong loading shader. delete m_shadow_mix_cb; delete m_screen_quad; - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error compiling cascade shadow mapping shader." << std::endl; return; } @@ -579,13 +622,13 @@ void ShadowRenderer::createShaders() if (m_shadow_map_colored && depth_shader_trans == -1) { std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_trans_vertex.glsl"); if (depth_shader_vs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error shadow mapping vs shader not found." << std::endl; return; } std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_trans_fragment.glsl"); if (depth_shader_fs.empty()) { - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error shadow mapping fs shader not found." << std::endl; return; } @@ -601,7 +644,7 @@ void ShadowRenderer::createShaders() // upsi, something went wrong loading shader. delete m_shadow_depth_trans_cb; m_shadow_map_colored = false; - m_shadows_enabled = false; + m_shadows_supported = false; errorstream << "Error compiling colored shadow mapping shader." << std::endl; return; } diff --git a/src/client/shadows/dynamicshadowsrender.h b/src/client/shadows/dynamicshadowsrender.h index e4b3c3e22..dc8f79c56 100644 --- a/src/client/shadows/dynamicshadowsrender.h +++ b/src/client/shadows/dynamicshadowsrender.h @@ -82,11 +82,12 @@ public: } - bool is_active() const { return m_shadows_enabled; } + bool is_active() const { return m_shadows_enabled && shadowMapTextureFinal != nullptr; } void setTimeOfDay(float isDay) { m_time_day = isDay; }; + void setShadowIntensity(float shadow_intensity); s32 getShadowSamples() const { return m_shadow_samples; } - float getShadowStrength() const { return m_shadow_strength; } + float getShadowStrength() const { return m_shadows_enabled ? m_shadow_strength : 0.0f; } float getTimeOfDay() const { return m_time_day; } private: @@ -101,6 +102,9 @@ private: void mixShadowsQuad(); void updateSMTextures(); + void disable(); + void enable() { m_shadows_enabled = m_shadows_supported; } + // a bunch of variables IrrlichtDevice *m_device{nullptr}; scene::ISceneManager *m_smgr{nullptr}; @@ -116,12 +120,14 @@ private: std::vector<NodeToApply> m_shadow_node_array; float m_shadow_strength; + float m_shadow_strength_gamma; float m_shadow_map_max_distance; float m_shadow_map_texture_size; float m_time_day{0.0f}; int m_shadow_samples; bool m_shadow_map_texture_32bit; bool m_shadows_enabled; + bool m_shadows_supported; bool m_shadow_map_colored; u8 m_map_shadow_update_frames; /* Use this number of frames to update map shaodw */ u8 m_current_frame{0}; /* Current frame */ diff --git a/src/client/sky.h b/src/client/sky.h index 3dc057b70..e03683f12 100644 --- a/src/client/sky.h +++ b/src/client/sky.h @@ -65,6 +65,7 @@ public: } void setSunVisible(bool sun_visible) { m_sun_params.visible = sun_visible; } + bool getSunVisible() const { return m_sun_params.visible; } void setSunTexture(const std::string &sun_texture, const std::string &sun_tonemap, ITextureSource *tsrc); void setSunScale(f32 sun_scale) { m_sun_params.scale = sun_scale; } @@ -72,6 +73,7 @@ public: void setSunriseTexture(const std::string &sunglow_texture, ITextureSource* tsrc); void setMoonVisible(bool moon_visible) { m_moon_params.visible = moon_visible; } + bool getMoonVisible() const { return m_moon_params.visible; } void setMoonTexture(const std::string &moon_texture, const std::string &moon_tonemap, ITextureSource *tsrc); void setMoonScale(f32 moon_scale) { m_moon_params.scale = moon_scale; } |