aboutsummaryrefslogtreecommitdiff
path: root/src/client/shadows/dynamicshadowsrender.cpp
diff options
context:
space:
mode:
authorElias Fleckenstein <eliasfleckenstein@web.de>2022-05-17 22:12:00 +0200
committerElias Fleckenstein <eliasfleckenstein@web.de>2022-05-17 22:12:00 +0200
commit21df26984da91143c15587f5a03c98d68c3adc4e (patch)
treeaaa707a628ad331f67890023dffe1b4f60dd01d3 /src/client/shadows/dynamicshadowsrender.cpp
parentb09fc5de5cdb021f43ad32b7e3f50dc75c0bc622 (diff)
parenteabf05758e3ba5f6f4bb1b8d1d1f02179b84e410 (diff)
downloaddragonfireclient-21df26984da91143c15587f5a03c98d68c3adc4e.tar.xz
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/client/shadows/dynamicshadowsrender.cpp')
-rw-r--r--src/client/shadows/dynamicshadowsrender.cpp148
1 files changed, 98 insertions, 50 deletions
diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp
index a913a9290..07dc6daf2 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"
@@ -30,12 +31,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h"
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_smgr(device->getSceneManager()), m_driver(device->getVideoDriver()),
+ m_client(client), m_current_frame(0),
+ m_perspective_bias_xy(0.8), m_perspective_bias_z(0.5)
{
+ (void) m_client;
+
+ 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,8 +57,15 @@ 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_depth_entity_cb)
+ delete m_shadow_depth_entity_cb;
+ if (m_shadow_depth_trans_cb)
+ delete m_shadow_depth_trans_cb;
if (m_shadow_mix_cb)
delete m_shadow_mix_cb;
m_shadow_node_array.clear();
@@ -72,15 +87,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 +119,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;
}
@@ -118,16 +145,21 @@ size_t ShadowRenderer::getDirectionalLightCount() const
f32 ShadowRenderer::getMaxShadowFar() const
{
if (!m_light_list.empty()) {
- float wanted_range = m_client->getEnv().getClientMap().getWantedRange();
-
- float zMax = m_light_list[0].getMaxFarValue() > wanted_range
- ? wanted_range
- : m_light_list[0].getMaxFarValue();
- return zMax * MAP_BLOCKSIZE;
+ float zMax = m_light_list[0].getFarValue();
+ return zMax;
}
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)
{
@@ -157,6 +189,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) {
@@ -165,6 +198,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) {
@@ -172,6 +206,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) {
@@ -179,6 +214,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
@@ -198,6 +234,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()) {
@@ -219,9 +256,15 @@ void ShadowRenderer::updateSMTextures()
// Update SM incrementally:
for (DirectionalLight &light : m_light_list) {
// Static shader values.
- m_shadow_depth_cb->MapRes = (f32)m_shadow_map_texture_size;
- m_shadow_depth_cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
-
+ for (auto cb : {m_shadow_depth_cb, m_shadow_depth_entity_cb, m_shadow_depth_trans_cb})
+ if (cb) {
+ cb->MapRes = (f32)m_shadow_map_texture_size;
+ cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
+ cb->PerspectiveBiasXY = getPerspectiveBiasXY();
+ cb->PerspectiveBiasZ = getPerspectiveBiasZ();
+ cb->CameraPos = light.getFuturePlayerPos();
+ }
+
// set the Render Target
// right now we can only render in usual RTT, not
// Depth texture is available in irrlicth maybe we
@@ -274,12 +317,17 @@ 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) {
- // Static shader values.
- m_shadow_depth_cb->MapRes = (f32)m_shadow_map_texture_size;
- m_shadow_depth_cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
+ // Static shader values for entities are set in updateSMTextures
+ // SM texture for entities is not updated incrementally and
+ // must by updated using current player position.
+ m_shadow_depth_entity_cb->CameraPos = light.getPlayerPos();
// render shadows for the n0n-map objects.
m_driver->setRenderTarget(shadowMapTextureDynamicObjects, true,
@@ -311,19 +359,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,
@@ -368,10 +420,6 @@ void ShadowRenderer::renderShadowMap(video::ITexture *target,
material.BackfaceCulling = false;
material.FrontfaceCulling = true;
- material.PolygonOffsetFactor = 4.0f;
- material.PolygonOffsetDirection = video::EPO_BACK;
- //material.PolygonOffsetDepthBias = 1.0f/4.0f;
- //material.PolygonOffsetSlopeScale = -1.f;
if (m_shadow_map_colored && pass != scene::ESNRP_SOLID) {
material.MaterialType = (video::E_MATERIAL_TYPE) depth_shader_trans;
@@ -381,9 +429,6 @@ void ShadowRenderer::renderShadowMap(video::ITexture *target,
material.BlendOperation = video::EBO_MIN;
}
- // FIXME: I don't think this is needed here
- map_node->OnAnimate(m_device->getTimer()->getTime());
-
m_driver->setTransform(video::ETS_WORLD,
map_node->getAbsoluteTransformation());
@@ -429,10 +474,6 @@ void ShadowRenderer::renderShadowObjects(
current_mat.BackfaceCulling = true;
current_mat.FrontfaceCulling = false;
- current_mat.PolygonOffsetFactor = 1.0f/2048.0f;
- current_mat.PolygonOffsetDirection = video::EPO_BACK;
- //current_mat.PolygonOffsetDepthBias = 1.0 * 2.8e-6;
- //current_mat.PolygonOffsetSlopeScale = -1.f;
}
m_driver->setTransform(video::ETS_WORLD,
@@ -473,13 +514,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;
}
@@ -494,7 +535,9 @@ void ShadowRenderer::createShaders()
if (depth_shader == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_cb;
+ m_shadow_depth_cb = nullptr;
m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader." << std::endl;
return;
}
@@ -510,26 +553,30 @@ 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;
}
+ m_shadow_depth_entity_cb = new ShadowDepthShaderCB();
depth_shader_entities = gpu->addHighLevelShaderMaterial(
readShaderFile(depth_shader_vs).c_str(), "vertexMain",
video::EVST_VS_1_1,
readShaderFile(depth_shader_fs).c_str(), "pixelMain",
- video::EPST_PS_1_2, m_shadow_depth_cb);
+ video::EPST_PS_1_2, m_shadow_depth_entity_cb);
if (depth_shader_entities == -1) {
// upsi, something went wrong loading shader.
+ delete m_shadow_depth_entity_cb;
+ m_shadow_depth_entity_cb = nullptr;
m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl;
return;
}
@@ -543,14 +590,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;
}
@@ -569,7 +616,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;
}
@@ -583,13 +630,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;
}
@@ -604,8 +651,9 @@ void ShadowRenderer::createShaders()
if (depth_shader_trans == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_trans_cb;
+ m_shadow_depth_trans_cb = nullptr;
m_shadow_map_colored = false;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling colored shadow mapping shader." << std::endl;
return;
}