summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-12-17 18:58:53 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2023-12-17 18:58:53 +0000
commitedb63bcb5fd140d0d4db71e170a43f767a4b70be (patch)
tree2703b2e4517ead609738e2597e0ab20670643573
parentUse new calc types in camera extents to address overflow (diff)
downloadilt-edb63bcb5fd140d0d4db71e170a43f767a4b70be.tar.bz2
ilt-edb63bcb5fd140d0d4db71e170a43f767a4b70be.tar.xz
ilt-edb63bcb5fd140d0d4db71e170a43f767a4b70be.zip
Run shadow mapper in camera relative space
-rw-r--r--gfx/gl/sceneRenderer.cpp10
-rw-r--r--gfx/gl/sceneRenderer.h8
-rw-r--r--gfx/gl/shaders/directionalLight.fs7
-rw-r--r--gfx/gl/shadowMapper.cpp16
4 files changed, 22 insertions, 19 deletions
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index 2854dea..c856279 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -116,7 +116,7 @@ SceneRenderer::setDirectionalLight(const RGB & colour, const Direction3D & direc
glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll);
glViewport(0, 0, size.x, size.y);
dirLight.use();
- dirLight.setDirectionalLight(colour, direction, lvp.projections, lvp.regions, lvp.maps);
+ dirLight.setDirectionalLight(colour, direction, camera.getPosition(), lvp.projections, lvp.regions, lvp.maps);
renderQuad();
}
}
@@ -131,7 +131,8 @@ SceneRenderer::renderQuad() const
SceneRenderer::DirectionalLightProgram::DirectionalLightProgram() :
Program {lighting_vs, directionalLight_fs}, directionLoc {*this, "lightDirection"},
- colourLoc {*this, "lightColour"}, lightViewProjectionLoc {*this, "lightViewProjection"},
+ colourLoc {*this, "lightColour"}, lightPointLoc {*this, "lightPoint"},
+ lightViewProjectionLoc {*this, "lightViewProjection"},
lightViewProjectionCountLoc {*this, "lightViewProjectionCount"},
lightViewShadowMapRegionLoc {*this, "shadowMapRegion"}
{
@@ -139,12 +140,13 @@ SceneRenderer::DirectionalLightProgram::DirectionalLightProgram() :
void
SceneRenderer::DirectionalLightProgram::setDirectionalLight(const RGB & c, const Direction3D & d,
- const std::span<const glm::mat4x4> lvp, const std::span<const TextureRelRegion> shadowMapRegions,
- std::size_t maps) const
+ const GlobalPosition3D & p, const std::span<const glm::mat4x4> lvp,
+ const std::span<const TextureRelRegion> shadowMapRegions, std::size_t maps) const
{
glUniform3fv(colourLoc, 1, glm::value_ptr(c));
const auto nd = glm::normalize(d);
glUniform3fv(directionLoc, 1, glm::value_ptr(nd));
+ glUniform3iv(lightPointLoc, 1, glm::value_ptr(p));
glUniform1ui(lightViewProjectionCountLoc, static_cast<GLuint>(maps));
glUniformMatrix4fv(lightViewProjectionLoc, static_cast<GLsizei>(maps), GL_FALSE, glm::value_ptr(lvp.front()));
glUniform4fv(lightViewShadowMapRegionLoc, static_cast<GLsizei>(maps), glm::value_ptr(shadowMapRegions.front()));
diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h
index c935f93..797ecf1 100644
--- a/gfx/gl/sceneRenderer.h
+++ b/gfx/gl/sceneRenderer.h
@@ -39,12 +39,12 @@ protected:
DirectionalLightProgram();
using Program::use;
- void setDirectionalLight(const RGB &, const Direction3D &, const std::span<const glm::mat4x4>,
- const std::span<const TextureRelRegion>, std::size_t maps) const;
+ void setDirectionalLight(const RGB &, const Direction3D &, const GlobalPosition3D &,
+ const std::span<const glm::mat4x4>, const std::span<const TextureRelRegion>, std::size_t maps) const;
private:
- RequiredUniformLocation directionLoc, colourLoc, lightViewProjectionLoc, lightViewProjectionCountLoc,
- lightViewShadowMapRegionLoc;
+ RequiredUniformLocation directionLoc, colourLoc, lightPointLoc, lightViewProjectionLoc,
+ lightViewProjectionCountLoc, lightViewShadowMapRegionLoc;
};
DeferredLightProgram lighting;
diff --git a/gfx/gl/shaders/directionalLight.fs b/gfx/gl/shaders/directionalLight.fs
index 3756db7..f36d83f 100644
--- a/gfx/gl/shaders/directionalLight.fs
+++ b/gfx/gl/shaders/directionalLight.fs
@@ -13,6 +13,7 @@ layout(binding = 2) uniform sampler2D shadowMap;
uniform vec3 lightDirection;
uniform vec3 lightColour;
+uniform ivec3 lightPoint;
uniform mat4 lightViewProjection[MAX_MAPS];
uniform vec4 shadowMapRegion[MAX_MAPS];
uniform uint lightViewProjectionCount;
@@ -27,10 +28,10 @@ insideShadowCube(vec3 v)
}
float
-isShaded(ivec3 Position)
+isShaded(vec4 Position)
{
for (uint m = 0u; m < lightViewProjectionCount; m++) {
- vec3 PositionInLightSpace = (lightViewProjection[m] * vec4(Position, 1.0f)).xyz;
+ const vec3 PositionInLightSpace = (lightViewProjection[m] * Position).xyz;
const float inside = insideShadowCube(PositionInLightSpace);
if (inside > 0) {
const float lightSpaceDepth
@@ -44,7 +45,7 @@ isShaded(ivec3 Position)
void
main()
{
- const ivec3 Position = texture(gPosition, TexCoords).xyz;
+ const vec4 Position = vec4(texture(gPosition, TexCoords).xyz - lightPoint, 1);
const vec3 Normal = texture(gNormal, TexCoords).rgb;
const float shaded = isShaded(Position);
FragColor = (1 - shaded) * max(dot(-lightDirection, Normal) * lightColour, 0);
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index deb0630..74d93bd 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -106,14 +106,15 @@ struct DefinitionsInserter {
};
std::vector<std::array<Position3D, 4>>
-ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightView)
+ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightViewDir)
{
std::vector<std::array<Position3D, 4>> bandViewExtents;
for (const auto dist : shadowBands) {
const auto extents = camera.extentsAtDist(dist);
- bandViewExtents.emplace_back(extents * [&lightView](const auto & e) -> Position3D {
- return lightView * glm::vec4(Position3D {e}, 1);
- });
+ bandViewExtents.emplace_back(
+ extents * [&lightViewDir, cameraPos = camera.getPosition()](const auto & e) -> Position3D {
+ return lightViewDir * RelativePosition4D(e.xyz() - cameraPos, 1);
+ });
if (std::none_of(extents.begin(), extents.end(), [targetDist = dist - 1](const auto & e) {
return e.w > targetDist;
})) {
@@ -131,14 +132,13 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
glCullFace(GL_FRONT);
const auto lightViewDir = glm::lookAt(origin, dir, up);
- const auto lightView = lightViewDir * glm::translate(RelativePosition3D {-camera.getPosition()});
const auto lightViewPoint = camera.getPosition();
- const auto bandViewExtents = getBandViewExtents(camera, lightView);
+ const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
Definitions out;
std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()),
DefinitionsInserter {out},
- [&scene, this, &lightView, bands = bandViewExtents.size() - 2, &out, &lightViewPoint, &lightViewDir](
+ [&scene, this, bands = bandViewExtents.size() - 2, &out, &lightViewPoint, &lightViewDir](
const auto & near, const auto & far) {
const auto extents_minmax = [extents = std::span {near.begin(), far.end()}](auto && comp) {
const auto mm = std::minmax_element(extents.begin(), extents.end(), comp);
@@ -158,7 +158,7 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
glViewport(size.x >> viewport.x, size.y >> viewport.y, size.x >> viewport.z, size.y >> viewport.w);
scene.shadows(*this);
- return std::make_pair(lightProjection * lightView, shadowMapRegions[bands][out.maps]);
+ return std::make_pair(lightViewDirProjection, shadowMapRegions[bands][out.maps]);
});
glCullFace(GL_BACK);