diff --git a/install/gl/interaction_fp.glsl b/install/gl/interaction_fp.glsl index efffd7cb4b..4b46b146db 100644 --- a/install/gl/interaction_fp.glsl +++ b/install/gl/interaction_fp.glsl @@ -7,12 +7,13 @@ uniform sampler2D u_attenuationmap_xy; uniform sampler2D u_attenuationmap_z; uniform sampler2D u_ShadowMap; -uniform vec3 u_view_origin; -uniform vec3 u_light_origin; -uniform vec3 u_light_color; -uniform float u_light_scale; -uniform vec4 u_ColourModulation; -uniform vec4 u_ColourAddition; +uniform vec3 u_view_origin; +uniform vec3 u_light_origin; +uniform vec3 u_light_color; +uniform float u_light_scale; +uniform vec4 u_ColourModulation; +uniform vec4 u_ColourAddition; +uniform mat4 u_ObjectTransform; // object to world // Defines the region within the shadow map atlas containing the depth information of the current light uniform vec4 u_ShadowMapRect; // x,y,w,h @@ -153,9 +154,13 @@ void main() float maxAbsL = max(absL.x, max(absL.y, absL.z)); float centerFragZ = maxAbsL; + vec3 normal = mat3(u_ObjectTransform) * N; + + float lightFallAngle = -dot(normal, L); + float errorMargin = 5.0 * maxAbsL / ( shadowMapResolution * max(lightFallAngle, 0.1) ); + float centerBlockerZ = getDepthValueForVector(u_ShadowMap, u_ShadowMapRect, L); - float lit = float(centerBlockerZ >= centerFragZ/* - errorMargin*/); - //lit = var_WorldLightDirection.y > 0.2 ? 1 : 0; + float lit = float(centerBlockerZ >= centerFragZ - errorMargin); totalColor *= lit; } diff --git a/radiantcore/rendersystem/backend/LightInteractions.cpp b/radiantcore/rendersystem/backend/LightInteractions.cpp index 9402bdce8e..3be9a768b5 100644 --- a/radiantcore/rendersystem/backend/LightInteractions.cpp +++ b/radiantcore/rendersystem/backend/LightInteractions.cpp @@ -33,6 +33,8 @@ bool LightInteractions::castsShadows() void LightInteractions::collectSurfaces(const IRenderView& view, const std::set& entities) { + bool shadowCasting = castsShadows(); + // Now check all the entities intersecting with this light for (const auto& entity : entities) { @@ -45,17 +47,21 @@ void LightInteractions::collectSurfaces(const IRenderView& view, const std::set< // Don't collect invisible shaders if (!shader->isVisible()) return; - if (object->isOriented()) + // For non-shadow lights we can cull surfaces that are not in view + if (!shadowCasting) { - if (view.TestAABB(object->getObjectBounds(), object->getObjectTransform()) == VOLUME_OUTSIDE) + if (object->isOriented()) + { + if (view.TestAABB(object->getObjectBounds(), object->getObjectTransform()) == VOLUME_OUTSIDE) + { + return; + } + } + else if (view.TestAABB(object->getObjectBounds()) == VOLUME_OUTSIDE) // non-oriented AABB test { return; } } - else if (view.TestAABB(object->getObjectBounds()) == VOLUME_OUTSIDE) // non-oriented AABB test - { - return; - } auto glShader = static_cast(shader); @@ -76,7 +82,7 @@ void LightInteractions::collectSurfaces(const IRenderView& view, const std::set< } void LightInteractions::fillDepthBuffer(OpenGLState& state, GLSLDepthFillAlphaProgram& program, - const IRenderView& view, std::size_t renderTime, std::vector& untransformedObjectsWithoutAlphaTest) + std::size_t renderTime, std::vector& untransformedObjectsWithoutAlphaTest) { std::vector untransformedObjects; untransformedObjects.reserve(1000); diff --git a/radiantcore/rendersystem/backend/LightInteractions.h b/radiantcore/rendersystem/backend/LightInteractions.h index ba936f2213..17274244e5 100644 --- a/radiantcore/rendersystem/backend/LightInteractions.h +++ b/radiantcore/rendersystem/backend/LightInteractions.h @@ -91,7 +91,7 @@ class LightInteractions void collectSurfaces(const IRenderView& view, const std::set& entities); void fillDepthBuffer(OpenGLState& state, GLSLDepthFillAlphaProgram& program, - const IRenderView& view, std::size_t renderTime, std::vector& untransformedObjectsWithoutAlphaTest); + std::size_t renderTime, std::vector& untransformedObjectsWithoutAlphaTest); void drawShadowMap(OpenGLState& state, const Rectangle& rectangle, ShadowMapProgram& program); diff --git a/radiantcore/rendersystem/backend/LightingModeRenderer.cpp b/radiantcore/rendersystem/backend/LightingModeRenderer.cpp index b2f13c35ad..34484520aa 100644 --- a/radiantcore/rendersystem/backend/LightingModeRenderer.cpp +++ b/radiantcore/rendersystem/backend/LightingModeRenderer.cpp @@ -105,6 +105,9 @@ IRenderResult::Ptr LightingModeRenderer::render(RenderStateFlags globalFlagsMask glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); current.setRenderFlag(RENDER_FILL); + glPolygonOffset(0, 0); + glEnable(GL_POLYGON_OFFSET_FILL); + // Enable the 4 clip planes, they are used in the vertex shader glEnable(GL_CLIP_DISTANCE0); glEnable(GL_CLIP_DISTANCE1); @@ -129,6 +132,8 @@ IRenderResult::Ptr LightingModeRenderer::render(RenderStateFlags globalFlagsMask glDisable(GL_CLIP_DISTANCE1); glDisable(GL_CLIP_DISTANCE0); + glDisable(GL_POLYGON_OFFSET_FILL); + // Restore view port glViewport(previousViewport[0], previousViewport[1], previousViewport[2], previousViewport[3]); @@ -202,7 +207,7 @@ std::size_t LightingModeRenderer::drawDepthFillPass(OpenGLState& current, Render for (auto& interactionList : interactionLists) { - interactionList.fillDepthBuffer(current, *depthFillProgram, view, renderTime, _untransformedObjectsWithoutAlphaTest); + interactionList.fillDepthBuffer(current, *depthFillProgram, renderTime, _untransformedObjectsWithoutAlphaTest); drawCalls += interactionList.getDepthDrawCalls(); }