Skip to content

Commit

Permalink
#219: Port the error correction terms from the TDM shaders.
Browse files Browse the repository at this point in the history
Don't cull out-of-view objects for shadow-casting lights
  • Loading branch information
codereader committed Mar 25, 2022
1 parent 4dcebf6 commit e51121e
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 17 deletions.
21 changes: 13 additions & 8 deletions install/gl/interaction_fp.glsl
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
20 changes: 13 additions & 7 deletions radiantcore/rendersystem/backend/LightInteractions.cpp
Expand Up @@ -33,6 +33,8 @@ bool LightInteractions::castsShadows()

void LightInteractions::collectSurfaces(const IRenderView& view, const std::set<IRenderEntityPtr>& entities)
{
bool shadowCasting = castsShadows();

// Now check all the entities intersecting with this light
for (const auto& entity : entities)
{
Expand All @@ -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<OpenGLShader*>(shader);

Expand All @@ -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<IGeometryStore::Slot>& untransformedObjectsWithoutAlphaTest)
std::size_t renderTime, std::vector<IGeometryStore::Slot>& untransformedObjectsWithoutAlphaTest)
{
std::vector<IGeometryStore::Slot> untransformedObjects;
untransformedObjects.reserve(1000);
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/rendersystem/backend/LightInteractions.h
Expand Up @@ -91,7 +91,7 @@ class LightInteractions
void collectSurfaces(const IRenderView& view, const std::set<IRenderEntityPtr>& entities);

void fillDepthBuffer(OpenGLState& state, GLSLDepthFillAlphaProgram& program,
const IRenderView& view, std::size_t renderTime, std::vector<IGeometryStore::Slot>& untransformedObjectsWithoutAlphaTest);
std::size_t renderTime, std::vector<IGeometryStore::Slot>& untransformedObjectsWithoutAlphaTest);

void drawShadowMap(OpenGLState& state, const Rectangle& rectangle, ShadowMapProgram& program);

Expand Down
7 changes: 6 additions & 1 deletion radiantcore/rendersystem/backend/LightingModeRenderer.cpp
Expand Up @@ -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);
Expand All @@ -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]);

Expand Down Expand Up @@ -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();
}

Expand Down

0 comments on commit e51121e

Please sign in to comment.