diff options
| -rw-r--r-- | game/scenary/foliage.cpp | 15 | ||||
| -rw-r--r-- | game/scenary/foliage.h | 2 | ||||
| -rw-r--r-- | gfx/gl/billboardPainter.cpp | 13 | ||||
| -rw-r--r-- | gfx/gl/billboardPainter.h | 4 | ||||
| -rw-r--r-- | gfx/gl/sceneRenderer.cpp | 2 | ||||
| -rw-r--r-- | gfx/gl/shadowStenciller.cpp | 9 | ||||
| -rw-r--r-- | gfx/gl/shadowStenciller.h | 2 |
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; }; |
