summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/scenary/foliage.cpp15
-rw-r--r--game/scenary/foliage.h2
-rw-r--r--gfx/gl/billboardPainter.cpp13
-rw-r--r--gfx/gl/billboardPainter.h4
-rw-r--r--gfx/gl/sceneRenderer.cpp2
-rw-r--r--gfx/gl/shadowStenciller.cpp9
-rw-r--r--gfx/gl/shadowStenciller.h2
7 files changed, 35 insertions, 12 deletions
diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp
index 680d902..0981ffc 100644
--- a/game/scenary/foliage.cpp
+++ b/game/scenary/foliage.cpp
@@ -9,8 +9,9 @@
static_assert(std::is_constructible_v<Foliage>);
constexpr float OBJECT_BILLBOARD_DIVISOR = 64;
+constexpr float BILLBOARD_ANGLE_TOLERANCE = 250.F; // Radians per mm size
constexpr float ASSUMED_VIEWPORT = 1440;
-constexpr float OVER_SAMPLE_MULTIPLIER = 4; // Use mesh until billboard 1/4 of rendered size
+constexpr float OVER_SAMPLE_MULTIPLIER = 2; // Use mesh until billboard 1/2 of rendered size
namespace {
GLsizei
@@ -51,18 +52,22 @@ Foliage::postLoad()
}
void
-Foliage::updateStencil(const ShadowStenciller & ss) const
+Foliage::updateStencil(const ShadowStenciller & shadowStenciller) const
{
- if (instancePartitions.second.second != instancePartitions.second.first) {
- ss.renderStencil(shadowStencil, *bodyMesh, texture);
+ if (instancePartitions.second.second != instancePartitions.second.first
+ && glm::distance(shadowStenciller.getLightDirection(), shadowStencilDir)
+ > BILLBOARD_ANGLE_TOLERANCE / bodyMesh->getDimensions().size) {
+ shadowStenciller.renderStencil(shadowStencil, *bodyMesh, texture);
}
}
void
Foliage::updateBillboard(const BillboardPainter & bbp) const
{
- if (instancePartitions.first != instancePartitions.second.first) {
+ if (instancePartitions.first != instancePartitions.second.first
+ && std::abs(bbp.getAngle() - billboardAngle) > BILLBOARD_ANGLE_TOLERANCE / bodyMesh->getDimensions().size) {
bbp.renderBillBoard(billboard, *bodyMesh, texture);
+ billboardAngle = bbp.getAngle();
}
}
diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h
index c457404..3d73573 100644
--- a/game/scenary/foliage.h
+++ b/game/scenary/foliage.h
@@ -37,7 +37,9 @@ protected:
void postLoad() override;
GLsizei billboardSize {};
RelativeDistance useMeshClipDist {};
+ mutable Direction2D shadowStencilDir {std::numeric_limits<Direction2D::value_type>::infinity()};
glTexture shadowStencil;
+ mutable Angle billboardAngle = std::numeric_limits<Angle>::infinity();
glTextures<3> billboard;
private:
diff --git a/gfx/gl/billboardPainter.cpp b/gfx/gl/billboardPainter.cpp
index 06e13ca..58fdce6 100644
--- a/gfx/gl/billboardPainter.cpp
+++ b/gfx/gl/billboardPainter.cpp
@@ -1,6 +1,4 @@
#include "billboardPainter.h"
-#include "gfx/models/mesh.h"
-#include "glArrays.h"
#include "gl_traits.h"
#include "gldebug.h"
#include "maths.h"
@@ -15,7 +13,7 @@ const auto VIEWS = []<GLint... Ep>(std::integer_sequence<GLint, Ep...>) {
}(std::make_integer_sequence<GLint, BillboardPainter::VIEW_ANGLES<GLint>>());
BillboardPainter::BillboardPainter() :
- program {billboardPainter_vert, billboardPainter_geom, billboardPainter_frag}, view {}
+ program {billboardPainter_vert, billboardPainter_geom, billboardPainter_frag}, angle {}, view {}
{
glDebugScope _ {fbo};
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -28,11 +26,18 @@ BillboardPainter::BillboardPainter() :
}
void
-BillboardPainter::setView(const glm::mat4 & newView)
+BillboardPainter::setView(const Angle newAngle, const glm::mat4 & newView)
{
+ angle = newAngle;
view = newView;
}
+Angle
+BillboardPainter::getAngle() const
+{
+ return angle;
+}
+
glTextures<3>
BillboardPainter::createBillBoardTextures(GLsizei width, GLsizei height)
{
diff --git a/gfx/gl/billboardPainter.h b/gfx/gl/billboardPainter.h
index 4ce7b10..33c807c 100644
--- a/gfx/gl/billboardPainter.h
+++ b/gfx/gl/billboardPainter.h
@@ -15,7 +15,8 @@ public:
[[nodiscard]]
static glTextures<3> createBillBoardTextures(GLsizei width, GLsizei height);
- void setView(const glm::mat4 &);
+ void setView(Angle angle, const glm::mat4 &);
+ [[nodiscard]] Angle getAngle() const;
void renderBillBoard(const glTextures<3> &, const MeshBase &, Texture::AnyPtr texture) const;
private:
@@ -24,5 +25,6 @@ private:
Program::RequiredUniformLocation viewProjectionLoc {program, "viewProjection"};
Program::RequiredUniformLocation viewLoc {program, "view"};
+ Angle angle;
glm::mat4 view;
};
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index efa08ef..15dde1b 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -83,7 +83,7 @@ SceneRenderer::preFrame(const SceneProvider & scene, const LightDirection lightD
{
glDebugScope _ {output};
const auto lightView = shadowMapper.preFrame(lightDirection, camera);
- billboardPainter.setView(camera.getView());
+ billboardPainter.setView(std::asin(camera.getForward().z), camera.getView());
scene.forEachRenderable([&lightView, this](Renderable * renderable) {
renderable->preFrame(camera, lightView);
renderable->updateBillboard(billboardPainter);
diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp
index 7a0fc9b..19c8bef 100644
--- a/gfx/gl/shadowStenciller.cpp
+++ b/gfx/gl/shadowStenciller.cpp
@@ -10,7 +10,7 @@
#include <stdexcept>
ShadowStenciller::ShadowStenciller() :
- shadowCaster {shadowStencil_vert, shadowStencil_geom, shadowStencil_frag}, viewProjections {}
+ shadowCaster {shadowStencil_vert, shadowStencil_geom, shadowStencil_frag}, lightDir {}, viewProjections {}
{
glDebugScope _ {fbo};
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -22,6 +22,7 @@ ShadowStenciller::ShadowStenciller() :
void
ShadowStenciller::setLightDirection(const LightDirection & lightDir)
{
+ this->lightDir = lightDir.position();
viewProjections = [&lightDir]<GLint... Ep>(std::integer_sequence<GLint, Ep...>) {
constexpr float STEP = two_pi / STENCIL_ANGLES<decltype(two_pi)>;
return std::array {rotate_pitch<4>(half_pi - lightDir.position().y)
@@ -29,6 +30,12 @@ ShadowStenciller::setLightDirection(const LightDirection & lightDir)
}(std::make_integer_sequence<GLint, STENCIL_ANGLES<GLint>>());
}
+Direction2D
+ShadowStenciller::getLightDirection() const
+{
+ return lightDir;
+}
+
glTexture
ShadowStenciller::createStencilTexture(GLsizei width, GLsizei height)
{
diff --git a/gfx/gl/shadowStenciller.h b/gfx/gl/shadowStenciller.h
index f774ac7..27ad9f9 100644
--- a/gfx/gl/shadowStenciller.h
+++ b/gfx/gl/shadowStenciller.h
@@ -16,6 +16,7 @@ public:
[[nodiscard]]
static glTexture createStencilTexture(GLsizei width, GLsizei height);
void setLightDirection(const LightDirection & lightDir);
+ [[nodiscard]] Direction2D getLightDirection() const;
void renderStencil(const glTexture &, const MeshBase &, Texture::AnyPtr texture) const;
private:
@@ -23,5 +24,6 @@ private:
Program shadowCaster;
Program::RequiredUniformLocation viewProjectionLoc {shadowCaster, "viewProjection"};
+ Direction2D lightDir;
std::array<glm::mat4, STENCIL_ANGLES<size_t>> viewProjections;
};