1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Add API to control shadow intensity from the game/mod (#11944)

* Also Disable shadows when sun/moon is hidden. Fixes #11972.
This commit is contained in:
x2048 2022-03-26 16:58:26 +01:00 committed by GitHub
parent 8d55702d13
commit 0f25fa7af6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 375 additions and 169 deletions

View file

@ -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;
}