summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/shaders/nodes_shader/opengl_fragment.glsl16
-rw-r--r--src/client/shader.cpp2
-rw-r--r--src/client/shadows/dynamicshadows.cpp31
-rw-r--r--src/util/numeric.cpp11
4 files changed, 37 insertions, 23 deletions
diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl
index 43a8b1f25..9f8a21d09 100644
--- a/client/shaders/nodes_shader/opengl_fragment.glsl
+++ b/client/shaders/nodes_shader/opengl_fragment.glsl
@@ -181,9 +181,14 @@ float getDeltaPerspectiveFactor(float l)
float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance, float multiplier)
{
+ float baseLength = getBaseLength(smTexCoord);
+ float perspectiveFactor;
+
// Return fast if sharp shadows are requested
- if (SOFTSHADOWRADIUS <= 1.0)
- return SOFTSHADOWRADIUS;
+ if (SOFTSHADOWRADIUS <= 1.0) {
+ perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
+ return max(2 * length(smTexCoord.xy) * 2048 / f_textureresolution / pow(perspectiveFactor, 3), SOFTSHADOWRADIUS);
+ }
vec2 clampedpos;
float texture_size = 1.0 / (2048 /*f_textureresolution*/ * 0.5);
@@ -192,8 +197,6 @@ float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDist
float pointDepth;
float maxRadius = SOFTSHADOWRADIUS * 5.0 * multiplier;
- float baseLength = getBaseLength(smTexCoord);
- float perspectiveFactor;
float bound = clamp(PCFBOUND * (1 - baseLength), 0.5, PCFBOUND);
int n = 0;
@@ -211,9 +214,10 @@ float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDist
}
depth = depth / n;
-
depth = pow(clamp(depth, 0.0, 1000.0), 1.6) / 0.001;
- return max(0.5, depth * maxRadius);
+
+ perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
+ return max(length(smTexCoord.xy) * 2 * 2048 / f_textureresolution / pow(perspectiveFactor, 3), depth * maxRadius);
}
#ifdef POISSON_FILTER
diff --git a/src/client/shader.cpp b/src/client/shader.cpp
index 355366bd3..0b35c37af 100644
--- a/src/client/shader.cpp
+++ b/src/client/shader.cpp
@@ -740,7 +740,7 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
s32 shadow_filter = g_settings->getS32("shadow_filters");
shaders_header << "#define SHADOW_FILTER " << shadow_filter << "\n";
- float shadow_soft_radius = g_settings->getS32("shadow_soft_radius");
+ float shadow_soft_radius = g_settings->getFloat("shadow_soft_radius");
if (shadow_soft_radius < 1.0f)
shadow_soft_radius = 1.0f;
shaders_header << "#define SOFTSHADOWRADIUS " << shadow_soft_radius << "\n";
diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp
index 775cdebce..17b711a61 100644
--- a/src/client/shadows/dynamicshadows.cpp
+++ b/src/client/shadows/dynamicshadows.cpp
@@ -33,29 +33,34 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
v3f newCenter;
v3f look = cam->getDirection();
+ // camera view tangents
+ float tanFovY = tanf(cam->getFovY() * 0.5f);
+ float tanFovX = tanf(cam->getFovX() * 0.5f);
+
+ // adjusted frustum boundaries
+ float sfNear = shadow_frustum.zNear;
+ float sfFar = adjustDist(shadow_frustum.zFar, cam->getFovY());
+
+ // adjusted camera positions
v3f camPos2 = cam->getPosition();
v3f camPos = v3f(camPos2.X - cam->getOffset().X * BS,
camPos2.Y - cam->getOffset().Y * BS,
camPos2.Z - cam->getOffset().Z * BS);
- camPos += look * shadow_frustum.zNear;
- camPos2 += look * shadow_frustum.zNear;
- float end = shadow_frustum.zNear + shadow_frustum.zFar;
- newCenter = camPos + look * (shadow_frustum.zNear + 0.05f * end);
- v3f world_center = camPos2 + look * (shadow_frustum.zNear + 0.05f * end);
- // Create a vector to the frustum far corner
- // @Liso: move all vars we can outside the loop.
- float tanFovY = tanf(cam->getFovY() * 0.5f);
- float tanFovX = tanf(cam->getFovX() * 0.5f);
+ camPos += look * sfNear;
+ camPos2 += look * sfNear;
- const v3f &viewUp = cam->getCameraNode()->getUpVector();
- // viewUp.normalize();
+ // center point of light frustum
+ float end = sfNear + sfFar;
+ newCenter = camPos + look * (sfNear + 0.05f * end);
+ v3f world_center = camPos2 + look * (sfNear + 0.05f * end);
+ // Create a vector to the frustum far corner
+ const v3f &viewUp = cam->getCameraNode()->getUpVector();
v3f viewRight = look.crossProduct(viewUp);
- // viewRight.normalize();
v3f farCorner = look + viewRight * tanFovX + viewUp * tanFovY;
// Compute the frustumBoundingSphere radius
- v3f boundVec = (camPos + farCorner * shadow_frustum.zFar) - newCenter;
+ v3f boundVec = (camPos + farCorner * sfFar) - newCenter;
radius = boundVec.getLength() * 2.0f;
// boundVec.getLength();
float vvolume = radius * 2.0f;
diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp
index 99e4cfb5c..702ddce95 100644
--- a/src/util/numeric.cpp
+++ b/src/util/numeric.cpp
@@ -159,7 +159,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
return true;
}
-s16 adjustDist(s16 dist, float zoom_fov)
+inline float adjustDist(float dist, float zoom_fov)
{
// 1.775 ~= 72 * PI / 180 * 1.4, the default FOV on the client.
// The heuristic threshold for zooming is half of that.
@@ -167,8 +167,13 @@ s16 adjustDist(s16 dist, float zoom_fov)
if (zoom_fov < 0.001f || zoom_fov > threshold_fov)
return dist;
- return std::round(dist * std::cbrt((1.0f - std::cos(threshold_fov)) /
- (1.0f - std::cos(zoom_fov / 2.0f))));
+ return dist * std::cbrt((1.0f - std::cos(threshold_fov)) /
+ (1.0f - std::cos(zoom_fov / 2.0f)));
+}
+
+s16 adjustDist(s16 dist, float zoom_fov)
+{
+ return std::round(adjustDist((float)dist, zoom_fov));
}
void setPitchYawRollRad(core::matrix4 &m, const v3f &rot)