From c0af8b71552b4130cae701de28dae6341a221b91 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Wed, 10 May 2023 22:38:06 +0800 Subject: [PATCH] Replace point light with sphere area light --- CMakeLists.txt | 1 + src/engine/math/numbers.hpp | 4 + src/engine/render/passes/material-pass.cpp | 88 ++++++++++++++----- src/engine/render/passes/material-pass.hpp | 5 ++ src/engine/scene/light-type.hpp | 8 +- .../{point-light.cpp => sphere-light.cpp} | 2 +- .../{point-light.hpp => sphere-light.hpp} | 35 ++++++-- src/game/game.hpp | 4 +- src/game/states/nest-view-state.cpp | 27 ++++-- src/game/states/nest-view-state.hpp | 4 +- 10 files changed, 134 insertions(+), 44 deletions(-) rename src/engine/scene/{point-light.cpp => sphere-light.cpp} (95%) rename src/engine/scene/{point-light.hpp => sphere-light.hpp} (65%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ca183..73e1a79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.25) + option(APPLICATION_NAME "Application name" "Antkeeper") option(APPLICATION_VERSION "Application version string" "0.0.0") option(APPLICATION_AUTHOR "Application author" "C. J. Howard") diff --git a/src/engine/math/numbers.hpp b/src/engine/math/numbers.hpp index 2cfaa9e..7f94f86 100644 --- a/src/engine/math/numbers.hpp +++ b/src/engine/math/numbers.hpp @@ -68,6 +68,10 @@ inline constexpr T inv_pi = std::numbers::inv_pi_v; template inline constexpr T inv_sqrt_pi = std::numbers::inv_sqrtpi_v; +/// Pi^2. +template +inline constexpr T sqr_pi = std::numbers::pi_v * std::numbers::pi_v; + /// ln(2). template inline constexpr T ln_2 = std::numbers::ln2_v; diff --git a/src/engine/render/passes/material-pass.cpp b/src/engine/render/passes/material-pass.cpp index d8695e9..e5d3274 100644 --- a/src/engine/render/passes/material-pass.cpp +++ b/src/engine/render/passes/material-pass.cpp @@ -40,8 +40,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -315,6 +315,7 @@ void material_pass::evaluate_lighting(const render::context& ctx) directional_light_count = 0; directional_shadow_count = 0; spot_light_count = 0; + sphere_light_count = 0; const auto& lights = ctx.collection->get_objects(scene::light::object_type_id); for (const scene::object_base* object: lights) @@ -340,25 +341,6 @@ void material_pass::evaluate_lighting(const render::context& ctx) break; } - // Add point light - case scene::light_type::point: - { - const scene::point_light& point_light = static_cast(light); - - const std::size_t index = point_light_count; - - ++point_light_count; - if (point_light_count > point_light_colors.size()) - { - point_light_colors.resize(point_light_count); - point_light_positions.resize(point_light_count); - } - - point_light_colors[index] = point_light.get_luminous_flux() * ctx.camera->get_exposure_normalization(); - point_light_positions[index] = point_light.get_translation(); - break; - } - // Add directional light case scene::light_type::directional: { @@ -421,6 +403,49 @@ void material_pass::evaluate_lighting(const render::context& ctx) break; } + // Add sphere light + case scene::light_type::sphere: + { + const scene::sphere_light& sphere_light = static_cast(light); + + if (sphere_light.get_radius() == 0.0f) + { + const std::size_t index = point_light_count; + + ++point_light_count; + if (point_light_count > point_light_colors.size()) + { + point_light_colors.resize(point_light_count); + point_light_positions.resize(point_light_count); + } + + point_light_colors[index] = sphere_light.get_luminous_flux() * ctx.camera->get_exposure_normalization(); + point_light_positions[index] = sphere_light.get_translation(); + } + else + { + const std::size_t index = sphere_light_count; + + ++sphere_light_count; + if (sphere_light_count > sphere_light_colors.size()) + { + sphere_light_colors.resize(sphere_light_count); + sphere_light_positions_radii.resize(sphere_light_count); + } + + sphere_light_colors[index] = sphere_light.get_luminous_flux() * ctx.camera->get_exposure_normalization(); + + const auto& position = sphere_light.get_translation(); + auto& position_radius = sphere_light_positions_radii[index]; + position_radius[0] = position.x(); + position_radius[1] = position.y(); + position_radius[2] = position.z(); + position_radius[3] = sphere_light.get_radius(); + } + + break; + } + default: break; } @@ -432,6 +457,7 @@ void material_pass::evaluate_lighting(const render::context& ctx) lighting_state_hash = hash::combine(lighting_state_hash, std::hash{}(directional_shadow_count)); lighting_state_hash = hash::combine(lighting_state_hash, std::hash{}(point_light_count)); lighting_state_hash = hash::combine(lighting_state_hash, std::hash{}(spot_light_count)); + lighting_state_hash = hash::combine(lighting_state_hash, std::hash{}(sphere_light_count)); } void material_pass::evaluate_misc(const render::context& ctx) @@ -471,6 +497,7 @@ std::unique_ptr material_pass::generate_shader_program(const definitions["DIRECTIONAL_SHADOW_COUNT"] = std::to_string(directional_shadow_count); definitions["POINT_LIGHT_COUNT"] = std::to_string(point_light_count); definitions["SPOT_LIGHT_COUNT"] = std::to_string(spot_light_count); + definitions["SPHERE_LIGHT_COUNT"] = std::to_string(sphere_light_count); auto shader_program = shader_template.build(definitions); @@ -619,6 +646,27 @@ void material_pass::build_shader_command_buffer(std::vectorupdate(std::span{sphere_light_colors.data(), sphere_light_count}); + sphere_light_positions_radii_var->update(std::span{sphere_light_positions_radii.data(), sphere_light_count}); + } + ); + } + } + } + // Update time variable if (auto time_var = shader_program.variable("time")) { diff --git a/src/engine/render/passes/material-pass.hpp b/src/engine/render/passes/material-pass.hpp index 3f6ec02..cdeeda0 100644 --- a/src/engine/render/passes/material-pass.hpp +++ b/src/engine/render/passes/material-pass.hpp @@ -120,6 +120,11 @@ private: std::vector spot_light_cutoffs; std::size_t spot_light_count; + // Sphere lights + std::vector sphere_light_colors; + std::vector sphere_light_positions_radii; + std::size_t sphere_light_count; + // Misc float time; float timestep; diff --git a/src/engine/scene/light-type.hpp b/src/engine/scene/light-type.hpp index 439b483..732c5ca 100644 --- a/src/engine/scene/light-type.hpp +++ b/src/engine/scene/light-type.hpp @@ -33,11 +33,11 @@ enum class light_type: std::uint8_t /// Directional light. directional, - /// Point light. - point, - /// Spot light. - spot + spot, + + /// Sphere light. + sphere }; } // namespace scene diff --git a/src/engine/scene/point-light.cpp b/src/engine/scene/sphere-light.cpp similarity index 95% rename from src/engine/scene/point-light.cpp rename to src/engine/scene/sphere-light.cpp index 62e3046..8fe0d8d 100644 --- a/src/engine/scene/point-light.cpp +++ b/src/engine/scene/sphere-light.cpp @@ -17,7 +17,7 @@ * along with Antkeeper source code. If not, see . */ -#include +#include namespace scene { diff --git a/src/engine/scene/point-light.hpp b/src/engine/scene/sphere-light.hpp similarity index 65% rename from src/engine/scene/point-light.hpp rename to src/engine/scene/sphere-light.hpp index a651619..ec5b063 100644 --- a/src/engine/scene/point-light.hpp +++ b/src/engine/scene/sphere-light.hpp @@ -17,8 +17,8 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_SCENE_POINT_LIGHT_HPP -#define ANTKEEPER_SCENE_POINT_LIGHT_HPP +#ifndef ANTKEEPER_SCENE_SPHERE_LIGHT_HPP +#define ANTKEEPER_SCENE_SPHERE_LIGHT_HPP #include #include @@ -26,19 +26,19 @@ namespace scene { /** - * Light source that radiates outward from a point. + * Light source that radiates outward from a sphere. */ -class point_light: public light +class sphere_light: public light { public: - /// Returns light_type::point + /// Returns light_type::sphere. [[nodiscard]] inline light_type get_light_type() const noexcept override { - return light_type::point; + return light_type::sphere; } /** - * Sets the luminous flux of the point light. + * Sets the luminous flux of the sphere light. * * @param luminous_flux Luminous flux, in *lm*. */ @@ -47,16 +47,33 @@ public: m_luminous_flux = luminous_flux; } - /// Returns the luminous flux of the point light, in *lm*. + /** + * Sets the radius of the sphere light. + * + * @param radius Radius of the sphere light. + */ + inline void set_radius(float radius) noexcept + { + m_radius = radius; + } + + /// Returns the luminous flux of the sphere light, in *lm*. [[nodiscard]] inline const math::vector& get_luminous_flux() const noexcept { return m_luminous_flux; } + + /// Returns the radius of the sphere light. + [[nodiscard]] inline float get_radius() const noexcept + { + return m_radius; + } private: math::vector m_luminous_flux{0.0f, 0.0f, 0.0f}; + float m_radius{0.0f}; }; } // namespace scene -#endif // ANTKEEPER_SCENE_POINT_LIGHT_HPP +#endif // ANTKEEPER_SCENE_SPHERE_LIGHT_HPP diff --git a/src/game/game.hpp b/src/game/game.hpp index e71bbe4..6874b8e 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include #include @@ -338,7 +338,7 @@ public: std::shared_ptr underground_camera; std::unique_ptr underground_directional_light; std::unique_ptr underground_ambient_light; - std::unique_ptr underground_point_light; + std::unique_ptr underground_sphere_light; scene::collection* active_scene; // Animation diff --git a/src/game/states/nest-view-state.cpp b/src/game/states/nest-view-state.cpp index 31fc69a..175752b 100644 --- a/src/game/states/nest-view-state.cpp +++ b/src/game/states/nest-view-state.cpp @@ -75,6 +75,7 @@ #include #include #include +#include #include #include @@ -122,14 +123,15 @@ nest_view_state::nest_view_state(::game& ctx): // Create ambient light ctx.underground_ambient_light = std::make_unique(); - ctx.underground_ambient_light->set_illuminance(float3{1.0f, 1.0f, 1.0f} * 0.025f); + ctx.underground_ambient_light->set_illuminance(float3{1.0f, 1.0f, 1.0f} * 0.075f); ctx.underground_scene->add_object(*ctx.underground_ambient_light); - // Create point light - ctx.underground_point_light = std::make_unique(); - ctx.underground_point_light->set_luminous_flux(float3{1.0f, 1.0f, 1.0f} * 200.0f); - ctx.underground_point_light->set_translation(float3{-13.0f, 7.0f, -6.0f}); - ctx.underground_scene->add_object(*ctx.underground_point_light); + // Create sphere light + ctx.underground_sphere_light = std::make_unique(); + ctx.underground_sphere_light->set_luminous_flux(float3{0.8f, 0.88f, 1.0f} * 250.0f); + ctx.underground_sphere_light->set_radius(3.0f); + ctx.underground_sphere_light->set_translation(float3{-13.0f, 7.0f, -6.0f}); + ctx.underground_scene->add_object(*ctx.underground_sphere_light); // Create chamber auto chamber_eid = ctx.entity_registry->create(); @@ -165,6 +167,19 @@ nest_view_state::nest_view_state(::game& ctx): } ); + // Create suzanne + auto suzanne_eid = ctx.entity_registry->create(); + auto suzanne_static_mesh = std::make_shared(ctx.resource_manager->load("suzanne.mdl")); + ctx.entity_registry->emplace(suzanne_eid, std::move(suzanne_static_mesh), std::uint8_t{2}); + ctx.entity_registry->patch + ( + suzanne_eid, + [&](auto& component) + { + component.object->set_translation({-13.0f, -1.0f, -6.0f}); + } + ); + // Disable UI color clear ctx.ui_clear_pass->set_cleared_buffers(false, true, false); diff --git a/src/game/states/nest-view-state.hpp b/src/game/states/nest-view-state.hpp index df51bf6..d13bf97 100644 --- a/src/game/states/nest-view-state.hpp +++ b/src/game/states/nest-view-state.hpp @@ -79,8 +79,8 @@ private: double third_person_camera_near_focal_plane_height{2.0f}; double third_person_camera_far_focal_plane_height{50.0f}; - double third_person_camera_near_hfov{math::radians(45.0)}; - double third_person_camera_far_hfov{math::radians(90.0)}; + double third_person_camera_near_hfov{math::radians(90.0)}; + double third_person_camera_far_hfov{math::radians(45.0)}; /// In focal plane heights per second. double third_person_camera_speed{1.0f};