summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/gl/sceneRenderer.cpp2
-rw-r--r--gfx/gl/shaders/commonShadowPoint.glsl5
-rw-r--r--gfx/gl/shaders/commonShadowPoint.gs22
-rw-r--r--gfx/gl/shaders/directionalLight.fs7
-rw-r--r--gfx/gl/shaders/shadowDynamicPoint.vs1
-rw-r--r--gfx/gl/shaders/shadowDynamicPointInst.vs1
-rw-r--r--gfx/gl/shaders/shadowFixedPoint.vs1
-rw-r--r--gfx/gl/shadowMapper.cpp80
-rw-r--r--gfx/gl/shadowMapper.h18
9 files changed, 88 insertions, 49 deletions
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index 4c96902..b60d9af 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -81,7 +81,7 @@ SceneRenderer::render(const SceneProvider & scene) const
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormal);
glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, shadowMapper);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper);
scene.environment(shader, *this);
glDisable(GL_DEPTH_TEST);
scene.lights(shader);
diff --git a/gfx/gl/shaders/commonShadowPoint.glsl b/gfx/gl/shaders/commonShadowPoint.glsl
index 47722d6..ba4611a 100644
--- a/gfx/gl/shaders/commonShadowPoint.glsl
+++ b/gfx/gl/shaders/commonShadowPoint.glsl
@@ -1,7 +1,8 @@
+out vec4 vworldPos;
+
void
main()
{
vec3 worldPos = model * position;
- gl_Position = viewProjection * vec4(worldPos - viewPoint + modelPos, 1);
- gl_Position.z = max(gl_Position.z, -1);
+ vworldPos = vec4(worldPos - viewPoint + modelPos, 1);
}
diff --git a/gfx/gl/shaders/commonShadowPoint.gs b/gfx/gl/shaders/commonShadowPoint.gs
new file mode 100644
index 0000000..b008f29
--- /dev/null
+++ b/gfx/gl/shaders/commonShadowPoint.gs
@@ -0,0 +1,22 @@
+#version 330 core
+#extension GL_ARB_viewport_array : enable
+
+uniform mat4 viewProjection[4];
+uniform int viewProjections;
+in vec4 vworldPos[];
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 12) out;
+
+void
+main()
+{
+ for (int vp = 0; vp < viewProjections; ++vp) {
+ for (int v = 0; v < vworldPos.length(); ++v) {
+ gl_Position = viewProjection[vp] * vworldPos[v];
+ gl_Position.z = max(gl_Position.z, -1);
+ gl_Layer = vp;
+ EmitVertex();
+ }
+ EndPrimitive();
+ }
+}
diff --git a/gfx/gl/shaders/directionalLight.fs b/gfx/gl/shaders/directionalLight.fs
index f36d83f..d0c5062 100644
--- a/gfx/gl/shaders/directionalLight.fs
+++ b/gfx/gl/shaders/directionalLight.fs
@@ -9,7 +9,7 @@ in vec2 TexCoords;
layout(binding = 0) uniform isampler2D gPosition;
layout(binding = 1) uniform sampler2D gNormal;
-layout(binding = 2) uniform sampler2D shadowMap;
+layout(binding = 2) uniform sampler2DArray shadowMap;
uniform vec3 lightDirection;
uniform vec3 lightColour;
@@ -34,8 +34,9 @@ isShaded(vec4 Position)
const vec3 PositionInLightSpace = (lightViewProjection[m] * Position).xyz;
const float inside = insideShadowCube(PositionInLightSpace);
if (inside > 0) {
- const float lightSpaceDepth
- = texture(shadowMap, PositionInLightSpace.xy * shadowMapRegion[m].xy + shadowMapRegion[m].zw).r;
+ const float lightSpaceDepth = texture(
+ shadowMap, vec3(PositionInLightSpace.xy * shadowMapRegion[m].xy + shadowMapRegion[m].zw, m))
+ .r;
return step(lightSpaceDepth, PositionInLightSpace.z * .5 + .5);
}
}
diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs
index bf0f0a1..7335b9a 100644
--- a/gfx/gl/shaders/shadowDynamicPoint.vs
+++ b/gfx/gl/shaders/shadowDynamicPoint.vs
@@ -2,7 +2,6 @@
include(`meshIn.glsl')
-uniform mat4 viewProjection;
uniform ivec3 viewPoint;
uniform mat3 model;
uniform ivec3 modelPos;
diff --git a/gfx/gl/shaders/shadowDynamicPointInst.vs b/gfx/gl/shaders/shadowDynamicPointInst.vs
index b0b80da..d0eb649 100644
--- a/gfx/gl/shaders/shadowDynamicPointInst.vs
+++ b/gfx/gl/shaders/shadowDynamicPointInst.vs
@@ -2,7 +2,6 @@
include(`meshIn.glsl')
-uniform mat4 viewProjection;
uniform ivec3 viewPoint;
layout(location = 5) in mat3 model;
layout(location = 8) in ivec3 modelPos;
diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs
index 307aac2..1376388 100644
--- a/gfx/gl/shaders/shadowFixedPoint.vs
+++ b/gfx/gl/shaders/shadowFixedPoint.vs
@@ -2,7 +2,6 @@
include(`meshIn.glsl')
-uniform mat4 viewProjection;
uniform ivec3 viewPoint;
const mat3 model = mat3(1);
const ivec3 modelPos = ivec3(0);
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index 040010f..7770c9d 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -1,6 +1,7 @@
#include "shadowMapper.h"
#include "camera.h"
#include "collections.h"
+#include "gfx/gl/shaders/gs-commonShadowPoint.h"
#include "gfx/gl/shaders/vs-shadowDynamicPoint.h"
#include "gfx/gl/shaders/vs-shadowDynamicPointInst.h"
#include "gfx/gl/shaders/vs-shadowFixedPoint.h"
@@ -17,19 +18,21 @@
#include <vector>
ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
- fixedPoint {shadowFixedPoint_vs}, dynamicPointInst {shadowDynamicPointInst_vs}, size {s}
+ fixedPoint {shadowFixedPoint_vs, commonShadowPoint_gs},
+ dynamicPointInst {shadowDynamicPointInst_vs, commonShadowPoint_gs}, size {s}
{
- glBindTexture(GL_TEXTURE_2D, depthMap);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, depthMap);
+ glTexImage3D(
+ GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, size.x, size.y, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
static constexpr RGBA border {std::numeric_limits<RGBA::value_type>::infinity()};
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, border);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
@@ -130,19 +133,16 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
glCullFace(GL_FRONT);
+ glViewport(0, 0, size.x, size.y);
const auto lightViewDir = glm::lookAt({}, dir, up);
const auto lightViewPoint = camera.getPosition();
const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
- fixedPoint.setViewPoint(lightViewPoint);
- dynamicPoint.setViewPoint(lightViewPoint);
- dynamicPointInst.setViewPoint(lightViewPoint);
-
Definitions out;
std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()),
DefinitionsInserter {out},
- [&scene, this, bands = bandViewExtents.size() - 2, &out, &lightViewDir](
- const auto & near, const auto & far) {
+ [this, bands = bandViewExtents.size() - 2, &out, &lightViewDir](
+ const auto & near, const auto & far) mutable {
const auto extents_minmax = [extents = std::span {near.begin(), far.end()}](auto && comp) {
const auto mm = std::minmax_element(extents.begin(), extents.end(), comp);
return std::make_pair(comp.get(*mm.first), comp.get(*mm.second));
@@ -153,39 +153,46 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
}(extents_minmax(CompareBy {0}), extents_minmax(CompareBy {1}), extents_minmax(CompareBy {2}));
const auto lightViewDirProjection = lightProjection * lightViewDir;
- fixedPoint.setViewProjection(lightViewDirProjection);
- dynamicPoint.setViewProjection(lightViewDirProjection);
- dynamicPointInst.setViewProjection(lightViewDirProjection);
-
- const auto & viewport = viewports[bands][out.maps];
- glViewport(size.x >> viewport.x, size.y >> viewport.y, size.x >> viewport.z, size.y >> viewport.w);
- scene.shadows(*this);
+ fixedPoint.setViewProjection(lightViewDirProjection, out.maps);
+ dynamicPoint.setViewProjection(lightViewDirProjection, out.maps);
+ dynamicPointInst.setViewProjection(lightViewDirProjection, out.maps);
- return std::make_pair(lightViewDirProjection, shadowMapRegions[bands][out.maps]);
+ return std::make_pair(lightViewDirProjection, shadowMapRegions[0][0]);
});
+ fixedPoint.setViewPoint(lightViewPoint, out.maps);
+ dynamicPoint.setViewPoint(lightViewPoint, out.maps);
+ dynamicPointInst.setViewPoint(lightViewPoint, out.maps);
+ scene.shadows(*this);
glCullFace(GL_BACK);
return out;
}
-ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) :
- Program {vs}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"}
+ShadowMapper::FixedPoint::FixedPoint(const Shader & vs, const Shader & gs) :
+ Program {vs, gs}, viewProjectionLoc {{
+ {*this, "viewProjection[0]"},
+ {*this, "viewProjection[1]"},
+ {*this, "viewProjection[2]"},
+ {*this, "viewProjection[3]"},
+ }},
+ viewProjectionsLoc {*this, "viewProjections"}, viewPointLoc {*this, "viewPoint"}
{
}
void
-ShadowMapper::FixedPoint::setViewPoint(const GlobalPosition3D viewPoint) const
+ShadowMapper::FixedPoint::setViewPoint(const GlobalPosition3D viewPoint, size_t n) const
{
use();
glUniform(viewPointLoc, viewPoint);
+ glUniform(viewProjectionsLoc, static_cast<GLint>(n));
}
void
-ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection) const
+ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection, size_t n) const
{
use();
- glUniform(viewProjectionLoc, viewProjection);
+ glUniform(viewProjectionLoc[n], viewProjection);
}
void
@@ -195,23 +202,30 @@ ShadowMapper::FixedPoint::use() const
}
ShadowMapper::DynamicPoint::DynamicPoint() :
- Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"},
- modelLoc {*this, "model"}, modelPosLoc {*this, "modelPos"}
+ Program {shadowDynamicPoint_vs, commonShadowPoint_gs}, viewProjectionLoc {{
+ {*this, "viewProjection[0]"},
+ {*this, "viewProjection[1]"},
+ {*this, "viewProjection[2]"},
+ {*this, "viewProjection[3]"},
+ }},
+ viewProjectionsLoc {*this, "viewProjections"}, viewPointLoc {*this, "viewPoint"}, modelLoc {*this, "model"},
+ modelPosLoc {*this, "modelPos"}
{
}
void
-ShadowMapper::DynamicPoint::setViewPoint(const GlobalPosition3D viewPoint) const
+ShadowMapper::DynamicPoint::setViewPoint(const GlobalPosition3D viewPoint, size_t n) const
{
glUseProgram(*this);
glUniform(viewPointLoc, viewPoint);
+ glUniform(viewProjectionsLoc, static_cast<GLint>(n));
}
void
-ShadowMapper::DynamicPoint::setViewProjection(const glm::mat4 & viewProjection) const
+ShadowMapper::DynamicPoint::setViewProjection(const glm::mat4 & viewProjection, size_t n) const
{
glUseProgram(*this);
- glUniform(viewProjectionLoc, viewProjection);
+ glUniform(viewProjectionLoc[n], viewProjection);
}
void
diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h
index 065db4f..421e6a5 100644
--- a/gfx/gl/shadowMapper.h
+++ b/gfx/gl/shadowMapper.h
@@ -26,25 +26,29 @@ public:
class FixedPoint : public Program {
public:
- FixedPoint(const Shader & vs);
- void setViewPoint(const GlobalPosition3D) const;
- void setViewProjection(const glm::mat4 &) const;
+ FixedPoint(const Shader & vs, const Shader & gs);
+ void setViewPoint(const GlobalPosition3D, size_t n) const;
+ void setViewProjection(const glm::mat4 &, size_t n) const;
void use() const;
private:
- RequiredUniformLocation viewProjectionLoc, viewPointLoc;
+ std::array<RequiredUniformLocation, 4> viewProjectionLoc;
+ RequiredUniformLocation viewProjectionsLoc;
+ RequiredUniformLocation viewPointLoc;
};
class DynamicPoint : public Program {
public:
DynamicPoint();
- void setViewPoint(const GlobalPosition3D) const;
- void setViewProjection(const glm::mat4 &) const;
+ void setViewPoint(const GlobalPosition3D, size_t n) const;
+ void setViewProjection(const glm::mat4 &, size_t n) const;
void use(const Location &) const;
void setModel(const Location &) const;
private:
- RequiredUniformLocation viewProjectionLoc, viewPointLoc;
+ std::array<RequiredUniformLocation, 4> viewProjectionLoc;
+ RequiredUniformLocation viewProjectionsLoc;
+ RequiredUniformLocation viewPointLoc;
RequiredUniformLocation modelLoc;
RequiredUniformLocation modelPosLoc;
};