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:
parent
8d55702d13
commit
0f25fa7af6
24 changed files with 375 additions and 169 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue