diff options
Diffstat (limited to 'gfx/gl')
-rw-r--r-- | gfx/gl/camera.cpp | 62 | ||||
-rw-r--r-- | gfx/gl/camera.h | 87 | ||||
-rw-r--r-- | gfx/gl/sceneProvider.cpp | 2 | ||||
-rw-r--r-- | gfx/gl/sceneProvider.h | 5 | ||||
-rw-r--r-- | gfx/gl/sceneRenderer.cpp | 2 | ||||
-rw-r--r-- | gfx/gl/sceneRenderer.h | 2 | ||||
-rw-r--r-- | gfx/gl/shadowMapper.cpp | 42 |
7 files changed, 27 insertions, 175 deletions
diff --git a/gfx/gl/camera.cpp b/gfx/gl/camera.cpp deleted file mode 100644 index f03e85b..0000000 --- a/gfx/gl/camera.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "camera.h" -#include <collections.h> -#include <glm/gtx/transform.hpp> -#include <maths.h> -#include <ray.h> - -Camera::Camera(GlobalPosition3D pos, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar) : - position {pos}, forward {::north}, up {::up}, near {zNear}, far {zFar}, view {}, - projection { - glm::perspective(fov, aspect, static_cast<RelativeDistance>(zNear), static_cast<RelativeDistance>(zFar))}, - viewProjection {}, inverseViewProjection {} -{ - updateView(); -} - -Ray<GlobalPosition3D> -Camera::unProject(const ScreenRelCoord & mouse) const -{ - static constexpr const glm::vec4 SCREEN {0, 0, 1, 1}; - return { - .start = position, - .direction = glm::normalize(glm::unProject(mouse || 1.F, view, projection, SCREEN)), - }; -} - -void -Camera::updateView() -{ - view = glm::lookAt({}, forward, up); - viewProjection = projection * view; - inverseViewProjection = glm::inverse(viewProjection); -} - -Direction3D -Camera::upFromForward(const Direction3D & forward) -{ - const auto right = crossProduct(forward, ::down); - return crossProduct(forward, right); -} - -std::array<GlobalPosition4D, 4> -Camera::extentsAtDist(const GlobalDistance dist) const -{ - const auto clampToSeaFloor = [this, dist](GlobalPosition3D target) -> GlobalPosition4D { - target += position; - if (target.z < -1500) { - const CalcPosition3D diff = target - position; - const CalcDistance limit = -1500 - position.z; - return {position + ((limit * diff) / diff.z), (limit * dist) / diff.z}; - } - return {target, dist}; - }; - const auto depth = -(2.F * (static_cast<float>(dist - near)) * static_cast<float>(far)) - / (static_cast<float>(dist) * (static_cast<float>(near - far))) - - 1.F; - static constexpr const std::array extents {-1.F, 1.F}; - static constexpr const auto cartesianExtents = extents * extents; - return cartesianExtents * [&depth, this, &clampToSeaFloor](const auto & extent) { - const glm::vec4 in {extent.first, extent.second, depth, 1.F}; - return clampToSeaFloor(perspective_divide(inverseViewProjection * in)); - }; -} diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h deleted file mode 100644 index 5c37744..0000000 --- a/gfx/gl/camera.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "config/types.h" -#include <glm/glm.hpp> -#include <maths.h> -#include <ray.h> - -class Camera { -public: - Camera(GlobalPosition3D, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar); - - [[nodiscard]] glm::mat4 - getViewProjection() const - { - return viewProjection; - } - - [[nodiscard]] Ray<GlobalPosition3D> unProject(const ScreenRelCoord &) const; - - void - setPosition(const GlobalPosition3D & p) - { - position = p; - updateView(); - } - - void - setForward(const Direction3D & f) - { - setForward(f, upFromForward(f)); - } - - void - setForward(const Direction3D & f, const Direction3D & u) - { - forward = f; - up = u; - updateView(); - } - - void - setView(const GlobalPosition3D & p, const Direction3D & f) - { - position = p; - setForward(f); - } - - void - setView(const GlobalPosition3D & p, const Direction3D & f, const Direction3D & u) - { - position = p; - setView(f, u); - } - - void - lookAt(const GlobalPosition3D & target) - { - setForward(glm::normalize(RelativePosition3D(target - position))); - } - - [[nodiscard]] auto - getForward() const - { - return forward; - } - - [[nodiscard]] auto - getPosition() const - { - return position; - } - - [[nodiscard]] std::array<GlobalPosition4D, 4> extentsAtDist(GlobalDistance) const; - - [[nodiscard]] static Direction3D upFromForward(const Direction3D & forward); - -private: - void updateView(); - - GlobalPosition3D position; - Direction3D forward; - Direction3D up; - - GlobalDistance near, far; - glm::mat4 view, projection; - glm::mat4 viewProjection, inverseViewProjection; -}; diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp index 4e271db..e01532e 100644 --- a/gfx/gl/sceneProvider.cpp +++ b/gfx/gl/sceneProvider.cpp @@ -9,6 +9,6 @@ SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer) } void -SceneProvider::shadows(const ShadowMapper &) const +SceneProvider::shadows(const ShadowMapper &, const Frustum &) const { } diff --git a/gfx/gl/sceneProvider.h b/gfx/gl/sceneProvider.h index f5e8e99..f6b7009 100644 --- a/gfx/gl/sceneProvider.h +++ b/gfx/gl/sceneProvider.h @@ -5,6 +5,7 @@ class SceneRenderer; class ShadowMapper; class SceneShader; +class Frustum; class SceneProvider { public: @@ -12,8 +13,8 @@ public: virtual ~SceneProvider() = default; DEFAULT_MOVE_COPY(SceneProvider); - virtual void content(const SceneShader &) const = 0; + virtual void content(const SceneShader &, const Frustum &) const = 0; virtual void environment(const SceneShader &, const SceneRenderer &) const; virtual void lights(const SceneShader &) const = 0; - virtual void shadows(const ShadowMapper &) const; + virtual void shadows(const ShadowMapper &, const Frustum &) const; }; diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index b2a7d78..188c4fd 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -71,7 +71,7 @@ SceneRenderer::render(const SceneProvider & scene) const glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - scene.content(shader); + scene.content(shader, camera); // Environment pass - // * ambient - clears illumination texture - see setAmbientLight diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index 93470f5..4649a68 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -1,12 +1,12 @@ #pragma once -#include "camera.h" #include "gfx/lightDirection.h" #include "glArrays.h" #include "program.h" #include "sceneProvider.h" #include "sceneShader.h" #include "shadowMapper.h" +#include <gfx/camera.h> #include <glm/fwd.hpp> class SceneRenderer { diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 1b95aa3..6525f76 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -1,7 +1,7 @@ #include "shadowMapper.h" -#include "camera.h" #include "collections.h" #include "game/gamestate.h" +#include "gfx/aabb.h" #include "gfx/gl/shaders/fs-shadowDynamicPointInstWithTextures.h" #include "gfx/gl/shaders/fs-shadowDynamicPointStencil.h" #include "gfx/gl/shaders/gs-commonShadowPoint.h" @@ -20,7 +20,7 @@ #include "maths.h" #include "sceneProvider.h" #include "sceneShader.h" -#include "sorting.h" +#include <gfx/camera.h> #include <glm/gtc/type_ptr.hpp> #include <glm/gtx/transform.hpp> #include <glm/matrix.hpp> @@ -56,7 +56,7 @@ constexpr auto shadowBands = []<GlobalDistance... ints>(const float scaleFactor, std::integer_sequence<GlobalDistance, ints...>) { const auto base = 10'000'000 / pow(scaleFactor, sizeof...(ints) - 1); return std::array {1, static_cast<GlobalDistance>((base * pow(scaleFactor, ints)))...}; - }(6.6F, std::make_integer_sequence<GlobalDistance, ShadowMapper::SHADOW_BANDS>()); + }(4.6F, std::make_integer_sequence<GlobalDistance, ShadowMapper::SHADOW_BANDS>()); static_assert(shadowBands.front() == 1); static_assert(shadowBands.back() == 10'000'000); @@ -102,30 +102,30 @@ ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, co const auto bandViewExtents = getBandViewExtents(camera, lightViewDir); Definitions out; Sizes sizes; - std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()), - std::back_inserter(out), - [bands = bandViewExtents.size() - 2, &lightViewDir, &sizes](const auto & near, const auto & far) mutable { - const auto extents_minmax - = [extents = std::span {near.begin(), far.end()}](auto && comp, RelativeDistance extra) { - const auto mm = std::minmax_element(extents.begin(), extents.end(), comp); - return std::make_pair(comp.get(*mm.first) - extra, comp.get(*mm.second) + extra); - }; - const std::array extents = {extents_minmax(CompareBy {0}, 0), extents_minmax(CompareBy {1}, 0), - extents_minmax(CompareBy {2}, 10'000)}; - - const auto lightProjection = [](const auto & x, const auto & y, const auto & z) { - return glm::ortho(x.first, x.second, y.first, y.second, -z.second, -z.first); - }(extents[0], extents[1], extents[2]); - - sizes.emplace_back(extents[0].second - extents[0].first, extents[1].second - extents[1].first, - extents[2].second - extents[2].first); + using ExtentsBoundingBox = AxisAlignedBoundingBox<RelativeDistance>; + std::ranges::transform(bandViewExtents | std::views::pairwise, std::back_inserter(out), + [&lightViewDir, &sizes](const auto & band) mutable { + const auto & [near, far] = band; + auto extents = ExtentsBoundingBox::fromPoints(std::span {near.begin(), far.end()}); + extents.min.z -= 10'000.F; + extents.max.z += 10'000.F; + const auto lightProjection = glm::ortho( + extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z); + sizes.emplace_back(extents.max - extents.min); return lightProjection * lightViewDir; }); for (const auto p : std::initializer_list<const ShadowProgram *> { &landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures, &stencilShadowProgram}) { p->setView(out, sizes, lightViewPoint); } - scene.shadows(*this); + ExtentsBoundingBox extents {lightViewPoint, lightViewPoint}; + for (const auto & point : bandViewExtents.back()) { + extents += point; + } + const auto lightProjection + = glm::ortho(extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z); + Frustum frustum {lightViewPoint, lightViewDir, lightProjection}; + scene.shadows(*this, frustum); glCullFace(GL_BACK); |