From 4801bdf45aaaa9238bc52a157e1d25c9d477d81a Mon Sep 17 00:00:00 2001 From: Dmitry Kostenko Date: Sun, 20 Feb 2022 00:04:48 +0100 Subject: [PATCH] Correct normal bias for entities Remove use of magic constants. Apply cameraOffset Calculate distance projected on SM plane --- client/shaders/object_shader/opengl_vertex.glsl | 10 +++++++--- src/client/shadows/dynamicshadows.cpp | 8 +++----- src/client/shadows/dynamicshadows.h | 3 ++- src/client/shadows/dynamicshadowsrender.cpp | 8 ++------ 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl index 12078f532..185551c58 100644 --- a/client/shaders/object_shader/opengl_vertex.glsl +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -3,6 +3,7 @@ uniform vec3 dayLight; uniform vec3 eyePosition; uniform float animationTimer; uniform vec4 emissiveColor; +uniform vec3 cameraOffset; varying vec3 vNormal; @@ -110,10 +111,13 @@ void main(void) // Calculate normal offset scale based on the texel size adjusted for // curvature of the SM texture. This code must be change together with // getPerspectiveFactor or any light-space transformation. - float distanceToPlayer = length((eyePosition - worldPosition).xyz) / f_shadowfar; + vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset; + // Distance from the vertex to the player + float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar; + // perspective factor estimation according to the float perspectiveFactor = distanceToPlayer * bias0 + bias1; - float texelSize = 1.0 / f_textureresolution; - texelSize *= f_shadowfar * perspectiveFactor / (bias1 / perspectiveFactor - texelSize * bias0) * 0.15; + float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor / + (f_textureresolution * bias1 - perspectiveFactor * bias0); float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0); normalOffsetScale = texelSize * slopeScale; diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp index 6ef5a4f1d..a45bf64fe 100644 --- a/src/client/shadows/dynamicshadows.cpp +++ b/src/client/shadows/dynamicshadows.cpp @@ -58,15 +58,13 @@ void DirectionalLight::createSplitMatrices(const Camera *cam) const v3f &viewUp = cam->getCameraNode()->getUpVector(); v3f viewRight = look.crossProduct(viewUp); - v3f farCorner = look + viewRight * tanFovX + viewUp * tanFovY; + v3f farCorner = (look + viewRight * tanFovX + viewUp * tanFovY).normalize(); // Compute the frustumBoundingSphere radius v3f boundVec = (camPos + farCorner * sfFar) - newCenter; - radius = boundVec.getLength() * 2.0f; + radius = boundVec.getLength(); // boundVec.getLength(); - float vvolume = radius * 2.0f; - + float vvolume = radius; v3f frustumCenter = newCenter; - // probar radius multipliacdor en funcion del I, a menor I mas multiplicador v3f eye_displacement = direction * vvolume; // we must compute the viewmat with the position - the camera offset diff --git a/src/client/shadows/dynamicshadows.h b/src/client/shadows/dynamicshadows.h index d8be66be8..03dd36014 100644 --- a/src/client/shadows/dynamicshadows.h +++ b/src/client/shadows/dynamicshadows.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include #include "util/basic_macros.h" +#include "constants.h" class Camera; class Client; @@ -67,7 +68,7 @@ public: /// Gets the light's far value. f32 getMaxFarValue() const { - return farPlane; + return farPlane * BS; } diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp index a913a9290..528415aaf 100644 --- a/src/client/shadows/dynamicshadowsrender.cpp +++ b/src/client/shadows/dynamicshadowsrender.cpp @@ -118,12 +118,8 @@ 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].getMaxFarValue(); + return zMax; } return 0.0f; }