summaryrefslogtreecommitdiff
path: root/gfx
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2022-12-04 17:16:31 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2022-12-04 17:16:31 +0000
commit6433b56c3af8721f8301255818a8dd692e75492e (patch)
tree46471356f76e4dc66746fa4133c928609b5c0620 /gfx
parentFixed point shadow shader doesn't need normal/texture data (diff)
downloadilt-6433b56c3af8721f8301255818a8dd692e75492e.tar.bz2
ilt-6433b56c3af8721f8301255818a8dd692e75492e.tar.xz
ilt-6433b56c3af8721f8301255818a8dd692e75492e.zip
Generate and use a shadow map
Generated when the directional light is specified in the environment call, passed to the directional light shader pass to conditionally illuminate each pixel.
Diffstat (limited to 'gfx')
-rw-r--r--gfx/gl/sceneProvider.cpp2
-rw-r--r--gfx/gl/sceneRenderer.cpp22
-rw-r--r--gfx/gl/sceneRenderer.h8
-rw-r--r--gfx/gl/shaders/directionalLight.fs9
4 files changed, 32 insertions, 9 deletions
diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp
index 9152bfa..8ff7d73 100644
--- a/gfx/gl/sceneProvider.cpp
+++ b/gfx/gl/sceneProvider.cpp
@@ -5,7 +5,7 @@ void
SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer) const
{
renderer.setAmbientLight({0.5F, 0.5F, 0.5F});
- renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {1, 0, -1});
+ renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {1, 0, -1}, *this);
}
void
SceneProvider::shadows(const ShadowMapper &) const
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index a06a163..49c73a2 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -78,11 +78,15 @@ SceneRenderer::render(const SceneProvider & scene) const
glBindTexture(GL_TEXTURE_2D, gPosition);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormal);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, shadowMapper);
scene.environment(shader, *this);
scene.lights(shader);
// Lighting pass
glBindFramebuffer(GL_FRAMEBUFFER, output);
+ glViewport(0, 0, size.x, size.y);
+ glCullFace(GL_BACK);
glDisable(GL_BLEND);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
@@ -102,32 +106,40 @@ SceneRenderer::render(const SceneProvider & scene) const
void
SceneRenderer::setAmbientLight(const glm::vec3 & colour) const
{
+ glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(colour.r, colour.g, colour.b, 1.0F);
glClear(GL_COLOR_BUFFER_BIT);
}
void
-SceneRenderer::setDirectionalLight(const glm::vec3 & colour, const glm::vec3 & direction) const
+SceneRenderer::setDirectionalLight(
+ const glm::vec3 & colour, const glm::vec3 & direction, const SceneProvider & scene) const
{
if (colour.r > 0 || colour.g > 0 || colour.b > 0) {
+ const auto lvp = shadowMapper.update(scene, direction);
+ glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
+ glViewport(0, 0, size.x, size.y);
dirLight.use();
- dirLight.setDirectionalLight(colour, direction);
+ dirLight.setDirectionalLight(colour, direction, lvp);
glBindVertexArray(displayVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
+ glEnable(GL_DEPTH_TEST);
}
}
SceneRenderer::DirectionalLightProgram::DirectionalLightProgram() :
- Program {lightingShader_vs, directionalLight_fs}, directionLoc {*this, "lightDirection"}, colourLoc {*this,
- "lightColour"}
+ Program {lightingShader_vs, directionalLight_fs}, directionLoc {*this, "lightDirection"},
+ colourLoc {*this, "lightColour"}, lightViewProjectionLoc {*this, "lightViewProjection"}
{
}
void
-SceneRenderer::DirectionalLightProgram::setDirectionalLight(const glm::vec3 & c, const glm::vec3 & d) const
+SceneRenderer::DirectionalLightProgram::setDirectionalLight(
+ const glm::vec3 & c, const glm::vec3 & d, const glm::mat4x4 & lvp) const
{
glUniform3fv(colourLoc, 1, glm::value_ptr(c));
const auto nd = glm::normalize(d);
glUniform3fv(directionLoc, 1, glm::value_ptr(nd));
+ glUniformMatrix4fv(lightViewProjectionLoc, 1, GL_FALSE, glm::value_ptr(lvp));
}
diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h
index 736b15a..d7a92b7 100644
--- a/gfx/gl/sceneRenderer.h
+++ b/gfx/gl/sceneRenderer.h
@@ -5,6 +5,7 @@
#include "program.h"
#include "sceneProvider.h"
#include "sceneShader.h"
+#include "shadowMapper.h"
#include <functional>
#include <glm/fwd.hpp>
@@ -14,7 +15,7 @@ public:
void render(const SceneProvider &) const;
void setAmbientLight(const glm::vec3 & colour) const;
- void setDirectionalLight(const glm::vec3 & colour, const glm::vec3 & direction) const;
+ void setDirectionalLight(const glm::vec3 & colour, const glm::vec3 & direction, const SceneProvider &) const;
Camera camera;
@@ -34,10 +35,10 @@ private:
DirectionalLightProgram();
using Program::use;
- void setDirectionalLight(const glm::vec3 &, const glm::vec3 &) const;
+ void setDirectionalLight(const glm::vec3 &, const glm::vec3 &, const glm::mat4x4 &) const;
private:
- RequiredUniformLocation directionLoc, colourLoc;
+ RequiredUniformLocation directionLoc, colourLoc, lightViewProjectionLoc;
};
DeferredLightProgram lighting;
@@ -45,4 +46,5 @@ private:
glVertexArray displayVAO;
glBuffer displayVBO;
SceneShader shader;
+ ShadowMapper shadowMapper;
};
diff --git a/gfx/gl/shaders/directionalLight.fs b/gfx/gl/shaders/directionalLight.fs
index 7562f96..5350bf3 100644
--- a/gfx/gl/shaders/directionalLight.fs
+++ b/gfx/gl/shaders/directionalLight.fs
@@ -5,14 +5,23 @@ out vec3 FragColor;
in vec2 TexCoords;
+layout(binding = 0) uniform sampler2D gPosition;
layout(binding = 1) uniform sampler2D gNormal;
+layout(binding = 2) uniform sampler2D shadowMap;
uniform vec3 lightDirection;
uniform vec3 lightColour;
+uniform mat4 lightViewProjection;
void
main()
{
+ const vec3 Position = texture(gPosition, TexCoords).xyz;
+ const vec4 PositionInLightSpace = (lightViewProjection * vec4(Position, 1)) * 0.5 + 0.5;
+ const float lightSpaceDepth = texture(shadowMap, PositionInLightSpace.xy).r;
+ if (lightSpaceDepth < PositionInLightSpace.z) {
+ discard;
+ }
const vec3 Normal = texture(gNormal, TexCoords).rgb;
FragColor = dot(-lightDirection, Normal) * lightColour;
}