Start basic shadowmap stuff
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
// Created by kj16609 on 7/23/24.
|
// Created by kj16609 on 7/23/24.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "engine/camera/Camera.hpp"
|
#include "engine/camera/RenderCamera.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
namespace fgl::engine::gui
|
namespace fgl::engine::gui
|
||||||
{
|
{
|
||||||
|
|
||||||
void handleCameraInput( const FrameInfo& info, Camera& camera )
|
void handleCameraInput( const FrameInfo& info, RenderCamera& camera )
|
||||||
{
|
{
|
||||||
const auto delta_time { info.delta_time };
|
const auto delta_time { info.delta_time };
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ namespace fgl::engine::gui
|
|||||||
|
|
||||||
assert( camera_ptr );
|
assert( camera_ptr );
|
||||||
|
|
||||||
Camera& camera { *camera_ptr };
|
RenderCamera& camera { *camera_ptr };
|
||||||
|
|
||||||
std::string name {};
|
std::string name {};
|
||||||
|
|
||||||
@@ -31,6 +31,8 @@ namespace fgl::engine::gui
|
|||||||
void drawComponentsList( GameObject& game_object );
|
void drawComponentsList( GameObject& game_object );
|
||||||
void drawSelectedComponent();
|
void drawSelectedComponent();
|
||||||
|
|
||||||
|
void drawShadowmaps( const FrameInfo& info );
|
||||||
|
|
||||||
void drawCameraOutputs( FrameInfo& info );
|
void drawCameraOutputs( FrameInfo& info );
|
||||||
|
|
||||||
void drawStats( const FrameInfo& info );
|
void drawStats( const FrameInfo& info );
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
#include "assets/transfer/TransferManager.hpp"
|
#include "assets/transfer/TransferManager.hpp"
|
||||||
|
#include "camera/CameraManager.hpp"
|
||||||
|
#include "camera/ShadowMap.hpp"
|
||||||
#include "core.hpp"
|
#include "core.hpp"
|
||||||
#include "engine/debug/profiling/counters.hpp"
|
#include "engine/debug/profiling/counters.hpp"
|
||||||
#include "engine/debug/timing/FlameGraph.hpp"
|
#include "engine/debug/timing/FlameGraph.hpp"
|
||||||
#include "engine/flags.hpp"
|
#include "engine/flags.hpp"
|
||||||
#include "engine/math/literals/size.hpp"
|
#include "engine/math/literals/size.hpp"
|
||||||
#include "engine/memory/buffers/BufferHandle.hpp"
|
#include "engine/memory/buffers/BufferHandle.hpp"
|
||||||
#include "memory/buffers/BufferHandle.hpp"
|
|
||||||
#include "safe_include.hpp"
|
#include "safe_include.hpp"
|
||||||
|
|
||||||
namespace fgl::engine::gui
|
namespace fgl::engine::gui
|
||||||
@@ -123,6 +124,38 @@ namespace fgl::engine::gui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawShadowmaps( const FrameInfo& info )
|
||||||
|
{
|
||||||
|
ImGui::Begin( "Shadowmaps" );
|
||||||
|
|
||||||
|
static std::unordered_map< int*, std::vector< Texture > > textures {};
|
||||||
|
|
||||||
|
bool move_sun { false };
|
||||||
|
|
||||||
|
move_sun = ImGui::Button( "Move sun shadowmap to camera" );
|
||||||
|
|
||||||
|
for ( const auto& weak_shadowmap : getShadowmaps() )
|
||||||
|
{
|
||||||
|
if ( weak_shadowmap.expired() ) continue;
|
||||||
|
|
||||||
|
auto shadowmap_ptr { weak_shadowmap.lock() };
|
||||||
|
|
||||||
|
ShadowMap& shadowmap { *shadowmap_ptr };
|
||||||
|
|
||||||
|
// if ( move_sun )
|
||||||
|
{
|
||||||
|
shadowmap.m_camera->moveTo( CameraManager::instance().getPrimary()->getTransform() );
|
||||||
|
}
|
||||||
|
|
||||||
|
const FrameIndex frame_index { info.in_flight_idx };
|
||||||
|
// camera.getCompositeSwapchain().m_gbuffer_target[ frame_index ]->drawImGui( target_size );
|
||||||
|
|
||||||
|
shadowmap.m_swapchain->depthTexture( frame_index )->drawImGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
void drawStats( const FrameInfo& info )
|
void drawStats( const FrameInfo& info )
|
||||||
{
|
{
|
||||||
ImGui::Begin( "Stats" );
|
ImGui::Begin( "Stats" );
|
||||||
@@ -143,6 +176,11 @@ namespace fgl::engine::gui
|
|||||||
debug::timing::render();
|
debug::timing::render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ImGui::CollapsingHeader( "Shadowmaps" ) )
|
||||||
|
{
|
||||||
|
drawShadowmaps( info );
|
||||||
|
}
|
||||||
|
|
||||||
if ( ImGui::Button( "Reload shaders" ) )
|
if ( ImGui::Button( "Reload shaders" ) )
|
||||||
{
|
{
|
||||||
flags::triggerShaderReload();
|
flags::triggerShaderReload();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "engine/FrameInfo.hpp"
|
#include "engine/FrameInfo.hpp"
|
||||||
#include "engine/assets/model/Model.hpp"
|
#include "engine/assets/model/Model.hpp"
|
||||||
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
||||||
#include "engine/camera/Camera.hpp"
|
#include "engine/camera/RenderCamera.hpp"
|
||||||
#include "engine/filesystem/scanner/FileScanner.hpp"
|
#include "engine/filesystem/scanner/FileScanner.hpp"
|
||||||
#include "engine/filesystem/types.hpp"
|
#include "engine/filesystem/types.hpp"
|
||||||
#include "engine/rendering/PresentSwapChain.hpp"
|
#include "engine/rendering/PresentSwapChain.hpp"
|
||||||
@@ -126,7 +126,7 @@ namespace fgl::engine::gui
|
|||||||
|
|
||||||
inline void drawConfigBar(
|
inline void drawConfigBar(
|
||||||
[[maybe_unused]] const FrameInfo& info,
|
[[maybe_unused]] const FrameInfo& info,
|
||||||
[[maybe_unused]] const Camera& camera,
|
[[maybe_unused]] const RenderCamera& camera,
|
||||||
[[maybe_unused]] const FrameIndex frame_index,
|
[[maybe_unused]] const FrameIndex frame_index,
|
||||||
std::uint_fast8_t& current )
|
std::uint_fast8_t& current )
|
||||||
{
|
{
|
||||||
@@ -167,7 +167,7 @@ namespace fgl::engine::gui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawRenderingOutputs( FrameInfo& info, const Camera& camera )
|
void drawRenderingOutputs( FrameInfo& info, const RenderCamera& camera )
|
||||||
{
|
{
|
||||||
ZoneScoped;
|
ZoneScoped;
|
||||||
const auto frame_index { info.in_flight_idx };
|
const auto frame_index { info.in_flight_idx };
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
struct FrameInfo;
|
struct FrameInfo;
|
||||||
class Camera;
|
class RenderCamera;
|
||||||
} // namespace fgl::engine
|
} // namespace fgl::engine
|
||||||
|
|
||||||
namespace fgl::engine::gui
|
namespace fgl::engine::gui
|
||||||
{
|
{
|
||||||
|
|
||||||
void drawRenderingOutputs( FrameInfo& info, const Camera& camera );
|
void drawRenderingOutputs( FrameInfo& info, const RenderCamera& camera );
|
||||||
|
|
||||||
} // namespace fgl::engine::gui
|
} // namespace fgl::engine::gui
|
||||||
|
|||||||
@@ -11,9 +11,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "KeyboardMovementController.hpp"
|
#include "KeyboardMovementController.hpp"
|
||||||
#include "camera/Camera.hpp"
|
|
||||||
#include "camera/CameraManager.hpp"
|
#include "camera/CameraManager.hpp"
|
||||||
#include "camera/GBufferRenderer.hpp"
|
#include "camera/GBufferRenderer.hpp"
|
||||||
|
#include "camera/RenderCamera.hpp"
|
||||||
|
#include "camera/ShadowMap.hpp"
|
||||||
#include "debug/timing/FlameGraph.hpp"
|
#include "debug/timing/FlameGraph.hpp"
|
||||||
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
||||||
#include "engine/assets/transfer/TransferManager.hpp"
|
#include "engine/assets/transfer/TransferManager.hpp"
|
||||||
@@ -27,49 +28,20 @@ namespace fgl::engine
|
|||||||
constexpr float MAX_DELTA_TIME { 0.5 };
|
constexpr float MAX_DELTA_TIME { 0.5 };
|
||||||
inline static EngineContext* instance { nullptr };
|
inline static EngineContext* instance { nullptr };
|
||||||
|
|
||||||
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createDrawCommandsDescriptors(
|
|
||||||
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > >& gpu_draw_commands,
|
|
||||||
PerFrameArray< DeviceVector< InstanceRenderInfo > >& per_vertex_info )
|
|
||||||
{
|
|
||||||
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > descriptors {};
|
|
||||||
|
|
||||||
for ( std::uint16_t i = 0; i < gpu_draw_commands.size(); ++i )
|
|
||||||
{
|
|
||||||
auto& command_buffer { gpu_draw_commands[ i ] };
|
|
||||||
auto& per_vertex_buffer { per_vertex_info[ i ] };
|
|
||||||
auto descriptor { COMMANDS_SET.create() };
|
|
||||||
|
|
||||||
descriptor->bindStorageBuffer( 0, command_buffer );
|
|
||||||
descriptor->bindStorageBuffer( 1, per_vertex_buffer );
|
|
||||||
descriptor->update();
|
|
||||||
descriptor->setName( "Command Buffer + Vertex Buffer" );
|
|
||||||
|
|
||||||
descriptors[ i ] = std::move( descriptor );
|
|
||||||
}
|
|
||||||
|
|
||||||
return descriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
EngineContext::EngineContext() :
|
EngineContext::EngineContext() :
|
||||||
m_ubo_buffer_pool( 1_MiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ),
|
m_ubo_buffer_pool( 1_MiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible ),
|
||||||
m_draw_parameter_pool(
|
m_delta_time( 0.0 ),
|
||||||
4_MiB,
|
m_camera_manager()
|
||||||
vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eStorageBuffer,
|
|
||||||
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
|
|
||||||
m_gpu_draw_commands(
|
|
||||||
constructPerFrame< DeviceVector< vk::DrawIndexedIndirectCommand > >( m_draw_parameter_pool ) ),
|
|
||||||
m_per_vertex_infos( m_model_buffers.m_generated_instance_info ),
|
|
||||||
m_gpu_draw_cmds_desc( createDrawCommandsDescriptors( m_gpu_draw_commands, m_per_vertex_infos ) ),
|
|
||||||
m_delta_time( 0.0 )
|
|
||||||
{
|
{
|
||||||
ZoneScoped;
|
ZoneScoped;
|
||||||
using namespace fgl::literals::size_literals;
|
using namespace fgl::literals::size_literals;
|
||||||
|
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
// memory::TransferManager::createInstance( device, 128_MiB );
|
m_camera_manager.createPrimary();
|
||||||
|
m_sun = std::make_unique< Sun >();
|
||||||
|
|
||||||
m_draw_parameter_pool->setDebugName( "Draw parameter pool" );
|
// memory::TransferManager::createInstance( device, 128_MiB );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Average< float, 60 * 15 > rolling_ms_average;
|
static Average< float, 60 * 15 > rolling_ms_average;
|
||||||
@@ -116,10 +88,19 @@ namespace fgl::engine
|
|||||||
|
|
||||||
auto sh_camera { current_camera_ptr.lock() };
|
auto sh_camera { current_camera_ptr.lock() };
|
||||||
|
|
||||||
Camera& current_camera { *sh_camera };
|
RenderCamera& current_camera { *sh_camera };
|
||||||
|
|
||||||
current_camera.pass( frame_info );
|
current_camera.pass( frame_info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( auto& shadow_map : getShadowmaps() )
|
||||||
|
{
|
||||||
|
if ( shadow_map.expired() ) continue;
|
||||||
|
|
||||||
|
auto shadowmap { shadow_map.lock() };
|
||||||
|
|
||||||
|
shadowmap->pass( frame_info );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineContext::renderFrame()
|
void EngineContext::renderFrame()
|
||||||
@@ -136,9 +117,6 @@ namespace fgl::engine
|
|||||||
// Begin by getting every single instance ready.
|
// Begin by getting every single instance ready.
|
||||||
DeviceVector< PrimitiveInstanceInfo >& instances { m_model_buffers.m_primitive_instances.vec() };
|
DeviceVector< PrimitiveInstanceInfo >& instances { m_model_buffers.m_primitive_instances.vec() };
|
||||||
|
|
||||||
m_gpu_draw_commands[ in_flight_idx ].resize( instances.size() );
|
|
||||||
m_model_buffers.m_generated_instance_info[ in_flight_idx ].resize( instances.size() );
|
|
||||||
|
|
||||||
FrameInfo frame_info { in_flight_idx,
|
FrameInfo frame_info { in_flight_idx,
|
||||||
present_idx,
|
present_idx,
|
||||||
m_delta_time,
|
m_delta_time,
|
||||||
@@ -148,8 +126,9 @@ namespace fgl::engine
|
|||||||
m_renderer.getCurrentTracyCTX(),
|
m_renderer.getCurrentTracyCTX(),
|
||||||
*m_model_buffers.m_primitives_desc,
|
*m_model_buffers.m_primitives_desc,
|
||||||
*m_model_buffers.m_instances_desc,
|
*m_model_buffers.m_instances_desc,
|
||||||
*m_gpu_draw_cmds_desc[ in_flight_idx ],
|
instances,
|
||||||
m_gpu_draw_commands[ in_flight_idx ],
|
// *m_gpu_draw_cmds_desc[ in_flight_idx ],
|
||||||
|
// m_gpu_draw_commands[ in_flight_idx ],
|
||||||
m_game_objects,
|
m_game_objects,
|
||||||
this->m_renderer.getSwapChain() };
|
this->m_renderer.getSwapChain() };
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "engine/assets/transfer/TransferManager.hpp"
|
#include "engine/assets/transfer/TransferManager.hpp"
|
||||||
#include "engine/math/literals/size.hpp"
|
#include "engine/math/literals/size.hpp"
|
||||||
#include "engine/rendering/Renderer.hpp"
|
#include "engine/rendering/Renderer.hpp"
|
||||||
|
#include "lighting/lights/Sun.hpp"
|
||||||
#include "scene/World.hpp"
|
#include "scene/World.hpp"
|
||||||
#include "systems/composition/GuiSystem.hpp"
|
#include "systems/composition/GuiSystem.hpp"
|
||||||
|
|
||||||
@@ -67,9 +68,6 @@ namespace fgl::engine
|
|||||||
// Memory pool for shader uniforms.
|
// Memory pool for shader uniforms.
|
||||||
memory::Buffer m_ubo_buffer_pool;
|
memory::Buffer m_ubo_buffer_pool;
|
||||||
|
|
||||||
// Memory pool for matrix info and draw parameters
|
|
||||||
memory::Buffer m_draw_parameter_pool;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::vector< std::shared_ptr< GameObject > > m_game_objects {};
|
std::vector< std::shared_ptr< GameObject > > m_game_objects {};
|
||||||
@@ -78,22 +76,18 @@ namespace fgl::engine
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > > m_gpu_draw_commands;
|
|
||||||
//TODO: Outright remove this. Or the one in model buffers.
|
|
||||||
PerFrameArray< DeviceVector< InstanceRenderInfo > >& m_per_vertex_infos;
|
|
||||||
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_gpu_draw_cmds_desc;
|
|
||||||
|
|
||||||
MaterialManager m_material_manager {};
|
MaterialManager m_material_manager {};
|
||||||
|
|
||||||
CameraManager m_camera_manager {};
|
|
||||||
|
|
||||||
memory::TransferManager m_transfer_manager { m_device, 512_MiB };
|
memory::TransferManager m_transfer_manager { m_device, 512_MiB };
|
||||||
|
|
||||||
std::chrono::time_point< Clock > m_last_tick { Clock::now() };
|
std::chrono::time_point< Clock > m_last_tick { Clock::now() };
|
||||||
DeltaTime m_delta_time;
|
DeltaTime m_delta_time;
|
||||||
|
|
||||||
|
CameraManager m_camera_manager {};
|
||||||
// World m_world;
|
// World m_world;
|
||||||
|
|
||||||
|
std::unique_ptr< Sun > m_sun;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// ModelManager& models() { return m_model_manager; }
|
// ModelManager& models() { return m_model_manager; }
|
||||||
|
|||||||
@@ -4,20 +4,21 @@
|
|||||||
|
|
||||||
#include "FrameInfo.hpp"
|
#include "FrameInfo.hpp"
|
||||||
|
|
||||||
#include "camera/Camera.hpp"
|
|
||||||
#include "camera/GBufferSwapchain.hpp"
|
#include "camera/GBufferSwapchain.hpp"
|
||||||
|
#include "camera/RenderCamera.hpp"
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|
||||||
descriptors::DescriptorSet& FrameInfo::getGBufferDescriptor() const
|
// descriptors::DescriptorSet& FrameInfo::getGBufferDescriptor() const
|
||||||
{
|
// {
|
||||||
return camera->getSwapchain().getGBufferDescriptor( in_flight_idx );
|
// return camera->getSwapchain().getGBufferDescriptor( in_flight_idx );
|
||||||
}
|
// }
|
||||||
|
|
||||||
descriptors::DescriptorSet& FrameInfo::getCameraDescriptor() const
|
descriptors::DescriptorSet& FrameInfo::getCameraDescriptor() const
|
||||||
{
|
{
|
||||||
return camera->getDescriptor( in_flight_idx );
|
FGL_ASSERT( camera != nullptr, "Camera not set" );
|
||||||
|
return *camera->m_camera_info_descriptors[ in_flight_idx ];
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameInfo::bindCamera( [[maybe_unused]] Pipeline& pipeline )
|
void FrameInfo::bindCamera( [[maybe_unused]] Pipeline& pipeline )
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
class CameraViewpoint;
|
||||||
struct PrimitiveRenderInfo;
|
struct PrimitiveRenderInfo;
|
||||||
struct PrimitiveInstanceInfo;
|
struct PrimitiveInstanceInfo;
|
||||||
class Pipeline;
|
class Pipeline;
|
||||||
@@ -31,7 +32,7 @@ namespace fgl::engine
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PresentSwapChain;
|
class PresentSwapChain;
|
||||||
class Camera;
|
class RenderCamera;
|
||||||
|
|
||||||
struct PointLight
|
struct PointLight
|
||||||
{
|
{
|
||||||
@@ -81,9 +82,9 @@ namespace fgl::engine
|
|||||||
|
|
||||||
CommandBuffers& command_buffer;
|
CommandBuffers& command_buffer;
|
||||||
|
|
||||||
Camera* camera { nullptr };
|
CameraViewpoint* camera { nullptr };
|
||||||
|
|
||||||
std::vector< std::weak_ptr< Camera > >& m_camera_list;
|
std::vector< std::weak_ptr< RenderCamera > >& m_camera_list;
|
||||||
|
|
||||||
// descriptors::DescriptorSet& global_descriptor_set;
|
// descriptors::DescriptorSet& global_descriptor_set;
|
||||||
// OctTreeNode& game_objects;
|
// OctTreeNode& game_objects;
|
||||||
@@ -91,16 +92,17 @@ namespace fgl::engine
|
|||||||
|
|
||||||
descriptors::DescriptorSet& m_primitives_desc;
|
descriptors::DescriptorSet& m_primitives_desc;
|
||||||
descriptors::DescriptorSet& m_instances_desc;
|
descriptors::DescriptorSet& m_instances_desc;
|
||||||
descriptors::DescriptorSet& m_command_buffer_desc;
|
DeviceVector< PrimitiveInstanceInfo >& instances;
|
||||||
|
// descriptors::DescriptorSet& m_command_buffer_desc;
|
||||||
// out for rendering process
|
// out for rendering process
|
||||||
|
|
||||||
//! Populated commands buffer by the culling pass
|
//! Populated commands buffer by the culling pass
|
||||||
DeviceVector< vk::DrawIndexedIndirectCommand >& m_commands;
|
// DeviceVector< vk::DrawIndexedIndirectCommand >& m_commands;
|
||||||
std::vector< std::shared_ptr< GameObject > >& m_game_objects;
|
std::vector< std::shared_ptr< GameObject > >& m_game_objects;
|
||||||
|
|
||||||
// descriptors::DescriptorSet& gui_input_descriptor;
|
// descriptors::DescriptorSet& gui_input_descriptor;
|
||||||
|
|
||||||
[[nodiscard]] descriptors::DescriptorSet& getGBufferDescriptor() const;
|
// [[nodiscard]] descriptors::DescriptorSet& getGBufferDescriptor() const;
|
||||||
[[nodiscard]] descriptors::DescriptorSet& getCameraDescriptor() const;
|
[[nodiscard]] descriptors::DescriptorSet& getCameraDescriptor() const;
|
||||||
|
|
||||||
PresentSwapChain& swap_chain;
|
PresentSwapChain& swap_chain;
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ namespace fgl::engine
|
|||||||
1_GiB,
|
1_GiB,
|
||||||
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst,
|
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst,
|
||||||
vk::MemoryPropertyFlagBits::eDeviceLocal ),
|
vk::MemoryPropertyFlagBits::eDeviceLocal ),
|
||||||
m_generated_instance_info( constructPerFrame< DeviceVector< InstanceRenderInfo > >( m_vertex_buffer ) ),
|
|
||||||
m_primitive_info( m_long_buffer ),
|
m_primitive_info( m_long_buffer ),
|
||||||
m_primitive_instances( m_short_buffer ),
|
m_primitive_instances( m_short_buffer ),
|
||||||
m_model_instances( m_short_buffer )
|
m_model_instances( m_short_buffer )
|
||||||
|
|||||||
@@ -104,9 +104,6 @@ namespace fgl::engine
|
|||||||
memory::Buffer m_vertex_buffer;
|
memory::Buffer m_vertex_buffer;
|
||||||
memory::Buffer m_index_buffer;
|
memory::Buffer m_index_buffer;
|
||||||
|
|
||||||
//! Generated by the compute shader, This vector contains the instance info for each primitive.
|
|
||||||
PerFrameArray< DeviceVector< InstanceRenderInfo > > m_generated_instance_info;
|
|
||||||
|
|
||||||
//! contains the core primitive info, like vertex and index offsets and counts
|
//! contains the core primitive info, like vertex and index offsets and counts
|
||||||
IndexedVector< PrimitiveRenderInfo > m_primitive_info;
|
IndexedVector< PrimitiveRenderInfo > m_primitive_info;
|
||||||
//! contains a list of all rendered primitives
|
//! contains a list of all rendered primitives
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "assets/model/ModelVertex.hpp"
|
#include "assets/model/ModelVertex.hpp"
|
||||||
#include "engine/assets/stores.hpp"
|
#include "engine/assets/stores.hpp"
|
||||||
#include "engine/camera/Camera.hpp"
|
#include "engine/camera/RenderCamera.hpp"
|
||||||
#include "engine/debug/logging/logging.hpp"
|
#include "engine/debug/logging/logging.hpp"
|
||||||
#include "engine/descriptors/DescriptorSet.hpp"
|
#include "engine/descriptors/DescriptorSet.hpp"
|
||||||
#include "engine/gameobjects/GameObject.hpp"
|
#include "engine/gameobjects/GameObject.hpp"
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/mat4x4.hpp>
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#include "CameraManager.hpp"
|
#include "CameraManager.hpp"
|
||||||
|
|
||||||
#include "Camera.hpp"
|
|
||||||
#include "GBufferRenderer.hpp"
|
#include "GBufferRenderer.hpp"
|
||||||
|
#include "RenderCamera.hpp"
|
||||||
#include "engine/debug/DEBUG_NAMES.hpp"
|
#include "engine/debug/DEBUG_NAMES.hpp"
|
||||||
#include "engine/math/literals/size.hpp"
|
#include "engine/math/literals/size.hpp"
|
||||||
|
|
||||||
@@ -14,35 +14,64 @@ namespace fgl::engine
|
|||||||
|
|
||||||
using namespace fgl::literals::size_literals;
|
using namespace fgl::literals::size_literals;
|
||||||
|
|
||||||
std::vector< std::weak_ptr< Camera > >& CameraManager::getCameras()
|
inline static CameraManager* camera_manager_instance { nullptr };
|
||||||
{
|
|
||||||
return cameras;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr< Camera >& CameraManager::getPrimary()
|
|
||||||
{
|
|
||||||
return m_primary_camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraManager::CameraManager() :
|
CameraManager::CameraManager() :
|
||||||
m_renderer( std::make_shared< GBufferRenderer >() ),
|
m_renderer( std::make_shared< GBufferRenderer >() ),
|
||||||
m_data_buffer( 4_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible )
|
m_data_buffer( 4_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible )
|
||||||
{
|
{
|
||||||
m_primary_camera = createCamera( { 1920, 1080 } );
|
FGL_ASSERT( camera_manager_instance == nullptr, "CameraManager already initialized" );
|
||||||
m_primary_camera->setName( CAMERA_EDITOR_NAME );
|
camera_manager_instance = this;
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr< Camera > CameraManager::createCamera( const vk::Extent2D extent )
|
m_data_buffer->setDebugName( "Camera data buffer" );
|
||||||
{
|
|
||||||
std::shared_ptr< Camera > camera { new Camera( extent, m_data_buffer, m_renderer ) };
|
|
||||||
|
|
||||||
this->cameras.emplace_back( camera );
|
|
||||||
|
|
||||||
return camera;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraManager::~CameraManager()
|
CameraManager::~CameraManager()
|
||||||
{
|
{
|
||||||
m_primary_camera.reset();
|
m_primary_camera.reset();
|
||||||
|
camera_manager_instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::weak_ptr< RenderCamera > >& CameraManager::getCameras()
|
||||||
|
{
|
||||||
|
return cameras;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< RenderCamera >& CameraManager::getPrimary()
|
||||||
|
{
|
||||||
|
return m_primary_camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraManager::createPrimary()
|
||||||
|
{
|
||||||
|
m_primary_camera = createCamera( { 1920, 1080 } );
|
||||||
|
m_primary_camera->setName( CAMERA_EDITOR_NAME );
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraManager& CameraManager::instance()
|
||||||
|
{
|
||||||
|
FGL_ASSERT( camera_manager_instance, "CameraManager not initialized" );
|
||||||
|
return *camera_manager_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< RenderCamera > CameraManager::createCamera( const vk::Extent2D extent )
|
||||||
|
{
|
||||||
|
auto& instance = CameraManager::instance();
|
||||||
|
|
||||||
|
std::shared_ptr< RenderCamera > camera {
|
||||||
|
new RenderCamera( extent, instance.m_data_buffer, instance.m_renderer )
|
||||||
|
};
|
||||||
|
|
||||||
|
instance.cameras.emplace_back( camera );
|
||||||
|
|
||||||
|
return camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< CameraViewpoint > CameraManager::createViewpoint( const vk::Extent2D extent )
|
||||||
|
{
|
||||||
|
auto& instance = CameraManager::instance();
|
||||||
|
std::shared_ptr< CameraViewpoint > camera_viewpoint { new CameraViewpoint( instance.m_data_buffer, extent ) };
|
||||||
|
|
||||||
|
return camera_viewpoint;
|
||||||
}
|
}
|
||||||
} // namespace fgl::engine
|
} // namespace fgl::engine
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Camera.hpp"
|
#include "RenderCamera.hpp"
|
||||||
#include "engine/memory/buffers/BufferHandle.hpp"
|
#include "engine/memory/buffers/BufferHandle.hpp"
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
@@ -20,20 +20,23 @@ namespace fgl::engine
|
|||||||
std::shared_ptr< GBufferRenderer > m_renderer;
|
std::shared_ptr< GBufferRenderer > m_renderer;
|
||||||
memory::Buffer m_data_buffer;
|
memory::Buffer m_data_buffer;
|
||||||
|
|
||||||
std::shared_ptr< Camera > m_primary_camera { nullptr };
|
std::shared_ptr< RenderCamera > m_primary_camera { nullptr };
|
||||||
|
|
||||||
std::vector< std::weak_ptr< Camera > > cameras {};
|
std::vector< std::weak_ptr< RenderCamera > > cameras {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CameraManager();
|
CameraManager();
|
||||||
~CameraManager();
|
~CameraManager();
|
||||||
|
|
||||||
std::vector< std::weak_ptr< Camera > >& getCameras();
|
std::vector< std::weak_ptr< RenderCamera > >& getCameras();
|
||||||
|
|
||||||
std::shared_ptr< Camera >& getPrimary();
|
std::shared_ptr< RenderCamera >& getPrimary();
|
||||||
|
void createPrimary();
|
||||||
|
|
||||||
std::shared_ptr< Camera > createCamera( vk::Extent2D extent );
|
static CameraManager& instance();
|
||||||
|
static std::shared_ptr< RenderCamera > createCamera( vk::Extent2D extent );
|
||||||
|
static std::shared_ptr< CameraViewpoint > createViewpoint( vk::Extent2D extent );
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fgl::engine
|
} // namespace fgl::engine
|
||||||
240
src/engine/camera/CameraViewpoint.cpp
Normal file
240
src/engine/camera/CameraViewpoint.cpp
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#include "CameraViewpoint.hpp"
|
||||||
|
|
||||||
|
#include "CameraInfo.hpp"
|
||||||
|
#include "RenderCamera.hpp"
|
||||||
|
#include "assets/model/Model.hpp"
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
|
||||||
|
void CameraViewpoint::updateMatrix()
|
||||||
|
{
|
||||||
|
const auto& [ pos, scale, rotation ] = m_transform;
|
||||||
|
|
||||||
|
const auto rotation_matrix { rotation.forcedQuat().mat() };
|
||||||
|
|
||||||
|
const glm::vec3 forward { rotation_matrix * glm::vec4( constants::WORLD_FORWARD, 0.0f ) };
|
||||||
|
|
||||||
|
const glm::vec3 camera_up { rotation_matrix * glm::vec4( -constants::WORLD_Z, 0.0f ) };
|
||||||
|
|
||||||
|
const WorldCoordinate center_pos { pos + forward };
|
||||||
|
|
||||||
|
m_view_matrix = Matrix< MatrixType::WorldToCamera >( glm::lookAt( pos.vec(), center_pos.vec(), camera_up ) );
|
||||||
|
|
||||||
|
m_inverse_view_matrix = glm::inverse( m_view_matrix );
|
||||||
|
|
||||||
|
updateFrustum();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::updateFrustum()
|
||||||
|
{
|
||||||
|
m_last_frustum_pos = getPosition();
|
||||||
|
|
||||||
|
const Matrix< MatrixType::ModelToWorld > translation_matrix { frustumTranslationMatrix() };
|
||||||
|
|
||||||
|
m_frustum = translation_matrix * m_base_frustum;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr descriptors::Descriptor camera_descriptor { 0,
|
||||||
|
vk::DescriptorType::eUniformBuffer,
|
||||||
|
vk::ShaderStageFlagBits::eAllGraphics };
|
||||||
|
|
||||||
|
inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor };
|
||||||
|
|
||||||
|
memory::BufferSuballocation& CameraViewpoint::frameInfo( const FrameIndex i )
|
||||||
|
{
|
||||||
|
return m_camera_frame_info[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::unique_ptr< descriptors::DescriptorSet > > CameraViewpoint::createCameraDescriptors()
|
||||||
|
{
|
||||||
|
std::vector< std::unique_ptr< descriptors::DescriptorSet > > sets {};
|
||||||
|
sets.reserve( constants::MAX_FRAMES_IN_FLIGHT );
|
||||||
|
|
||||||
|
for ( std::uint8_t i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||||
|
{
|
||||||
|
auto set { camera_descriptor_set.create() };
|
||||||
|
set->bindUniformBuffer( 0, m_camera_frame_info[ i ] );
|
||||||
|
set->update();
|
||||||
|
set->setName( std::format( "Viewpoint {} descriptor set {}", m_viewpoint_idx, i ) );
|
||||||
|
|
||||||
|
sets.emplace_back( std::move( set ) );
|
||||||
|
}
|
||||||
|
return sets;
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace fgl::literals::size_literals;
|
||||||
|
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createDrawCommandsDescriptors(
|
||||||
|
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > >& gpu_draw_commands,
|
||||||
|
PerFrameArray< DeviceVector< InstanceRenderInfo > >& per_vertex_info )
|
||||||
|
{
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > descriptors {};
|
||||||
|
|
||||||
|
for ( std::uint16_t i = 0; i < gpu_draw_commands.size(); ++i )
|
||||||
|
{
|
||||||
|
auto& command_buffer { gpu_draw_commands[ i ] };
|
||||||
|
auto& per_vertex_buffer { per_vertex_info[ i ] };
|
||||||
|
auto descriptor { COMMANDS_SET.create() };
|
||||||
|
|
||||||
|
descriptor->bindStorageBuffer( 0, command_buffer );
|
||||||
|
descriptor->bindStorageBuffer( 1, per_vertex_buffer );
|
||||||
|
descriptor->update();
|
||||||
|
descriptor->setName( "Command Buffer + Vertex Buffer" );
|
||||||
|
|
||||||
|
descriptors[ i ] = std::move( descriptor );
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraViewpoint::CameraViewpoint( memory::Buffer& buffer, const vk::Extent2D extent ) :
|
||||||
|
m_extent( extent ),
|
||||||
|
m_camera_frame_info( buffer ),
|
||||||
|
m_draw_parameter_pool(
|
||||||
|
4_MiB,
|
||||||
|
vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eStorageBuffer,
|
||||||
|
vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible ),
|
||||||
|
m_gpu_draw_commands(
|
||||||
|
constructPerFrame< DeviceVector< vk::DrawIndexedIndirectCommand > >( m_draw_parameter_pool ) ),
|
||||||
|
m_generated_instance_info(
|
||||||
|
constructPerFrame< DeviceVector< InstanceRenderInfo > >( getModelBuffers().m_vertex_buffer ) ),
|
||||||
|
m_gpu_draw_cmds_desc( createDrawCommandsDescriptors( m_gpu_draw_commands, m_generated_instance_info ) ),
|
||||||
|
m_camera_info_descriptors( createCameraDescriptors() )
|
||||||
|
{
|
||||||
|
setFOV( m_fov_y );
|
||||||
|
}
|
||||||
|
|
||||||
|
Coordinate< CoordinateSpace::World > CameraViewpoint::getPosition() const
|
||||||
|
{
|
||||||
|
//Should maybe store the inverse view matrix
|
||||||
|
return WorldCoordinate( m_inverse_view_matrix[ 3 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix< MatrixType::WorldToScreen > CameraViewpoint::getProjectionViewMatrix() const
|
||||||
|
{
|
||||||
|
assert( m_projection_matrix != constants::MAT4_IDENTITY );
|
||||||
|
return m_projection_matrix * m_view_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 CameraViewpoint::getInverseViewMatrix() const
|
||||||
|
{
|
||||||
|
return glm::inverse( m_view_matrix );
|
||||||
|
}
|
||||||
|
|
||||||
|
FGL_FLATTEN_HOT void CameraViewpoint::
|
||||||
|
setView( const WorldCoordinate pos, const QuatRotation& rotation, const ViewMode mode )
|
||||||
|
{
|
||||||
|
switch ( mode )
|
||||||
|
{
|
||||||
|
case ViewMode::TaitBryan:
|
||||||
|
{
|
||||||
|
m_transform.translation = pos;
|
||||||
|
m_transform.rotation = rotation;
|
||||||
|
updateMatrix();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ViewMode::Euler:
|
||||||
|
[[fallthrough]];
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
//view_matrix = glm::lookAt(position, position + );
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error( "Unimplemented view mode" );
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFrustum();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::setOrthographicProjection(
|
||||||
|
const float left, const float right, const float top, const float bottom, const float near, const float far )
|
||||||
|
{
|
||||||
|
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::ortho( left, right, bottom, top, near, far ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
FGL_FLATTEN_HOT void CameraViewpoint::
|
||||||
|
setPerspectiveProjection( const float fovy, const float aspect, const float near, const float far )
|
||||||
|
{
|
||||||
|
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::perspective( fovy, aspect, near, far ) );
|
||||||
|
|
||||||
|
m_base_frustum = createFrustum( aspect, fovy, near, far );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::setViewport( const vk::raii::CommandBuffer& command_buffer )
|
||||||
|
{
|
||||||
|
vk::Viewport viewport {};
|
||||||
|
viewport.x = 0.0f;
|
||||||
|
viewport.y = 0.0f;
|
||||||
|
|
||||||
|
const auto& [ width, height ] = m_extent;
|
||||||
|
viewport.width = static_cast< float >( width );
|
||||||
|
viewport.height = static_cast< float >( height );
|
||||||
|
viewport.minDepth = 0.0f;
|
||||||
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
|
const std::vector< vk::Viewport > viewports { viewport };
|
||||||
|
|
||||||
|
command_buffer.setViewport( 0, viewports );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::setScissor( const vk::raii::CommandBuffer& command_buffer )
|
||||||
|
{
|
||||||
|
const vk::Rect2D scissor { { 0, 0 }, m_extent };
|
||||||
|
|
||||||
|
const std::vector< vk::Rect2D > scissors { scissor };
|
||||||
|
|
||||||
|
command_buffer.setScissor( 0, scissors );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::setFOV( const float fov_y )
|
||||||
|
{
|
||||||
|
m_fov_y = fov_y;
|
||||||
|
setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
||||||
|
}
|
||||||
|
|
||||||
|
float CameraViewpoint::aspectRatio() const
|
||||||
|
{
|
||||||
|
return static_cast< float >( m_extent.width ) / static_cast< float >( m_extent.height );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::moveTo( const WorldTransform pos )
|
||||||
|
{
|
||||||
|
this->m_transform = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::updateInfo( const FrameIndex frame_index )
|
||||||
|
{
|
||||||
|
ZoneScoped;
|
||||||
|
updateMatrix();
|
||||||
|
CameraInfo current_camera_info { .projection = getProjectionMatrix(),
|
||||||
|
.view = getViewMatrix(),
|
||||||
|
.inverse_view = getInverseViewMatrix() };
|
||||||
|
|
||||||
|
m_camera_frame_info[ frame_index ] = current_camera_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraViewpoint::setExtent( const vk::Extent2D extent )
|
||||||
|
{
|
||||||
|
m_extent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::Rect2D CameraViewpoint::scissor() const
|
||||||
|
{
|
||||||
|
return { { 0, 0 }, m_extent };
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::Viewport CameraViewpoint::viewport() const
|
||||||
|
{
|
||||||
|
return { 0, 0, this->m_extent.width, this->m_extent.height, 0.0f, 1.0f };
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptors::DescriptorSetLayout& CameraViewpoint::getDescriptorLayout()
|
||||||
|
{
|
||||||
|
return camera_descriptor_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fgl::engine
|
||||||
@@ -1,82 +1,37 @@
|
|||||||
//
|
//
|
||||||
// Created by kj16609 on 11/28/23.
|
// Created by kj16609 on 9/23/25.
|
||||||
//
|
//
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#include "CameraInfo.hpp"
|
||||||
#pragma GCC diagnostic ignored "-Weffc++"
|
#include "memory/buffers/HostSingleT.hpp"
|
||||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
#include "memory/buffers/UniqueFrameSuballocation.hpp"
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#include "primitives/Frustum.hpp"
|
||||||
#include <glm/glm.hpp>
|
#include "primitives/Transform.hpp"
|
||||||
#include <glm/gtx/string_cast.hpp>
|
#include "primitives/matricies/Matrix.hpp"
|
||||||
#pragma GCC diagnostic pop
|
#include "rendering/PresentSwapChain.hpp"
|
||||||
|
|
||||||
#include "../primitives/rotation/QuatRotation.hpp"
|
|
||||||
#include "CompositeSwapchain.hpp"
|
|
||||||
#include "GBufferSwapchain.hpp"
|
|
||||||
#include "debug/Track.hpp"
|
|
||||||
#include "engine/descriptors/DescriptorSet.hpp"
|
|
||||||
#include "engine/memory/buffers/HostSingleT.hpp"
|
|
||||||
#include "engine/memory/buffers/UniqueFrameSuballocation.hpp"
|
|
||||||
#include "engine/primitives/Frustum.hpp"
|
|
||||||
#include "engine/primitives/Transform.hpp"
|
|
||||||
#include "engine/rendering/types.hpp"
|
|
||||||
|
|
||||||
namespace vk::raii
|
|
||||||
{
|
|
||||||
class CommandBuffer;
|
|
||||||
class RenderPass;
|
|
||||||
} // namespace vk::raii
|
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
struct InstanceRenderInfo;
|
||||||
|
|
||||||
namespace descriptors
|
namespace descriptors
|
||||||
{
|
{
|
||||||
class DescriptorSetLayout;
|
class DescriptorSetLayout;
|
||||||
}
|
class DescriptorSet;
|
||||||
class Image;
|
} // namespace descriptors
|
||||||
struct FrameInfo;
|
|
||||||
class GBufferRenderer;
|
|
||||||
|
|
||||||
struct CameraInfo;
|
class CameraViewpoint
|
||||||
class Camera;
|
|
||||||
|
|
||||||
FrustumBase createFrustum( float aspect, float fovy, float near, float far );
|
|
||||||
|
|
||||||
using CameraIDX = std::uint8_t;
|
|
||||||
|
|
||||||
class Camera
|
|
||||||
{
|
{
|
||||||
inline static CameraIDX m_camera_counter { 0 };
|
protected:
|
||||||
|
|
||||||
debug::Track< "CPU", "Camera" > m_camera {};
|
|
||||||
|
|
||||||
vk::Extent2D m_target_extent;
|
|
||||||
|
|
||||||
std::unique_ptr< CompositeSwapchain > m_composite_swapchain;
|
|
||||||
std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain;
|
|
||||||
|
|
||||||
//TODO: Move to deffered deleter
|
|
||||||
std::queue< std::unique_ptr< CompositeSwapchain > > m_old_composite_swapchain {};
|
|
||||||
std::queue< std::unique_ptr< GBufferSwapchain > > m_old_gbuffer_swapchain {};
|
|
||||||
|
|
||||||
std::shared_ptr< GBufferRenderer > m_camera_renderer;
|
|
||||||
|
|
||||||
//! True if the camera is active and to be rendered
|
|
||||||
bool m_active { true };
|
|
||||||
|
|
||||||
//! If true, The camera's swapchain is to be destroyed in order to preserve memory.
|
|
||||||
//! This is here to allow us to set a camera cold when it's not likely to be used soon
|
|
||||||
bool m_cold { false };
|
|
||||||
|
|
||||||
// Const is acceptable, Since this value should never change. EVER
|
|
||||||
const CameraIDX m_camera_idx { m_camera_counter++ };
|
|
||||||
|
|
||||||
|
vk::Extent2D m_extent;
|
||||||
Matrix< MatrixType::CameraToScreen > m_projection_matrix { 1.0f };
|
Matrix< MatrixType::CameraToScreen > m_projection_matrix { 1.0f };
|
||||||
|
|
||||||
Matrix< MatrixType::WorldToCamera > m_view_matrix { 1.0f };
|
Matrix< MatrixType::WorldToCamera > m_view_matrix { 1.0f };
|
||||||
glm::mat4 m_inverse_view_matrix { 1.0f };
|
glm::mat4 m_inverse_view_matrix { 1.0f };
|
||||||
|
bool m_ortho { false };
|
||||||
|
|
||||||
//! Frustum of the camera in model space relative to the camera
|
//! Frustum of the camera in model space relative to the camera
|
||||||
//! @note Must be transformed by the inverse view matrix to get the frustum in world space
|
//! @note Must be transformed by the inverse view matrix to get the frustum in world space
|
||||||
@@ -86,58 +41,62 @@ namespace fgl::engine
|
|||||||
|
|
||||||
WorldTransform m_transform {};
|
WorldTransform m_transform {};
|
||||||
|
|
||||||
float m_fov_y { glm::radians( 90.0f ) };
|
float& x { m_transform.translation.x };
|
||||||
|
float& y { m_transform.translation.y };
|
||||||
|
float& z { m_transform.translation.z };
|
||||||
|
|
||||||
PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info;
|
PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info;
|
||||||
|
std::uint32_t m_viewpoint_idx { 0 };
|
||||||
|
|
||||||
|
memory::Buffer m_draw_parameter_pool;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PerFrameArray< DeviceVector< vk::DrawIndexedIndirectCommand > > m_gpu_draw_commands;
|
||||||
|
PerFrameArray< DeviceVector< InstanceRenderInfo > > m_generated_instance_info;
|
||||||
|
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_gpu_draw_cmds_desc;
|
||||||
|
|
||||||
|
memory::BufferSuballocation& frameInfo( FrameIndex i );
|
||||||
|
|
||||||
// Camera info is expected at binding 0
|
// Camera info is expected at binding 0
|
||||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > createCameraDescriptors();
|
std::vector< std::unique_ptr< descriptors::DescriptorSet > > createCameraDescriptors();
|
||||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_camera_info_descriptors;
|
std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_camera_info_descriptors;
|
||||||
|
|
||||||
std::string m_name { "Unnamed Camera" };
|
private:
|
||||||
|
|
||||||
[[nodiscard]] Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
|
enum ViewMode
|
||||||
|
{
|
||||||
void updateFrustum();
|
Euler,
|
||||||
|
TaitBryan
|
||||||
#ifdef EXPOSE_CAMERA_TESTS
|
};
|
||||||
//Constructor for tests
|
|
||||||
Camera( vk::Extent2D test_extent ) : m_target_extent( test_extent ) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Camera( vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer );
|
|
||||||
|
|
||||||
friend class CameraManager;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
float& x { m_transform.translation.x };
|
float m_fov_y { glm::radians( 90.0f ) };
|
||||||
float& y { m_transform.translation.y };
|
|
||||||
float& z { m_transform.translation.z };
|
|
||||||
|
|
||||||
FGL_DELETE_ALL_RO5( Camera );
|
FGL_DELETE_ALL_RO5( CameraViewpoint );
|
||||||
|
|
||||||
~Camera();
|
explicit CameraViewpoint( memory::Buffer& buffer, vk::Extent2D extent = { 1920, 1080 } );
|
||||||
|
|
||||||
[[nodiscard]] CameraIDX getIDX() const;
|
[[nodiscard]] Coordinate< CoordinateSpace::World > getPosition() const;
|
||||||
|
|
||||||
[[nodiscard]] const std::string& getName() const;
|
WorldTransform& getTransform() { return m_transform; }
|
||||||
|
|
||||||
void setExtent( vk::Extent2D extent );
|
|
||||||
|
|
||||||
[[nodiscard]] QuatRotation getRotation() const { return m_transform.rotation.forcedQuat(); }
|
[[nodiscard]] QuatRotation getRotation() const { return m_transform.rotation.forcedQuat(); }
|
||||||
|
|
||||||
[[nodiscard]] const WorldTransform& getTransform() const { return m_transform; }
|
[[nodiscard]] const WorldTransform& getTransform() const { return m_transform; }
|
||||||
|
|
||||||
WorldTransform& getTransform() { return m_transform; }
|
|
||||||
|
|
||||||
WorldCoordinate getFrustumPosition() const;
|
|
||||||
|
|
||||||
[[nodiscard]] const FrustumBase& getBaseFrustum() const { return m_base_frustum; }
|
[[nodiscard]] const FrustumBase& getBaseFrustum() const { return m_base_frustum; }
|
||||||
|
|
||||||
//! Returns the frustum of the camera in world space
|
//! Returns the frustum of the camera in world space
|
||||||
[[nodiscard]] const Frustum& getFrustumBounds() const { return m_frustum; }
|
[[nodiscard]] const Frustum& getFrustumBounds() const { return m_frustum; }
|
||||||
|
|
||||||
|
[[nodiscard]] WorldCoordinate getFrustumPosition() const;
|
||||||
|
|
||||||
|
void updateMatrix();
|
||||||
|
void updateFrustum();
|
||||||
|
|
||||||
[[nodiscard]] const Matrix< MatrixType::CameraToScreen >& getProjectionMatrix() const
|
[[nodiscard]] const Matrix< MatrixType::CameraToScreen >& getProjectionMatrix() const
|
||||||
{
|
{
|
||||||
return m_projection_matrix;
|
return m_projection_matrix;
|
||||||
@@ -148,20 +107,13 @@ namespace fgl::engine
|
|||||||
[[nodiscard]] Matrix< MatrixType::WorldToScreen > getProjectionViewMatrix() const;
|
[[nodiscard]] Matrix< MatrixType::WorldToScreen > getProjectionViewMatrix() const;
|
||||||
|
|
||||||
[[nodiscard]] glm::mat4 getInverseViewMatrix() const;
|
[[nodiscard]] glm::mat4 getInverseViewMatrix() const;
|
||||||
|
[[nodiscard]] Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
|
||||||
enum ViewMode
|
|
||||||
{
|
|
||||||
Euler,
|
|
||||||
TaitBryan
|
|
||||||
};
|
|
||||||
|
|
||||||
void setView( WorldCoordinate pos, const QuatRotation& rotation, ViewMode mode = TaitBryan );
|
void setView( WorldCoordinate pos, const QuatRotation& rotation, ViewMode mode = TaitBryan );
|
||||||
void setOrthographicProjection( float left, float right, float top, float bottom, float near, float far );
|
void setOrthographicProjection( float left, float right, float top, float bottom, float near, float far );
|
||||||
void setPerspectiveProjection( float fovy, float aspect, float near, float far );
|
void setPerspectiveProjection( float fovy, float aspect, float near, float far );
|
||||||
|
|
||||||
[[nodiscard]] Coordinate< CoordinateSpace::World > getPosition() const;
|
FGL_FORCE_INLINE NormalVector getLeft() const { return -getRight(); }
|
||||||
|
|
||||||
FGL_FORCE_INLINE NormalVector getUp() const { return -getDown(); }
|
|
||||||
|
|
||||||
FGL_FORCE_INLINE NormalVector getRight() const
|
FGL_FORCE_INLINE NormalVector getRight() const
|
||||||
{
|
{
|
||||||
@@ -173,45 +125,30 @@ namespace fgl::engine
|
|||||||
return -NormalVector( glm::vec3( m_inverse_view_matrix[ 2 ] ) );
|
return -NormalVector( glm::vec3( m_inverse_view_matrix[ 2 ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
FGL_FORCE_INLINE NormalVector getLeft() const { return -getRight(); }
|
|
||||||
|
|
||||||
FGL_FORCE_INLINE NormalVector getBackward() const { return -getForward(); }
|
FGL_FORCE_INLINE NormalVector getBackward() const { return -getForward(); }
|
||||||
|
|
||||||
|
FGL_FORCE_INLINE NormalVector getUp() const { return -getDown(); }
|
||||||
|
|
||||||
FGL_FORCE_INLINE NormalVector getDown() const
|
FGL_FORCE_INLINE NormalVector getDown() const
|
||||||
{
|
{
|
||||||
return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) );
|
return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Updates the required info for rendering
|
|
||||||
void updateInfo( FrameIndex frame_index );
|
|
||||||
descriptors::DescriptorSet& getDescriptor( FrameIndex index );
|
|
||||||
|
|
||||||
void setFOV( float fov_y );
|
|
||||||
|
|
||||||
//! Performs the render pass for this camera
|
|
||||||
void pass( FrameInfo& frame_info );
|
|
||||||
|
|
||||||
[[nodiscard]] GBufferSwapchain& getSwapchain() const;
|
|
||||||
[[nodiscard]] CompositeSwapchain& getCompositeSwapchain() const;
|
|
||||||
void setViewport( const vk::raii::CommandBuffer& command_buffer );
|
void setViewport( const vk::raii::CommandBuffer& command_buffer );
|
||||||
void setScissor( const vk::raii::CommandBuffer& command_buffer );
|
void setScissor( const vk::raii::CommandBuffer& command_buffer );
|
||||||
|
void setFOV( float fov_y );
|
||||||
|
[[nodiscard]] float aspectRatio() const;
|
||||||
|
|
||||||
void remakeSwapchain( vk::Extent2D extent );
|
void moveTo( const WorldTransform pos );
|
||||||
|
|
||||||
void setName( std::string_view str );
|
//! Updates the required info for rendering
|
||||||
|
void updateInfo( FrameIndex frame_index );
|
||||||
|
|
||||||
float aspectRatio() const;
|
void setExtent( vk::Extent2D extent );
|
||||||
|
|
||||||
void copyOutput( const vk::raii::CommandBuffer& command_buffer, FrameIndex frame_index, Image& target );
|
vk::Rect2D scissor() const;
|
||||||
void updateMatrix();
|
vk::Viewport viewport() const;
|
||||||
|
|
||||||
static descriptors::DescriptorSetLayout& getDescriptorLayout();
|
static descriptors::DescriptorSetLayout& getDescriptorLayout();
|
||||||
|
|
||||||
#ifdef EXPOSE_CAMERA_TESTS
|
|
||||||
|
|
||||||
Camera CREATE_TESTING_CAMERA() { return { { 1920, 1080 } }; }
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
} // namespace fgl::engine
|
||||||
} // namespace fgl::engine
|
|
||||||
@@ -3,9 +3,10 @@
|
|||||||
//
|
//
|
||||||
#include "GBufferCompositor.hpp"
|
#include "GBufferCompositor.hpp"
|
||||||
|
|
||||||
#include "Camera.hpp"
|
|
||||||
#include "CompositeSwapchain.hpp"
|
#include "CompositeSwapchain.hpp"
|
||||||
#include "GBufferSwapchain.hpp"
|
#include "GBufferSwapchain.hpp"
|
||||||
|
#include "RenderCamera.hpp"
|
||||||
|
#include "ShadowMap.hpp"
|
||||||
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
|
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
@@ -56,7 +57,8 @@ namespace fgl::engine
|
|||||||
PipelineBuilder builder { 0 };
|
PipelineBuilder builder { 0 };
|
||||||
|
|
||||||
builder.addDescriptorSet( gbuffer_set );
|
builder.addDescriptorSet( gbuffer_set );
|
||||||
builder.addDescriptorSet( Camera::getDescriptorLayout() );
|
builder.addDescriptorSet( RenderCamera::getDescriptorLayout() );
|
||||||
|
builder.addDescriptorSet( ShadowMap::getDescriptorLayout() );
|
||||||
|
|
||||||
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
|
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
|
||||||
|
|
||||||
@@ -73,7 +75,8 @@ namespace fgl::engine
|
|||||||
m_pipeline->setDebugName( "Composition pipeline" );
|
m_pipeline->setDebugName( "Composition pipeline" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBufferCompositor::composite( CommandBuffer& command_buffer, Camera& camera, const FrameIndex frame_index )
|
void GBufferCompositor::
|
||||||
|
composite( CommandBuffer& command_buffer, RenderCamera& camera, const FrameIndex frame_index )
|
||||||
{
|
{
|
||||||
auto& gbuffer_swapchain { camera.getSwapchain() };
|
auto& gbuffer_swapchain { camera.getSwapchain() };
|
||||||
auto& composite_swapchain { camera.getCompositeSwapchain() };
|
auto& composite_swapchain { camera.getCompositeSwapchain() };
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <vulkan/vulkan_raii.hpp>
|
#include <vulkan/vulkan_raii.hpp>
|
||||||
|
|
||||||
#include "Camera.hpp"
|
#include "RenderCamera.hpp"
|
||||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||||
#include "engine/rendering/types.hpp"
|
#include "engine/rendering/types.hpp"
|
||||||
#include "engine/systems/composition/Control.hpp"
|
#include "engine/systems/composition/Control.hpp"
|
||||||
@@ -48,7 +48,7 @@ namespace fgl::engine
|
|||||||
|
|
||||||
GBufferCompositor( CompositeFlags flags = CompositeFlagBits_Standard );
|
GBufferCompositor( CompositeFlags flags = CompositeFlagBits_Standard );
|
||||||
|
|
||||||
void composite( CommandBuffer& command_buffer, Camera& camera, FrameIndex frame_index );
|
void composite( CommandBuffer& command_buffer, RenderCamera& camera, FrameIndex frame_index );
|
||||||
|
|
||||||
inline void switchMode( const CompositeFlags flags ) { m_flags = flags; }
|
inline void switchMode( const CompositeFlags flags ) { m_flags = flags; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ namespace fgl::engine
|
|||||||
|
|
||||||
camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::FINAL, frame_info.in_flight_idx );
|
camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::FINAL, frame_info.in_flight_idx );
|
||||||
|
|
||||||
m_compositor.composite( command_buffer, *frame_info.camera, frame_info.in_flight_idx );
|
m_compositor
|
||||||
|
.composite( command_buffer, *static_cast< RenderCamera* >( frame_info.camera ), frame_info.in_flight_idx );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace fgl::engine
|
} // namespace fgl::engine
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
// Created by kj16609 on 11/28/23.
|
// Created by kj16609 on 11/28/23.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Camera.hpp"
|
#include "RenderCamera.hpp"
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/gtx/string_cast.hpp>
|
#include <glm/gtx/string_cast.hpp>
|
||||||
#include <tracy/Tracy.hpp>
|
#include <tracy/Tracy.hpp>
|
||||||
|
|
||||||
#include "CameraInfo.hpp"
|
|
||||||
#include "GBufferRenderer.hpp"
|
#include "GBufferRenderer.hpp"
|
||||||
#include "GBufferSwapchain.hpp"
|
#include "GBufferSwapchain.hpp"
|
||||||
#include "engine/debug/timing/FlameGraph.hpp"
|
#include "engine/debug/timing/FlameGraph.hpp"
|
||||||
@@ -16,61 +15,67 @@
|
|||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|
||||||
Matrix< MatrixType::WorldToScreen > Camera::getProjectionViewMatrix() const
|
FrustumBase createFrustum( const float aspect, const float fov_y, const float near, const float far )
|
||||||
{
|
{
|
||||||
assert( m_projection_matrix != constants::MAT4_IDENTITY );
|
const Plane< CoordinateSpace::Model > near_plane { ModelCoordinate( constants::WORLD_FORWARD * near ),
|
||||||
return m_projection_matrix * m_view_matrix;
|
NormalVector( constants::WORLD_FORWARD ) };
|
||||||
|
const Plane< CoordinateSpace::Model > far_plane { ModelCoordinate( constants::WORLD_FORWARD * far ),
|
||||||
|
NormalVector( -constants::WORLD_FORWARD ) };
|
||||||
|
|
||||||
|
const float half_height { far * glm::tan( fov_y / 2.0f ) };
|
||||||
|
const float half_width { half_height * aspect };
|
||||||
|
|
||||||
|
const ModelCoordinate far_forward { constants::WORLD_FORWARD * far };
|
||||||
|
const ModelCoordinate right_half { constants::WORLD_RIGHT * half_width };
|
||||||
|
|
||||||
|
const Vector right_forward { ( far_forward + right_half ).vec() };
|
||||||
|
const Vector left_forward { ( far_forward - right_half ).vec() };
|
||||||
|
|
||||||
|
const Plane< CoordinateSpace::Model > right_plane {
|
||||||
|
ModelCoordinate( constants::WORLD_CENTER ),
|
||||||
|
NormalVector( glm::cross( right_forward.vec(), constants::WORLD_Z_NEG ) )
|
||||||
|
};
|
||||||
|
const Plane< CoordinateSpace::Model > left_plane {
|
||||||
|
ModelCoordinate( constants::WORLD_CENTER ),
|
||||||
|
NormalVector( glm::cross( left_forward.vec(), constants::WORLD_Z ) )
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModelCoordinate top_half { constants::WORLD_Z * half_height };
|
||||||
|
|
||||||
|
const Vector top_forward { ( far_forward + top_half ).vec() };
|
||||||
|
const Vector bottom_forward { ( far_forward - top_half ).vec() };
|
||||||
|
|
||||||
|
const Plane< CoordinateSpace::Model > top_plane {
|
||||||
|
ModelCoordinate( constants::WORLD_CENTER ),
|
||||||
|
NormalVector( glm::cross( top_forward.vec(), constants::WORLD_RIGHT ) )
|
||||||
|
};
|
||||||
|
|
||||||
|
const Plane< CoordinateSpace::Model > bottom_plane {
|
||||||
|
ModelCoordinate( constants::WORLD_CENTER ),
|
||||||
|
NormalVector( glm::cross( bottom_forward.vec(), -constants::WORLD_RIGHT ) )
|
||||||
|
};
|
||||||
|
|
||||||
|
return { near_plane,
|
||||||
|
far_plane,
|
||||||
|
top_plane,
|
||||||
|
bottom_plane,
|
||||||
|
right_plane,
|
||||||
|
left_plane,
|
||||||
|
Coordinate< CoordinateSpace::Model >( constants::WORLD_CENTER ) };
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Camera::getInverseViewMatrix() const
|
const std::string& RenderCamera::getName() const
|
||||||
{
|
{
|
||||||
return glm::inverse( m_view_matrix );
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
|
descriptors::DescriptorSet& RenderCamera::getDescriptor( const FrameIndex index )
|
||||||
{
|
|
||||||
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::ortho( left, right, bottom, top, near, far ) );
|
|
||||||
|
|
||||||
//TODO: Figure out frustum culling for orthographic projection. (If we even wanna use it)
|
|
||||||
}
|
|
||||||
|
|
||||||
FGL_FLATTEN_HOT void Camera::
|
|
||||||
setPerspectiveProjection( const float fovy, const float aspect, const float near, const float far )
|
|
||||||
{
|
|
||||||
m_projection_matrix = Matrix< MatrixType::CameraToScreen >( glm::perspective( fovy, aspect, near, far ) );
|
|
||||||
|
|
||||||
m_base_frustum = createFrustum( aspect, fovy, near, far );
|
|
||||||
}
|
|
||||||
|
|
||||||
Coordinate< CoordinateSpace::World > Camera::getPosition() const
|
|
||||||
{
|
|
||||||
//Should maybe store the inverse view matrix
|
|
||||||
return WorldCoordinate( m_inverse_view_matrix[ 3 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::updateInfo( const FrameIndex frame_index )
|
|
||||||
{
|
|
||||||
ZoneScoped;
|
|
||||||
CameraInfo current_camera_info { .projection = getProjectionMatrix(),
|
|
||||||
.view = getViewMatrix(),
|
|
||||||
.inverse_view = getInverseViewMatrix() };
|
|
||||||
|
|
||||||
m_camera_frame_info[ frame_index ] = current_camera_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptors::DescriptorSet& Camera::getDescriptor( const FrameIndex index )
|
|
||||||
{
|
{
|
||||||
assert( index < m_camera_info_descriptors.size() );
|
assert( index < m_camera_info_descriptors.size() );
|
||||||
return *m_camera_info_descriptors[ index ];
|
return *m_camera_info_descriptors[ index ];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setFOV( const float fov_y )
|
void RenderCamera::pass( FrameInfo& frame_info )
|
||||||
{
|
|
||||||
m_fov_y = fov_y;
|
|
||||||
setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::pass( FrameInfo& frame_info )
|
|
||||||
{
|
{
|
||||||
ZoneScopedN( "Camera::pass" );
|
ZoneScopedN( "Camera::pass" );
|
||||||
auto timer = debug::timing::push( "Camera" );
|
auto timer = debug::timing::push( "Camera" );
|
||||||
@@ -98,45 +103,20 @@ namespace fgl::engine
|
|||||||
frame_info.camera = nullptr;
|
frame_info.camera = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GBufferSwapchain& Camera::getSwapchain() const
|
GBufferSwapchain& RenderCamera::getSwapchain() const
|
||||||
{
|
{
|
||||||
return *m_gbuffer_swapchain;
|
return *m_gbuffer_swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositeSwapchain& Camera::getCompositeSwapchain() const
|
CompositeSwapchain& RenderCamera::getCompositeSwapchain() const
|
||||||
{
|
{
|
||||||
return *m_composite_swapchain;
|
return *m_composite_swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setViewport( const vk::raii::CommandBuffer& command_buffer )
|
void RenderCamera::remakeSwapchain( vk::Extent2D extent )
|
||||||
{
|
{
|
||||||
vk::Viewport viewport {};
|
setExtent( extent );
|
||||||
viewport.x = 0.0f;
|
this->setPerspectiveProjection( m_fov_y, this->aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
||||||
viewport.y = 0.0f;
|
|
||||||
|
|
||||||
const auto& [ width, height ] = m_gbuffer_swapchain->getExtent();
|
|
||||||
viewport.width = static_cast< float >( width );
|
|
||||||
viewport.height = static_cast< float >( height );
|
|
||||||
viewport.minDepth = 0.0f;
|
|
||||||
viewport.maxDepth = 1.0f;
|
|
||||||
|
|
||||||
const std::vector< vk::Viewport > viewports { viewport };
|
|
||||||
|
|
||||||
command_buffer.setViewport( 0, viewports );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::setScissor( const vk::raii::CommandBuffer& command_buffer )
|
|
||||||
{
|
|
||||||
const vk::Rect2D scissor { { 0, 0 }, m_gbuffer_swapchain->getExtent() };
|
|
||||||
|
|
||||||
const std::vector< vk::Rect2D > scissors { scissor };
|
|
||||||
|
|
||||||
command_buffer.setScissor( 0, scissors );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::remakeSwapchain( vk::Extent2D extent )
|
|
||||||
{
|
|
||||||
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
|
||||||
|
|
||||||
log::debug( "Camera swapchain recreated" );
|
log::debug( "Camera swapchain recreated" );
|
||||||
|
|
||||||
@@ -148,20 +128,22 @@ namespace fgl::engine
|
|||||||
|
|
||||||
m_composite_swapchain = std::make_unique< CompositeSwapchain >( extent );
|
m_composite_swapchain = std::make_unique< CompositeSwapchain >( extent );
|
||||||
m_gbuffer_swapchain = std::make_unique< GBufferSwapchain >( extent );
|
m_gbuffer_swapchain = std::make_unique< GBufferSwapchain >( extent );
|
||||||
|
|
||||||
|
CameraViewpoint::setExtent( extent );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::setName( const std::string_view str )
|
void RenderCamera::setName( const std::string_view str )
|
||||||
{
|
{
|
||||||
m_name = str;
|
m_name = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Camera::aspectRatio() const
|
float RenderCamera::aspectRatio() const
|
||||||
{
|
{
|
||||||
return m_gbuffer_swapchain->getAspectRatio();
|
return m_gbuffer_swapchain->getAspectRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::
|
void RenderCamera::
|
||||||
copyOutput( const vk::raii::CommandBuffer& command_buffer, const FrameIndex frame_index, Image& target )
|
copyOutput( const vk::raii::CommandBuffer& command_buffer, const FrameIndex frame_index, Image& target ) const
|
||||||
{
|
{
|
||||||
assert( m_gbuffer_swapchain->getExtent() == target.getExtent() );
|
assert( m_gbuffer_swapchain->getExtent() == target.getExtent() );
|
||||||
|
|
||||||
@@ -271,175 +253,39 @@ namespace fgl::engine
|
|||||||
{ barrier_to_source } );
|
{ barrier_to_source } );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::updateMatrix()
|
WorldCoordinate CameraViewpoint::getFrustumPosition() const
|
||||||
{
|
{
|
||||||
const auto& [ pos, scale, rotation ] = m_transform;
|
return m_last_frustum_pos;
|
||||||
|
|
||||||
const auto rotation_matrix { rotation.forcedQuat().mat() };
|
|
||||||
|
|
||||||
const glm::vec3 forward { rotation_matrix * glm::vec4( constants::WORLD_FORWARD, 0.0f ) };
|
|
||||||
|
|
||||||
const glm::vec3 camera_up { rotation_matrix * glm::vec4( -constants::WORLD_Z, 0.0f ) };
|
|
||||||
|
|
||||||
const WorldCoordinate center_pos { pos + forward };
|
|
||||||
|
|
||||||
m_view_matrix = Matrix< MatrixType::WorldToCamera >( glm::lookAt( pos.vec(), center_pos.vec(), camera_up ) );
|
|
||||||
|
|
||||||
m_inverse_view_matrix = glm::inverse( m_view_matrix );
|
|
||||||
|
|
||||||
updateFrustum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FGL_FLATTEN_HOT void Camera::setView( const WorldCoordinate pos, const QuatRotation& rotation, const ViewMode mode )
|
Matrix< MatrixType::ModelToWorld > CameraViewpoint::frustumTranslationMatrix() const
|
||||||
{
|
{
|
||||||
switch ( mode )
|
return m_transform.mat();
|
||||||
{
|
|
||||||
case ViewMode::TaitBryan:
|
|
||||||
{
|
|
||||||
m_transform.translation = pos;
|
|
||||||
m_transform.rotation = rotation;
|
|
||||||
updateMatrix();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ViewMode::Euler:
|
|
||||||
[[fallthrough]];
|
|
||||||
{
|
|
||||||
//TODO: Implement
|
|
||||||
//view_matrix = glm::lookAt(position, position + );
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw std::runtime_error( "Unimplemented view mode" );
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFrustum();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::updateFrustum()
|
RenderCamera::RenderCamera(
|
||||||
{
|
|
||||||
m_last_frustum_pos = getPosition();
|
|
||||||
|
|
||||||
const Matrix< MatrixType::ModelToWorld > translation_matrix { frustumTranslationMatrix() };
|
|
||||||
|
|
||||||
m_frustum = translation_matrix * m_base_frustum;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& Camera::getName() const
|
|
||||||
{
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr descriptors::Descriptor camera_descriptor { 0,
|
|
||||||
vk::DescriptorType::eUniformBuffer,
|
|
||||||
vk::ShaderStageFlagBits::eAllGraphics };
|
|
||||||
|
|
||||||
inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor };
|
|
||||||
|
|
||||||
descriptors::DescriptorSetLayout& Camera::getDescriptorLayout()
|
|
||||||
{
|
|
||||||
return camera_descriptor_set;
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera::Camera(
|
|
||||||
const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) :
|
const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) :
|
||||||
|
CameraViewpoint( buffer, extent ),
|
||||||
m_target_extent( extent ),
|
m_target_extent( extent ),
|
||||||
m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ),
|
m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ),
|
||||||
m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ),
|
m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ),
|
||||||
m_camera_renderer( renderer ),
|
m_camera_renderer( renderer )
|
||||||
m_camera_frame_info( buffer ),
|
|
||||||
m_camera_info_descriptors( createCameraDescriptors() )
|
|
||||||
{
|
{
|
||||||
FGL_ASSERT( renderer, "Camera renderer is null" );
|
FGL_ASSERT( renderer, "Camera renderer is null" );
|
||||||
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
||||||
this->setView( WorldCoordinate( constants::CENTER ), QuatRotation( 0.0f, 0.0f, 0.0f ) );
|
this->setView( WorldCoordinate( constants::CENTER ), QuatRotation( 0.0f, 0.0f, 0.0f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > Camera::createCameraDescriptors()
|
RenderCamera::~RenderCamera() = default;
|
||||||
{
|
|
||||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > sets {};
|
|
||||||
sets.reserve( constants::MAX_FRAMES_IN_FLIGHT );
|
|
||||||
|
|
||||||
for ( std::uint8_t i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
|
CameraIDX RenderCamera::getIDX() const
|
||||||
{
|
|
||||||
auto set { camera_descriptor_set.create() };
|
|
||||||
set->bindUniformBuffer( 0, m_camera_frame_info[ i ] );
|
|
||||||
set->update();
|
|
||||||
set->setName( std::format( "Camera {} descriptor set {}", m_camera_idx, i ) );
|
|
||||||
|
|
||||||
sets.emplace_back( std::move( set ) );
|
|
||||||
}
|
|
||||||
return sets;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::setExtent( const vk::Extent2D extent )
|
|
||||||
{
|
|
||||||
m_target_extent = extent;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrustumBase createFrustum( const float aspect, const float fov_y, const float near, const float far )
|
|
||||||
{
|
|
||||||
const Plane< CoordinateSpace::Model > near_plane { ModelCoordinate( constants::WORLD_FORWARD * near ),
|
|
||||||
NormalVector( constants::WORLD_FORWARD ) };
|
|
||||||
const Plane< CoordinateSpace::Model > far_plane { ModelCoordinate( constants::WORLD_FORWARD * far ),
|
|
||||||
NormalVector( -constants::WORLD_FORWARD ) };
|
|
||||||
|
|
||||||
const float half_height { far * glm::tan( fov_y / 2.0f ) };
|
|
||||||
const float half_width { half_height * aspect };
|
|
||||||
|
|
||||||
const ModelCoordinate far_forward { constants::WORLD_FORWARD * far };
|
|
||||||
const ModelCoordinate right_half { constants::WORLD_RIGHT * half_width };
|
|
||||||
|
|
||||||
const Vector right_forward { ( far_forward + right_half ).vec() };
|
|
||||||
const Vector left_forward { ( far_forward - right_half ).vec() };
|
|
||||||
|
|
||||||
const Plane< CoordinateSpace::Model > right_plane {
|
|
||||||
ModelCoordinate( constants::WORLD_CENTER ),
|
|
||||||
NormalVector( glm::cross( right_forward.vec(), constants::WORLD_Z_NEG ) )
|
|
||||||
};
|
|
||||||
const Plane< CoordinateSpace::Model > left_plane {
|
|
||||||
ModelCoordinate( constants::WORLD_CENTER ),
|
|
||||||
NormalVector( glm::cross( left_forward.vec(), constants::WORLD_Z ) )
|
|
||||||
};
|
|
||||||
|
|
||||||
const ModelCoordinate top_half { constants::WORLD_Z * half_height };
|
|
||||||
|
|
||||||
const Vector top_forward { ( far_forward + top_half ).vec() };
|
|
||||||
const Vector bottom_forward { ( far_forward - top_half ).vec() };
|
|
||||||
|
|
||||||
const Plane< CoordinateSpace::Model > top_plane {
|
|
||||||
ModelCoordinate( constants::WORLD_CENTER ),
|
|
||||||
NormalVector( glm::cross( top_forward.vec(), constants::WORLD_RIGHT ) )
|
|
||||||
};
|
|
||||||
|
|
||||||
const Plane< CoordinateSpace::Model > bottom_plane {
|
|
||||||
ModelCoordinate( constants::WORLD_CENTER ),
|
|
||||||
NormalVector( glm::cross( bottom_forward.vec(), -constants::WORLD_RIGHT ) )
|
|
||||||
};
|
|
||||||
|
|
||||||
return { near_plane,
|
|
||||||
far_plane,
|
|
||||||
top_plane,
|
|
||||||
bottom_plane,
|
|
||||||
right_plane,
|
|
||||||
left_plane,
|
|
||||||
Coordinate< CoordinateSpace::Model >( constants::WORLD_CENTER ) };
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix< MatrixType::ModelToWorld > Camera::frustumTranslationMatrix() const
|
|
||||||
{
|
|
||||||
return m_transform.mat();
|
|
||||||
}
|
|
||||||
|
|
||||||
WorldCoordinate Camera::getFrustumPosition() const
|
|
||||||
{
|
|
||||||
return m_last_frustum_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera::~Camera()
|
|
||||||
{}
|
|
||||||
|
|
||||||
CameraIDX Camera::getIDX() const
|
|
||||||
{
|
{
|
||||||
return m_camera_idx;
|
return m_camera_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderCamera::setExtent( const vk::Extent2D extent )
|
||||||
|
{
|
||||||
|
m_target_extent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fgl::engine
|
} // namespace fgl::engine
|
||||||
110
src/engine/camera/RenderCamera.hpp
Normal file
110
src/engine/camera/RenderCamera.hpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 11/28/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Weffc++"
|
||||||
|
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
#include "CameraViewpoint.hpp"
|
||||||
|
#include "CompositeSwapchain.hpp"
|
||||||
|
#include "GBufferSwapchain.hpp"
|
||||||
|
#include "debug/Track.hpp"
|
||||||
|
#include "engine/descriptors/DescriptorSet.hpp"
|
||||||
|
#include "engine/memory/buffers/HostSingleT.hpp"
|
||||||
|
#include "engine/memory/buffers/UniqueFrameSuballocation.hpp"
|
||||||
|
#include "engine/primitives/Frustum.hpp"
|
||||||
|
#include "engine/rendering/types.hpp"
|
||||||
|
|
||||||
|
namespace vk::raii
|
||||||
|
{
|
||||||
|
class CommandBuffer;
|
||||||
|
class RenderPass;
|
||||||
|
} // namespace vk::raii
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
namespace descriptors
|
||||||
|
{
|
||||||
|
class DescriptorSetLayout;
|
||||||
|
}
|
||||||
|
class Image;
|
||||||
|
struct FrameInfo;
|
||||||
|
class GBufferRenderer;
|
||||||
|
|
||||||
|
struct CameraInfo;
|
||||||
|
class RenderCamera;
|
||||||
|
|
||||||
|
FrustumBase createFrustum( float aspect, float fovy, float near, float far );
|
||||||
|
|
||||||
|
using CameraIDX = std::uint8_t;
|
||||||
|
|
||||||
|
class RenderCamera final : public CameraViewpoint
|
||||||
|
{
|
||||||
|
inline static CameraIDX m_camera_counter { 0 };
|
||||||
|
|
||||||
|
debug::Track< "CPU", "Camera" > m_camera {};
|
||||||
|
|
||||||
|
vk::Extent2D m_target_extent;
|
||||||
|
|
||||||
|
std::unique_ptr< CompositeSwapchain > m_composite_swapchain;
|
||||||
|
std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain;
|
||||||
|
|
||||||
|
//TODO: Move to deffered deleter
|
||||||
|
std::queue< std::unique_ptr< CompositeSwapchain > > m_old_composite_swapchain {};
|
||||||
|
std::queue< std::unique_ptr< GBufferSwapchain > > m_old_gbuffer_swapchain {};
|
||||||
|
|
||||||
|
std::shared_ptr< GBufferRenderer > m_camera_renderer;
|
||||||
|
|
||||||
|
//! True if the camera is active and to be rendered
|
||||||
|
bool m_active { true };
|
||||||
|
|
||||||
|
//! If true, The camera's swapchain is to be destroyed to preserve memory.
|
||||||
|
//! This is here to allow us to set a camera cold when it's not likely to be used soon
|
||||||
|
bool m_cold { false };
|
||||||
|
|
||||||
|
// Const is acceptable, Since this value should never change. EVER
|
||||||
|
const CameraIDX m_camera_idx { m_camera_counter++ };
|
||||||
|
|
||||||
|
std::string m_name { "Unnamed Camera" };
|
||||||
|
|
||||||
|
RenderCamera( vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer );
|
||||||
|
|
||||||
|
friend class CameraManager;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGL_DELETE_ALL_RO5( RenderCamera );
|
||||||
|
|
||||||
|
~RenderCamera();
|
||||||
|
|
||||||
|
[[nodiscard]] CameraIDX getIDX() const;
|
||||||
|
|
||||||
|
[[nodiscard]] const std::string& getName() const;
|
||||||
|
|
||||||
|
descriptors::DescriptorSet& getDescriptor( FrameIndex index );
|
||||||
|
|
||||||
|
void setExtent( vk::Extent2D extent );
|
||||||
|
|
||||||
|
//! Performs the render pass for this camera
|
||||||
|
void pass( FrameInfo& frame_info );
|
||||||
|
|
||||||
|
[[nodiscard]] GBufferSwapchain& getSwapchain() const;
|
||||||
|
[[nodiscard]] CompositeSwapchain& getCompositeSwapchain() const;
|
||||||
|
|
||||||
|
void remakeSwapchain( vk::Extent2D extent );
|
||||||
|
|
||||||
|
void setName( std::string_view str );
|
||||||
|
|
||||||
|
[[nodiscard]] float aspectRatio() const;
|
||||||
|
|
||||||
|
void copyOutput( const vk::raii::CommandBuffer& command_buffer, FrameIndex frame_index, Image& target ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fgl::engine
|
||||||
167
src/engine/camera/ShadowMap.cpp
Normal file
167
src/engine/camera/ShadowMap.cpp
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#include "ShadowMap.hpp"
|
||||||
|
|
||||||
|
#include "CameraManager.hpp"
|
||||||
|
#include "assets/model/Model.hpp"
|
||||||
|
#include "assets/model/ModelVertex.hpp"
|
||||||
|
#include "debug/timing/FlameGraph.hpp"
|
||||||
|
#include "rendering/pipelines/v2/Pipeline.hpp"
|
||||||
|
#include "rendering/pipelines/v2/PipelineBuilder.hpp"
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr< Swapchain > createDepthSwapchain( const vk::Extent2D extent )
|
||||||
|
{
|
||||||
|
std::vector< SwapchainImageInfo > swapchain_images {
|
||||||
|
{ .m_format = { .m_canidates = { vk::Format::eD32Sfloat,
|
||||||
|
vk::Format::eD32SfloatS8Uint,
|
||||||
|
vk::Format::eD24UnormS8Uint },
|
||||||
|
.m_usage =
|
||||||
|
vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eSampled,
|
||||||
|
.m_features = vk::FormatFeatureFlagBits::eDepthStencilAttachment },
|
||||||
|
.m_inital_layout = vk::ImageLayout::eUndefined,
|
||||||
|
.m_final_layout = vk::ImageLayout::eDepthReadOnlyOptimal,
|
||||||
|
.m_extent = extent,
|
||||||
|
.m_name = "Shadowmap Depth" }
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::make_shared< Swapchain >( std::move( swapchain_images ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr descriptors::Descriptor camera_descriptor { 0,
|
||||||
|
vk::DescriptorType::eUniformBuffer,
|
||||||
|
vk::ShaderStageFlagBits::eAllGraphics };
|
||||||
|
|
||||||
|
// 2d sampler
|
||||||
|
constexpr descriptors::Descriptor shadowmap_descriptor { 1,
|
||||||
|
vk::DescriptorType::eSampledImage,
|
||||||
|
vk::ShaderStageFlagBits::eFragment };
|
||||||
|
|
||||||
|
inline static descriptors::DescriptorSetLayout shadowmap_descriptor_set { 2,
|
||||||
|
camera_descriptor,
|
||||||
|
shadowmap_descriptor };
|
||||||
|
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > ShadowMap::createShadowmapDescriptors() const
|
||||||
|
{
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > data {};
|
||||||
|
|
||||||
|
for ( std::size_t i = 0; i < data.size(); ++i )
|
||||||
|
{
|
||||||
|
auto set { shadowmap_descriptor_set.create() };
|
||||||
|
|
||||||
|
set->bindImage(
|
||||||
|
shadowmap_descriptor.m_index,
|
||||||
|
*this->m_swapchain->depthView( i ),
|
||||||
|
vk::ImageLayout::eDepthReadOnlyOptimal );
|
||||||
|
set->bindUniformBuffer( camera_descriptor.m_index, this->m_camera->frameInfo( i ) );
|
||||||
|
|
||||||
|
set->update();
|
||||||
|
|
||||||
|
data[ i ] = std::move( set );
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowMap::ShadowMap( const UniversalRotation& direction, const vk::Extent2D extent ) :
|
||||||
|
m_swapchain( createDepthSwapchain( extent ) ),
|
||||||
|
m_direction( direction ),
|
||||||
|
m_camera( CameraManager::createViewpoint( extent ) ),
|
||||||
|
m_extent( extent ),
|
||||||
|
m_shadowmap_descriptor( createShadowmapDescriptors() )
|
||||||
|
{
|
||||||
|
PipelineBuilder builder { 0 };
|
||||||
|
|
||||||
|
builder.addDepthAttachment();
|
||||||
|
|
||||||
|
builder.addDescriptorSet( CameraViewpoint::getDescriptorLayout() );
|
||||||
|
builder.setVertexShader( Shader::loadVertex( "shaders/shadowmap.slang" ) );
|
||||||
|
builder.setFragmentShader( Shader::loadFragment( "shaders/shadowmap.slang" ) );
|
||||||
|
|
||||||
|
builder.setAttributeDescriptions( ModelVertex::getAttributeDescriptions() );
|
||||||
|
builder.setBindingDescriptions( ModelVertex::getBindingDescriptions() );
|
||||||
|
|
||||||
|
m_shadow_pipeline = builder.create();
|
||||||
|
m_shadow_pipeline->setDebugName( "Shadow pipeline" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShadowMap::pass( FrameInfo info )
|
||||||
|
{
|
||||||
|
ZoneScopedN( "ShadowMap::pass" );
|
||||||
|
auto timer = debug::timing::push( "ShadowMap" );
|
||||||
|
|
||||||
|
info.camera = m_camera.get();
|
||||||
|
|
||||||
|
info.camera->updateInfo( info.in_flight_idx );
|
||||||
|
|
||||||
|
m_culling_system.pass( info );
|
||||||
|
|
||||||
|
auto& command_buffer { info.command_buffer.render_cb };
|
||||||
|
|
||||||
|
vk::RenderingInfo rendering_info {};
|
||||||
|
vk::RenderingAttachmentInfo depth_info {};
|
||||||
|
depth_info.setClearValue( vk::ClearDepthStencilValue( 1.0f, 0 ) );
|
||||||
|
depth_info.setLoadOp( vk::AttachmentLoadOp::eClear );
|
||||||
|
depth_info.setStoreOp( vk::AttachmentStoreOp::eStore );
|
||||||
|
depth_info.imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
||||||
|
depth_info.imageView = m_swapchain->depthView( info.in_flight_idx )->getVkView();
|
||||||
|
rendering_info.colorAttachmentCount = 0;
|
||||||
|
rendering_info.pColorAttachments = nullptr;
|
||||||
|
rendering_info.setRenderArea( { { 0, 0 }, this->m_extent } );
|
||||||
|
rendering_info.layerCount = 1;
|
||||||
|
|
||||||
|
rendering_info.setPDepthAttachment( &depth_info );
|
||||||
|
|
||||||
|
command_buffer->beginRendering( rendering_info );
|
||||||
|
|
||||||
|
command_buffer->setViewport( 0, { info.camera->viewport() } );
|
||||||
|
command_buffer->setScissor( 0, { info.camera->scissor() } );
|
||||||
|
|
||||||
|
m_shadow_pipeline->bind( command_buffer );
|
||||||
|
|
||||||
|
m_shadow_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
|
||||||
|
|
||||||
|
auto& model_buffers { getModelBuffers() };
|
||||||
|
|
||||||
|
const std::vector< vk::Buffer > vert_buffers {
|
||||||
|
model_buffers.m_vertex_buffer->getVkBuffer(),
|
||||||
|
info.camera->m_generated_instance_info[ info.in_flight_idx ].getVkBuffer(),
|
||||||
|
};
|
||||||
|
|
||||||
|
command_buffer->bindVertexBuffers(
|
||||||
|
0, vert_buffers, { 0, info.camera->m_generated_instance_info[ info.in_flight_idx ].getOffset() } );
|
||||||
|
command_buffer->bindIndexBuffer( model_buffers.m_index_buffer->getVkBuffer(), 0, vk::IndexType::eUint32 );
|
||||||
|
|
||||||
|
const auto& commands { info.camera->m_gpu_draw_commands[ info.in_flight_idx ] };
|
||||||
|
|
||||||
|
command_buffer
|
||||||
|
->drawIndexedIndirect( commands.getVkBuffer(), commands.getOffset(), commands.size(), commands.stride() );
|
||||||
|
|
||||||
|
command_buffer->endRendering();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector< std::weak_ptr< ShadowMap > > shadowmaps {};
|
||||||
|
|
||||||
|
descriptors::DescriptorSetLayout& ShadowMap::getDescriptorLayout()
|
||||||
|
{
|
||||||
|
return shadowmap_descriptor_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< ShadowMap > createShadowmap( UniversalRotation direction )
|
||||||
|
{
|
||||||
|
constexpr int size { 1024 };
|
||||||
|
auto ptr { std::make_shared< ShadowMap >( direction, vk::Extent2D { size, size } ) };
|
||||||
|
|
||||||
|
shadowmaps.emplace_back( ptr );
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::weak_ptr< ShadowMap > > getShadowmaps()
|
||||||
|
{
|
||||||
|
return shadowmaps;
|
||||||
|
}
|
||||||
|
} // namespace fgl::engine
|
||||||
55
src/engine/camera/ShadowMap.hpp
Normal file
55
src/engine/camera/ShadowMap.hpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "RenderCamera.hpp"
|
||||||
|
#include "Swapchain.hpp"
|
||||||
|
#include "primitives/rotation/UniversalRotation.hpp"
|
||||||
|
#include "systems/prerender/CullingSystem.hpp"
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
void drawShadowmaps( const FrameInfo& info );
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CameraInfo;
|
||||||
|
|
||||||
|
class ShadowMap
|
||||||
|
{
|
||||||
|
std::shared_ptr< Swapchain > m_swapchain;
|
||||||
|
UniversalRotation m_direction;
|
||||||
|
|
||||||
|
std::shared_ptr< CameraViewpoint > m_camera;
|
||||||
|
|
||||||
|
std::unique_ptr< Pipeline > m_shadow_pipeline;
|
||||||
|
|
||||||
|
CullingSystem m_culling_system;
|
||||||
|
vk::Extent2D m_extent;
|
||||||
|
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > createShadowmapDescriptors() const;
|
||||||
|
PerFrameArray< std::unique_ptr< descriptors::DescriptorSet > > m_shadowmap_descriptor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ShadowMap() = delete;
|
||||||
|
|
||||||
|
ShadowMap( const UniversalRotation& direction, vk::Extent2D extent );
|
||||||
|
|
||||||
|
void pass( FrameInfo info );
|
||||||
|
|
||||||
|
friend void gui::drawShadowmaps( const FrameInfo& info );
|
||||||
|
static descriptors::DescriptorSetLayout& getDescriptorLayout();
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr< ShadowMap > createShadowmap( UniversalRotation direction );
|
||||||
|
|
||||||
|
std::vector< std::weak_ptr< ShadowMap > > getShadowmaps();
|
||||||
|
|
||||||
|
} // namespace fgl::engine
|
||||||
80
src/engine/camera/Swapchain.cpp
Normal file
80
src/engine/camera/Swapchain.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#include "Swapchain.hpp"
|
||||||
|
|
||||||
|
#include "assets/image/Image.hpp"
|
||||||
|
#include "assets/image/ImageView.hpp"
|
||||||
|
#include "assets/texture/Texture.hpp"
|
||||||
|
#include "constants.hpp"
|
||||||
|
#include "rendering/devices/Device.hpp"
|
||||||
|
#include "slang.h"
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
|
||||||
|
vk::Format SwapchainImageInfo::pickBestFormat() const
|
||||||
|
{
|
||||||
|
return Device::getInstance()
|
||||||
|
.findSupportedFormat( m_format.m_canidates, vk::ImageTiling::eOptimal, m_format.m_features );
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapchainImageSet::SwapchainImageSet( const SwapchainImageInfo& info )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < constants::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||||
|
{
|
||||||
|
auto image_itter { m_image.emplace_back(
|
||||||
|
std::make_shared< Image >(
|
||||||
|
info.m_extent,
|
||||||
|
info.pickBestFormat(),
|
||||||
|
info.m_format.m_usage,
|
||||||
|
info.m_inital_layout,
|
||||||
|
info.m_final_layout ) ) };
|
||||||
|
auto view_itter { m_view.emplace_back( image_itter->getView() ) };
|
||||||
|
|
||||||
|
image_itter->setName( std::format( "Swapchain image {}:{}", info.m_name, i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< Texture > SwapchainImageSet::getTexture( const FrameIndex frame_index ) const
|
||||||
|
{
|
||||||
|
if ( m_texture.empty() ) m_texture.resize( constants::MAX_FRAMES_IN_FLIGHT );
|
||||||
|
|
||||||
|
if ( !m_texture[ frame_index ] )
|
||||||
|
{
|
||||||
|
Sampler default_sampler {};
|
||||||
|
m_texture[ frame_index ] =
|
||||||
|
std::make_shared< Texture >( m_image[ frame_index ], std::move( default_sampler ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_texture[ frame_index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< ImageView > Swapchain::depthView( const FrameIndex frame_index ) const
|
||||||
|
{
|
||||||
|
const SwapchainImageSet& set { m_depth.value() };
|
||||||
|
|
||||||
|
return set.m_view[ frame_index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< Image > Swapchain::depthImage( const FrameIndex frame_index ) const
|
||||||
|
{
|
||||||
|
return m_depth.value().m_image[ frame_index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< Texture > Swapchain::depthTexture( const FrameIndex frame_index ) const
|
||||||
|
{
|
||||||
|
return m_depth.value().getTexture( frame_index );
|
||||||
|
}
|
||||||
|
|
||||||
|
Swapchain::Swapchain( const std::vector< SwapchainImageInfo >& in )
|
||||||
|
{
|
||||||
|
for ( const SwapchainImageInfo& info : in )
|
||||||
|
{
|
||||||
|
if ( info.m_format.m_usage & vk::ImageUsageFlagBits::eDepthStencilAttachment )
|
||||||
|
m_depth.emplace( info );
|
||||||
|
else
|
||||||
|
m_swapchain_images.emplace_back( info );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace fgl::engine
|
||||||
69
src/engine/camera/Swapchain.hpp
Normal file
69
src/engine/camera/Swapchain.hpp
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "FGL_DEFINES.hpp"
|
||||||
|
#include "assets/texture/Texture.hpp"
|
||||||
|
#include "rendering/types.hpp"
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
class Image;
|
||||||
|
class ImageView;
|
||||||
|
|
||||||
|
struct SwapchainImageInfo
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
std::vector< vk::Format > m_canidates;
|
||||||
|
vk::ImageUsageFlags m_usage;
|
||||||
|
vk::FormatFeatureFlags m_features;
|
||||||
|
} m_format;
|
||||||
|
|
||||||
|
vk::ImageLayout m_inital_layout;
|
||||||
|
vk::ImageLayout m_final_layout;
|
||||||
|
|
||||||
|
vk::Extent2D m_extent;
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Format pickBestFormat() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SwapchainImageSet
|
||||||
|
{
|
||||||
|
std::vector< std::shared_ptr< Image > > m_image {};
|
||||||
|
std::vector< std::shared_ptr< ImageView > > m_view {};
|
||||||
|
mutable std::vector< std::shared_ptr< Texture > > m_texture {};
|
||||||
|
|
||||||
|
friend class Swapchain;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SwapchainImageSet() = delete;
|
||||||
|
|
||||||
|
[[nodiscard]] SwapchainImageSet( const SwapchainImageInfo& info );
|
||||||
|
std::shared_ptr< Texture > getTexture( FrameIndex frame_index ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Swapchain
|
||||||
|
{
|
||||||
|
std::vector< SwapchainImageSet > m_swapchain_images {};
|
||||||
|
std::optional< SwapchainImageSet > m_depth {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
[[nodiscard]] std::shared_ptr< ImageView > depthView( FrameIndex frame_index ) const;
|
||||||
|
[[nodiscard]] std::shared_ptr< Image > depthImage( FrameIndex frame_index ) const;
|
||||||
|
std::shared_ptr< Texture > depthTexture( FrameIndex frame_index ) const;
|
||||||
|
|
||||||
|
FGL_DELETE_ALL_RO5( Swapchain );
|
||||||
|
|
||||||
|
[[nodiscard]] explicit Swapchain( const std::vector< SwapchainImageInfo >& in );
|
||||||
|
};
|
||||||
|
} // namespace fgl::engine
|
||||||
@@ -55,4 +55,6 @@ namespace fgl::engine::constants
|
|||||||
|
|
||||||
constexpr glm::vec3 DEFAULT_SCALE { 1.0f };
|
constexpr glm::vec3 DEFAULT_SCALE { 1.0f };
|
||||||
|
|
||||||
|
constexpr glm::vec3 SUN_DIR { 0.0f, 0.0f, 1.0f };
|
||||||
|
|
||||||
} // namespace fgl::engine::constants
|
} // namespace fgl::engine::constants
|
||||||
|
|||||||
@@ -9,7 +9,15 @@
|
|||||||
namespace fgl::engine::descriptors
|
namespace fgl::engine::descriptors
|
||||||
{
|
{
|
||||||
|
|
||||||
vk::raii::DescriptorPool createPool( std::uint32_t set_count )
|
static const std::unordered_map< vk::DescriptorType, float > DESCRIPTOR_ALLOCATION_RATIOS {
|
||||||
|
{ vk::DescriptorType::eUniformBuffer, 1.0f },
|
||||||
|
{ vk::DescriptorType::eCombinedImageSampler, 2.0f },
|
||||||
|
{ vk::DescriptorType::eStorageBuffer, 1.0f },
|
||||||
|
{ vk::DescriptorType::eInputAttachment, 0.5f },
|
||||||
|
{ vk::DescriptorType::eSampledImage, 2.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::raii::DescriptorPool createPool( const std::uint32_t set_count )
|
||||||
{
|
{
|
||||||
std::vector< vk::DescriptorPoolSize > pool_sizes {};
|
std::vector< vk::DescriptorPoolSize > pool_sizes {};
|
||||||
for ( auto& [ type, ratio ] : DESCRIPTOR_ALLOCATION_RATIOS )
|
for ( auto& [ type, ratio ] : DESCRIPTOR_ALLOCATION_RATIOS )
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ namespace fgl::engine
|
|||||||
namespace fgl::engine::descriptors
|
namespace fgl::engine::descriptors
|
||||||
{
|
{
|
||||||
|
|
||||||
static const std::unordered_map< vk::DescriptorType, float > DESCRIPTOR_ALLOCATION_RATIOS {
|
|
||||||
{ vk::DescriptorType::eUniformBuffer, 2.0f }, { vk::DescriptorType::eCombinedImageSampler, 2.0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
class DescriptorPool
|
class DescriptorPool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,16 +10,16 @@
|
|||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
class Camera;
|
class RenderCamera;
|
||||||
|
|
||||||
COMPONENT_CLASS( CameraComponent, CameraComponentID )
|
COMPONENT_CLASS( CameraComponent, CameraComponentID )
|
||||||
{
|
{
|
||||||
std::shared_ptr< Camera > m_camera;
|
std::shared_ptr< RenderCamera > m_camera;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CameraComponent() = delete;
|
CameraComponent() = delete;
|
||||||
CameraComponent( std::shared_ptr< Camera > & camera );
|
CameraComponent( std::shared_ptr< RenderCamera > & camera );
|
||||||
~CameraComponent();
|
~CameraComponent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
12
src/engine/lighting/lights/Sun.cpp
Normal file
12
src/engine/lighting/lights/Sun.cpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#include "Sun.hpp"
|
||||||
|
|
||||||
|
#include "camera/ShadowMap.hpp"
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
Sun::Sun() : m_shadowmap( createShadowmap( UniversalRotation::pointAt( constants::SUN_DIR ) ) )
|
||||||
|
{}
|
||||||
|
} // namespace fgl::engine
|
||||||
19
src/engine/lighting/lights/Sun.hpp
Normal file
19
src/engine/lighting/lights/Sun.hpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by kj16609 on 9/23/25.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace fgl::engine
|
||||||
|
{
|
||||||
|
class ShadowMap;
|
||||||
|
|
||||||
|
struct Sun
|
||||||
|
{
|
||||||
|
std::shared_ptr< ShadowMap > m_shadowmap;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Sun();
|
||||||
|
};
|
||||||
|
} // namespace fgl::engine
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by kj16609 on 2/17/25.
|
|
||||||
//
|
|
||||||
#include "ShadowMap.hpp"
|
|
||||||
|
|
||||||
#include "assets/image/Image.hpp"
|
|
||||||
#include "assets/texture/Texture.hpp"
|
|
||||||
|
|
||||||
namespace fgl::engine::shadows
|
|
||||||
{
|
|
||||||
|
|
||||||
std::shared_ptr< Image > getDepthImage( const vk::Extent2D extent )
|
|
||||||
{
|
|
||||||
constexpr auto format { vk::Format::eR16Unorm };
|
|
||||||
constexpr vk::ImageUsageFlags usage_flags { vk::ImageUsageFlagBits::eSampled
|
|
||||||
| vk::ImageUsageFlagBits::eDepthStencilAttachment };
|
|
||||||
constexpr auto inital_layout { vk::ImageLayout::eUndefined };
|
|
||||||
constexpr auto final_layout { vk::ImageLayout::eDepthReadOnlyOptimal };
|
|
||||||
|
|
||||||
return std::make_shared< Image >( extent, format, usage_flags, inital_layout, final_layout );
|
|
||||||
}
|
|
||||||
|
|
||||||
PerFrameArray< std::shared_ptr< Image > > createDepthImages( vk::Extent2D extent )
|
|
||||||
{
|
|
||||||
PerFrameArray< std::shared_ptr< Image > > array {};
|
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < array.size(); ++i ) array[ i ] = getDepthImage( extent );
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
PerFrameArray< std::shared_ptr< Texture > > ShadowMap::createDepthTargets()
|
|
||||||
{
|
|
||||||
PerFrameArray< std::shared_ptr< Texture > > array {};
|
|
||||||
|
|
||||||
Sampler default_sampler {};
|
|
||||||
for ( std::size_t i = 0; i < array.size(); ++i )
|
|
||||||
array[ i ] = std::make_shared< Texture >( m_image[ i ], std::move( default_sampler ) );
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShadowMap::renderForCamera( const Camera& camera )
|
|
||||||
{
|
|
||||||
// model -> world -> camera (identity) -> screen (shadow)
|
|
||||||
// since the camera in this case is the shadow map we just need to convert the screen space to world space. So we can just use an identity matrix
|
|
||||||
|
|
||||||
const Matrix< MatrixType::WorldToCamera > camera_matrix { m_transform.mat() };
|
|
||||||
const Matrix< MatrixType::CameraToScreen > identity { 1.0f };
|
|
||||||
|
|
||||||
const Matrix< MatrixType::WorldToScreen > matrix { camera_matrix * identity };
|
|
||||||
}
|
|
||||||
|
|
||||||
ShadowMap::ShadowMap( const vk::Extent2D extent ) :
|
|
||||||
m_image( createDepthImages( extent ) ),
|
|
||||||
m_target( createDepthTargets() )
|
|
||||||
{}
|
|
||||||
|
|
||||||
} // namespace fgl::engine::shadows
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by kj16609 on 2/17/25.
|
|
||||||
//
|
|
||||||
#pragma once
|
|
||||||
#include <vulkan/vulkan_raii.hpp>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "primitives/Transform.hpp"
|
|
||||||
#include "primitives/matricies/Matrix.hpp"
|
|
||||||
#include "primitives/matricies/MatrixEvolvedTypes.hpp"
|
|
||||||
#include "rendering/PresentSwapChain.hpp"
|
|
||||||
|
|
||||||
namespace fgl::engine
|
|
||||||
{
|
|
||||||
class Image;
|
|
||||||
class Texture;
|
|
||||||
} // namespace fgl::engine
|
|
||||||
|
|
||||||
namespace fgl::engine::shadows
|
|
||||||
{
|
|
||||||
|
|
||||||
class ShadowMap
|
|
||||||
{
|
|
||||||
PerFrameArray< std::shared_ptr< Image > > m_image;
|
|
||||||
PerFrameArray< std::shared_ptr< Texture > > m_target;
|
|
||||||
|
|
||||||
Matrix< MatrixType::WorldToScreen > m_matrix { 1.0f };
|
|
||||||
|
|
||||||
Transform< CoordinateSpace::World > m_transform {};
|
|
||||||
|
|
||||||
PerFrameArray< std::shared_ptr< Texture > > createDepthTargets();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void renderForCamera( const Camera& camera );
|
|
||||||
|
|
||||||
ShadowMap( vk::Extent2D extent );
|
|
||||||
~ShadowMap();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace fgl::engine::shadows
|
|
||||||
|
|
||||||
namespace fgl::engine
|
|
||||||
{
|
|
||||||
using namespace shadows;
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|
||||||
class Camera;
|
class RenderCamera;
|
||||||
|
|
||||||
//! Frustum constructed in model space (To be translated to a World space frustum later)
|
//! Frustum constructed in model space (To be translated to a World space frustum later)
|
||||||
struct FrustumBase
|
struct FrustumBase
|
||||||
@@ -60,7 +60,7 @@ namespace fgl::engine
|
|||||||
|
|
||||||
WorldCoordinate m_position {};
|
WorldCoordinate m_position {};
|
||||||
|
|
||||||
friend class Camera;
|
friend class RenderCamera;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
UniversalRotation UniversalRotation::pointAt( const glm::vec3 vec )
|
||||||
|
{
|
||||||
|
return UniversalRotation( QuatRotation( glm::normalize( vec ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
void UniversalRotation::addX( const float value )
|
void UniversalRotation::addX( const float value )
|
||||||
{
|
{
|
||||||
if ( isQuat() ) [[likely]]
|
if ( isQuat() ) [[likely]]
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ namespace fgl::engine
|
|||||||
return q_rotation;
|
return q_rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UniversalRotation pointAt( const glm::vec3 vec );
|
||||||
|
|
||||||
// Universal modification
|
// Universal modification
|
||||||
void addX( float value );
|
void addX( float value );
|
||||||
void addY( float value );
|
void addY( float value );
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ inline const static std::vector< const char* > DEVICE_EXTENSIONS = {
|
|||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, // Used for descriptor indexing
|
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, // Used for descriptor indexing
|
||||||
|
|
||||||
|
VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
|
||||||
|
|
||||||
// VK_EXT_MESH_SHADER_EXTENSION_NAME, // MAGICAL SHIT
|
// VK_EXT_MESH_SHADER_EXTENSION_NAME, // MAGICAL SHIT
|
||||||
VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME // Required until vulkan 1.4
|
VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME // Required until vulkan 1.4
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -168,45 +168,6 @@ namespace fgl::engine
|
|||||||
friend class RenderPassBuilder;
|
friend class RenderPassBuilder;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < std::size_t index, vk::ImageLayout layout >
|
|
||||||
struct InputAttachment
|
|
||||||
{
|
|
||||||
static constexpr bool is_input { true };
|
|
||||||
static constexpr vk::ImageLayout m_layout { layout };
|
|
||||||
static constexpr std::size_t m_index { index };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < std::size_t index, vk::ImageLayout layout >
|
|
||||||
struct UsedAttachment
|
|
||||||
{
|
|
||||||
static constexpr vk::ImageLayout m_layout { layout };
|
|
||||||
static constexpr std::size_t m_index { index };
|
|
||||||
static constexpr bool is_input { false };
|
|
||||||
};
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
concept is_input_attachment = requires( T a ) {
|
|
||||||
{ a.is_input } -> std::same_as< const bool& >;
|
|
||||||
{ a.m_layout } -> std::same_as< const vk::ImageLayout& >;
|
|
||||||
} && T::is_input;
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
concept is_used_attachment = requires( T a ) {
|
|
||||||
{ a.is_input } -> std::same_as< const bool& >;
|
|
||||||
{ a.m_layout } -> std::same_as< const vk::ImageLayout& >;
|
|
||||||
} && !T::is_input;
|
|
||||||
|
|
||||||
template < typename T > concept is_wrapped_attachment = is_input_attachment< T > || is_used_attachment< T >;
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
requires is_wrapped_attachment< T >
|
|
||||||
using UnwrappedAttachment = std::conditional_t< is_wrapped_attachment< T >, typename T::Attachment, T >;
|
|
||||||
|
|
||||||
//! Checks if the wrapped attachment is a depth attachment
|
|
||||||
template < typename T >
|
|
||||||
concept is_wrapped_depth_attachment = is_wrapped_attachment< T > && is_attachment< UnwrappedAttachment< T > >
|
|
||||||
&& ( T::m_layout == vk::ImageLayout::eDepthStencilAttachmentOptimal );
|
|
||||||
|
|
||||||
//Helper functions
|
//Helper functions
|
||||||
template < is_attachment Attachment, is_attachment... Attachments >
|
template < is_attachment Attachment, is_attachment... Attachments >
|
||||||
consteval std::uint32_t maxIndex()
|
consteval std::uint32_t maxIndex()
|
||||||
@@ -221,18 +182,6 @@ namespace fgl::engine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < is_attachment... Attachments >
|
|
||||||
static std::vector< vk::ImageView > getViewsForFrame( const FrameIndex frame_idx, Attachments... attachments )
|
|
||||||
{
|
|
||||||
std::vector< vk::ImageView > view {};
|
|
||||||
view.resize( sizeof...( Attachments ) );
|
|
||||||
static_assert( maxIndex< Attachments... >() + 1 == sizeof...( Attachments ) );
|
|
||||||
|
|
||||||
( ( view[ attachments.m_index ] = *attachments.getView( frame_idx ) ), ... );
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < is_attachment... Attachments >
|
template < is_attachment... Attachments >
|
||||||
static std::vector< vk::ClearValue > gatherClearValues( Attachments... attachments )
|
static std::vector< vk::ClearValue > gatherClearValues( Attachments... attachments )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,189 @@
|
|||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
vk::raii::PipelineLayout PipelineBuilder::createLayout()
|
||||||
|
{
|
||||||
|
vk::PipelineLayoutCreateInfo info {};
|
||||||
|
|
||||||
|
if ( m_state->push_constant.size > 0 ) info.setPushConstantRanges( m_state->push_constant );
|
||||||
|
|
||||||
|
std::vector< vk::DescriptorSetLayout > set_layouts {};
|
||||||
|
|
||||||
|
set_layouts.reserve( m_state->descriptor_set_layouts.size() );
|
||||||
|
|
||||||
|
SetID max_set_idx { 0 };
|
||||||
|
|
||||||
|
for ( const auto& [ set_idx, _ ] : m_state->descriptor_set_layouts )
|
||||||
|
{
|
||||||
|
max_set_idx = std::max( max_set_idx, set_idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any sets not used, Should be set to VK_NULL_HANDLE
|
||||||
|
set_layouts.resize( max_set_idx + 1 );
|
||||||
|
|
||||||
|
for ( std::size_t i = 0; i < set_layouts.size(); ++i )
|
||||||
|
{
|
||||||
|
auto itter { m_state->descriptor_set_layouts.find( static_cast< SetID >( i ) ) };
|
||||||
|
if ( itter == m_state->descriptor_set_layouts.end() )
|
||||||
|
{
|
||||||
|
// Could not find it. Empty
|
||||||
|
set_layouts[ i ] = m_empty_set_layout.layout();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_layouts[ i ] = itter->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( const auto& [ set_idx, layout ] : m_state->descriptor_set_layouts )
|
||||||
|
{
|
||||||
|
set_layouts[ set_idx ] = layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setSetLayouts( set_layouts );
|
||||||
|
|
||||||
|
return Device::getInstance()->createPipelineLayout( info );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::
|
||||||
|
addDescriptorSet( const SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout ) const
|
||||||
|
{
|
||||||
|
FGL_ASSERT( !m_state->descriptor_set_layouts.contains( idx ), "Descriptor already set! Conflicting SetIDs" );
|
||||||
|
m_state->descriptor_set_layouts.insert( std::make_pair( idx, *descriptor_set_layout ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::addDescriptorSet( descriptors::DescriptorSetLayout& descriptor )
|
||||||
|
{
|
||||||
|
addDescriptorSet( descriptor.m_set_idx, descriptor.layout() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::addDynamicState( vk::DynamicState dynamic_state )
|
||||||
|
{
|
||||||
|
m_state->m_dynamic_state.emplace_back( dynamic_state );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::setPushConstant( const vk::ShaderStageFlags flags, std::uint32_t size )
|
||||||
|
{
|
||||||
|
m_state->push_constant.offset = 0;
|
||||||
|
m_state->push_constant.size = size;
|
||||||
|
m_state->push_constant.stageFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::setBindPoint( vk::PipelineBindPoint bind_point )
|
||||||
|
{
|
||||||
|
m_state->bind_point = bind_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineBuilder::BuilderState::Formats::Formats()
|
||||||
|
{}
|
||||||
|
|
||||||
|
[[nodiscard]] vk::PipelineColorBlendAttachmentState& PipelineBuilder::BuilderState::addColorAttachment()
|
||||||
|
{
|
||||||
|
color_blend_attachment.emplace_back();
|
||||||
|
color_blend_info.setAttachments( color_blend_attachment );
|
||||||
|
return color_blend_attachment.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineBuilder::BuilderState::BuilderState( std::uint32_t subpass ) : m_subpass_stage( subpass )
|
||||||
|
{
|
||||||
|
setDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::BuilderState::setDefault()
|
||||||
|
{
|
||||||
|
viewport_info.viewportCount = 1;
|
||||||
|
viewport_info.pViewports = nullptr;
|
||||||
|
viewport_info.scissorCount = 1;
|
||||||
|
viewport_info.pScissors = nullptr;
|
||||||
|
|
||||||
|
assembly_info.topology = vk::PrimitiveTopology::eTriangleList;
|
||||||
|
assembly_info.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
|
rasterization_info.depthClampEnable = VK_FALSE;
|
||||||
|
rasterization_info.rasterizerDiscardEnable = VK_FALSE;
|
||||||
|
rasterization_info.polygonMode = vk::PolygonMode::eFill;
|
||||||
|
rasterization_info.cullMode = vk::CullModeFlagBits::eBack;
|
||||||
|
rasterization_info.frontFace = vk::FrontFace::eClockwise;
|
||||||
|
rasterization_info.depthBiasEnable = VK_FALSE;
|
||||||
|
rasterization_info.depthBiasConstantFactor = 0.0f;
|
||||||
|
rasterization_info.depthBiasClamp = 0.0f;
|
||||||
|
rasterization_info.depthBiasSlopeFactor = 0.0f;
|
||||||
|
rasterization_info.lineWidth = 1.0f;
|
||||||
|
|
||||||
|
multisample_info.rasterizationSamples = vk::SampleCountFlagBits::e1;
|
||||||
|
multisample_info.sampleShadingEnable = VK_FALSE;
|
||||||
|
multisample_info.minSampleShading = 1.0f;
|
||||||
|
multisample_info.pSampleMask = nullptr;
|
||||||
|
multisample_info.alphaToCoverageEnable = VK_FALSE;
|
||||||
|
multisample_info.alphaToOneEnable = VK_FALSE;
|
||||||
|
|
||||||
|
color_blend_info.logicOpEnable = VK_FALSE;
|
||||||
|
color_blend_info.logicOp = vk::LogicOp::eCopy;
|
||||||
|
color_blend_info.attachmentCount = 0;
|
||||||
|
color_blend_info.pAttachments = nullptr;
|
||||||
|
color_blend_info.blendConstants[ 0 ] = 0.0f;
|
||||||
|
color_blend_info.blendConstants[ 1 ] = 0.0f;
|
||||||
|
color_blend_info.blendConstants[ 2 ] = 0.0f;
|
||||||
|
color_blend_info.blendConstants[ 3 ] = 0.0f;
|
||||||
|
|
||||||
|
depth_stencil_info.depthTestEnable = VK_TRUE;
|
||||||
|
depth_stencil_info.depthWriteEnable = VK_TRUE;
|
||||||
|
depth_stencil_info.depthCompareOp = vk::CompareOp::eLess;
|
||||||
|
depth_stencil_info.depthBoundsTestEnable = VK_FALSE;
|
||||||
|
depth_stencil_info.stencilTestEnable = VK_FALSE;
|
||||||
|
//depth_stencil_info.front = {};
|
||||||
|
//depth_stencil_info.back = {};
|
||||||
|
depth_stencil_info.minDepthBounds = 0.0f;
|
||||||
|
depth_stencil_info.maxDepthBounds = 1.0f;
|
||||||
|
|
||||||
|
dynamic_state_enables = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||||
|
dynamic_state_info.setDynamicStates( dynamic_state_enables );
|
||||||
|
//info.dynamic_state_info.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::setTopology( const vk::PrimitiveTopology primitive_topology )
|
||||||
|
{
|
||||||
|
m_state->assembly_info.topology = primitive_topology;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::disableVertexInput()
|
||||||
|
{
|
||||||
|
m_state->vertex_input_descriptions.bindings = {};
|
||||||
|
m_state->vertex_input_descriptions.attributes = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::disableCulling()
|
||||||
|
{
|
||||||
|
m_state->rasterization_info.cullMode = vk::CullModeFlagBits::eNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::addDepthAttachment()
|
||||||
|
{
|
||||||
|
m_state->formats.depth = pickDepthFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachmentBuilder PipelineBuilder::addAttachment()
|
||||||
|
{
|
||||||
|
return { *this };
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachmentBuilder PipelineBuilder::addColorAttachment()
|
||||||
|
{
|
||||||
|
AttachmentBuilder builder { addAttachment() };
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions )
|
||||||
|
{
|
||||||
|
m_state->vertex_input_descriptions.bindings = descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::
|
||||||
|
setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions ) const
|
||||||
|
{
|
||||||
|
m_state->vertex_input_descriptions.attributes = descriptions;
|
||||||
|
}
|
||||||
|
|
||||||
PipelineBuilder::PipelineBuilder( std::uint32_t subpass ) : m_state( std::make_unique< BuilderState >( subpass ) )
|
PipelineBuilder::PipelineBuilder( std::uint32_t subpass ) : m_state( std::make_unique< BuilderState >( subpass ) )
|
||||||
{
|
{
|
||||||
addDynamicState( vk::DynamicState::eViewport );
|
addDynamicState( vk::DynamicState::eViewport );
|
||||||
@@ -87,6 +270,12 @@ namespace fgl::engine
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::raii::Pipeline PipelineBuilder::createDynamicPipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
|
||||||
|
{
|
||||||
|
if ( state.shaders.compute ) return createComputePipeline( state, layout );
|
||||||
|
return createGraphicsPipeline( state, layout );
|
||||||
|
}
|
||||||
|
|
||||||
vk::raii::Pipeline PipelineBuilder::createComputePipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
|
vk::raii::Pipeline PipelineBuilder::createComputePipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
|
||||||
{
|
{
|
||||||
vk::StructureChain< vk::ComputePipelineCreateInfo > chain {};
|
vk::StructureChain< vk::ComputePipelineCreateInfo > chain {};
|
||||||
@@ -106,12 +295,6 @@ namespace fgl::engine
|
|||||||
return Device::getInstance()->createComputePipeline( VK_NULL_HANDLE, info );
|
return Device::getInstance()->createComputePipeline( VK_NULL_HANDLE, info );
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::raii::Pipeline PipelineBuilder::createDynamicPipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
|
|
||||||
{
|
|
||||||
if ( state.shaders.compute ) return createComputePipeline( state, layout );
|
|
||||||
return createGraphicsPipeline( state, layout );
|
|
||||||
}
|
|
||||||
|
|
||||||
vk::raii::Pipeline PipelineBuilder::createGraphicsPipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
|
vk::raii::Pipeline PipelineBuilder::createGraphicsPipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
|
||||||
{
|
{
|
||||||
vk::StructureChain< vk::GraphicsPipelineCreateInfo, vk::PipelineRenderingCreateInfo > chain {};
|
vk::StructureChain< vk::GraphicsPipelineCreateInfo, vk::PipelineRenderingCreateInfo > chain {};
|
||||||
@@ -174,189 +357,6 @@ namespace fgl::engine
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::raii::PipelineLayout PipelineBuilder::createLayout()
|
|
||||||
{
|
|
||||||
vk::PipelineLayoutCreateInfo info {};
|
|
||||||
|
|
||||||
if ( m_state->push_constant.size > 0 ) info.setPushConstantRanges( m_state->push_constant );
|
|
||||||
|
|
||||||
std::vector< vk::DescriptorSetLayout > set_layouts {};
|
|
||||||
|
|
||||||
set_layouts.reserve( m_state->descriptor_set_layouts.size() );
|
|
||||||
|
|
||||||
SetID max_set_idx { 0 };
|
|
||||||
|
|
||||||
for ( const auto& [ set_idx, _ ] : m_state->descriptor_set_layouts )
|
|
||||||
{
|
|
||||||
max_set_idx = std::max( max_set_idx, set_idx );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any sets not used, Should be set to VK_NULL_HANDLE
|
|
||||||
set_layouts.resize( max_set_idx + 1 );
|
|
||||||
|
|
||||||
for ( std::size_t i = 0; i < set_layouts.size(); ++i )
|
|
||||||
{
|
|
||||||
auto itter { m_state->descriptor_set_layouts.find( static_cast< SetID >( i ) ) };
|
|
||||||
if ( itter == m_state->descriptor_set_layouts.end() )
|
|
||||||
{
|
|
||||||
// Could not find it. Empty
|
|
||||||
set_layouts[ i ] = m_empty_set_layout.layout();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set_layouts[ i ] = itter->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( const auto& [ set_idx, layout ] : m_state->descriptor_set_layouts )
|
|
||||||
{
|
|
||||||
set_layouts[ set_idx ] = layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.setSetLayouts( set_layouts );
|
|
||||||
|
|
||||||
return Device::getInstance()->createPipelineLayout( info );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::
|
|
||||||
addDescriptorSet( const SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout ) const
|
|
||||||
{
|
|
||||||
FGL_ASSERT( !m_state->descriptor_set_layouts.contains( idx ), "Descriptor already set!" );
|
|
||||||
m_state->descriptor_set_layouts.insert( std::make_pair( idx, *descriptor_set_layout ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::addDescriptorSet( descriptors::DescriptorSetLayout& descriptor )
|
|
||||||
{
|
|
||||||
addDescriptorSet( descriptor.m_set_idx, descriptor.layout() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::addDynamicState( vk::DynamicState dynamic_state )
|
|
||||||
{
|
|
||||||
m_state->m_dynamic_state.emplace_back( dynamic_state );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::setPushConstant( const vk::ShaderStageFlags flags, std::uint32_t size )
|
|
||||||
{
|
|
||||||
m_state->push_constant.offset = 0;
|
|
||||||
m_state->push_constant.size = size;
|
|
||||||
m_state->push_constant.stageFlags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::setBindPoint( vk::PipelineBindPoint bind_point )
|
|
||||||
{
|
|
||||||
m_state->bind_point = bind_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
PipelineBuilder::BuilderState::Formats::Formats()
|
|
||||||
{}
|
|
||||||
|
|
||||||
[[nodiscard]] vk::PipelineColorBlendAttachmentState& PipelineBuilder::BuilderState::addColorAttachment()
|
|
||||||
{
|
|
||||||
color_blend_attachment.emplace_back();
|
|
||||||
color_blend_info.setAttachments( color_blend_attachment );
|
|
||||||
return color_blend_attachment.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::BuilderState::setDefault()
|
|
||||||
{
|
|
||||||
viewport_info.viewportCount = 1;
|
|
||||||
viewport_info.pViewports = nullptr;
|
|
||||||
viewport_info.scissorCount = 1;
|
|
||||||
viewport_info.pScissors = nullptr;
|
|
||||||
|
|
||||||
assembly_info.topology = vk::PrimitiveTopology::eTriangleList;
|
|
||||||
assembly_info.primitiveRestartEnable = VK_FALSE;
|
|
||||||
|
|
||||||
rasterization_info.depthClampEnable = VK_FALSE;
|
|
||||||
rasterization_info.rasterizerDiscardEnable = VK_FALSE;
|
|
||||||
rasterization_info.polygonMode = vk::PolygonMode::eFill;
|
|
||||||
rasterization_info.cullMode = vk::CullModeFlagBits::eBack;
|
|
||||||
rasterization_info.frontFace = vk::FrontFace::eClockwise;
|
|
||||||
rasterization_info.depthBiasEnable = VK_FALSE;
|
|
||||||
rasterization_info.depthBiasConstantFactor = 0.0f;
|
|
||||||
rasterization_info.depthBiasClamp = 0.0f;
|
|
||||||
rasterization_info.depthBiasSlopeFactor = 0.0f;
|
|
||||||
rasterization_info.lineWidth = 1.0f;
|
|
||||||
|
|
||||||
multisample_info.rasterizationSamples = vk::SampleCountFlagBits::e1;
|
|
||||||
multisample_info.sampleShadingEnable = VK_FALSE;
|
|
||||||
multisample_info.minSampleShading = 1.0f;
|
|
||||||
multisample_info.pSampleMask = nullptr;
|
|
||||||
multisample_info.alphaToCoverageEnable = VK_FALSE;
|
|
||||||
multisample_info.alphaToOneEnable = VK_FALSE;
|
|
||||||
|
|
||||||
color_blend_info.logicOpEnable = VK_FALSE;
|
|
||||||
color_blend_info.logicOp = vk::LogicOp::eCopy;
|
|
||||||
color_blend_info.attachmentCount = 0;
|
|
||||||
color_blend_info.pAttachments = nullptr;
|
|
||||||
color_blend_info.blendConstants[ 0 ] = 0.0f;
|
|
||||||
color_blend_info.blendConstants[ 1 ] = 0.0f;
|
|
||||||
color_blend_info.blendConstants[ 2 ] = 0.0f;
|
|
||||||
color_blend_info.blendConstants[ 3 ] = 0.0f;
|
|
||||||
|
|
||||||
depth_stencil_info.depthTestEnable = VK_TRUE;
|
|
||||||
depth_stencil_info.depthWriteEnable = VK_TRUE;
|
|
||||||
depth_stencil_info.depthCompareOp = vk::CompareOp::eLess;
|
|
||||||
depth_stencil_info.depthBoundsTestEnable = VK_FALSE;
|
|
||||||
depth_stencil_info.stencilTestEnable = VK_FALSE;
|
|
||||||
//depth_stencil_info.front = {};
|
|
||||||
//depth_stencil_info.back = {};
|
|
||||||
depth_stencil_info.minDepthBounds = 0.0f;
|
|
||||||
depth_stencil_info.maxDepthBounds = 1.0f;
|
|
||||||
|
|
||||||
dynamic_state_enables = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
|
||||||
dynamic_state_info.setDynamicStates( dynamic_state_enables );
|
|
||||||
//info.dynamic_state_info.flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PipelineBuilder::BuilderState::BuilderState( std::uint32_t subpass ) : m_subpass_stage( subpass )
|
|
||||||
{
|
|
||||||
setDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::setTopology( const vk::PrimitiveTopology primitive_topology )
|
|
||||||
{
|
|
||||||
m_state->assembly_info.topology = primitive_topology;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::disableVertexInput()
|
|
||||||
{
|
|
||||||
m_state->vertex_input_descriptions.bindings = {};
|
|
||||||
m_state->vertex_input_descriptions.attributes = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::disableCulling()
|
|
||||||
{
|
|
||||||
m_state->rasterization_info.cullMode = vk::CullModeFlagBits::eNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::addDepthAttachment()
|
|
||||||
{
|
|
||||||
m_state->formats.depth = pickDepthFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
AttachmentBuilder PipelineBuilder::addAttachment()
|
|
||||||
{
|
|
||||||
return { *this };
|
|
||||||
}
|
|
||||||
|
|
||||||
AttachmentBuilder PipelineBuilder::addColorAttachment()
|
|
||||||
{
|
|
||||||
AttachmentBuilder builder { addAttachment() };
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions )
|
|
||||||
{
|
|
||||||
m_state->vertex_input_descriptions.bindings = descriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PipelineBuilder::
|
|
||||||
setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions ) const
|
|
||||||
{
|
|
||||||
m_state->vertex_input_descriptions.attributes = descriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
vk::raii::Pipeline PipelineBuilder::createFromState( BuilderState& state, vk::raii::PipelineLayout& layout )
|
vk::raii::Pipeline PipelineBuilder::createFromState( BuilderState& state, vk::raii::PipelineLayout& layout )
|
||||||
{
|
{
|
||||||
return createDynamicPipeline( state, layout );
|
return createDynamicPipeline( state, layout );
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Created by kj16609 on 2/28/25.
|
// Created by kj16609 on 2/28/25.
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "camera/Camera.hpp"
|
#include "camera/RenderCamera.hpp"
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "assets/model/Model.hpp"
|
#include "assets/model/Model.hpp"
|
||||||
#include "engine/FrameInfo.hpp"
|
#include "engine/FrameInfo.hpp"
|
||||||
#include "engine/camera/Camera.hpp"
|
#include "engine/camera/RenderCamera.hpp"
|
||||||
|
|
||||||
namespace fgl::engine
|
namespace fgl::engine
|
||||||
{
|
{
|
||||||
@@ -44,7 +44,7 @@ namespace fgl::engine
|
|||||||
CullingSystem::~CullingSystem()
|
CullingSystem::~CullingSystem()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CullingSystem::pass( FrameInfo& info )
|
void CullingSystem::pass( const FrameInfo& info )
|
||||||
{
|
{
|
||||||
ZoneScopedN( "Culling pass" );
|
ZoneScopedN( "Culling pass" );
|
||||||
|
|
||||||
@@ -61,10 +61,13 @@ namespace fgl::engine
|
|||||||
|
|
||||||
m_cull_compute->bindDescriptor( command_buffer, info.m_primitives_desc ); // primitive set
|
m_cull_compute->bindDescriptor( command_buffer, info.m_primitives_desc ); // primitive set
|
||||||
m_cull_compute->bindDescriptor( command_buffer, info.m_instances_desc ); // instances
|
m_cull_compute->bindDescriptor( command_buffer, info.m_instances_desc ); // instances
|
||||||
m_cull_compute->bindDescriptor( command_buffer, info.m_command_buffer_desc ); // commands output
|
m_cull_compute->bindDescriptor(
|
||||||
|
command_buffer, *info.camera->m_gpu_draw_cmds_desc[ info.in_flight_idx ] ); // commands output
|
||||||
|
|
||||||
|
auto& commands { info.camera->m_gpu_draw_commands[ info.in_flight_idx ] };
|
||||||
|
commands.resize( info.instances.size() );
|
||||||
CullPushConstants push_constants {};
|
CullPushConstants push_constants {};
|
||||||
push_constants.draw_count = info.m_commands.size();
|
push_constants.draw_count = commands.size();
|
||||||
|
|
||||||
command_buffer->pushConstants<
|
command_buffer->pushConstants<
|
||||||
CullPushConstants >( m_cull_compute->layout(), vk::ShaderStageFlagBits::eCompute, 0, { push_constants } );
|
CullPushConstants >( m_cull_compute->layout(), vk::ShaderStageFlagBits::eCompute, 0, { push_constants } );
|
||||||
@@ -76,7 +79,7 @@ namespace fgl::engine
|
|||||||
|
|
||||||
command_buffer->dispatch( group_count, 1, 1 );
|
command_buffer->dispatch( group_count, 1, 1 );
|
||||||
|
|
||||||
// Add a memory barrier to ensure synchronization between the compute and subsequent stages
|
// Add a memory barrier to ensure synchronization between the compute and later stages
|
||||||
vk::MemoryBarrier memory_barrier {
|
vk::MemoryBarrier memory_barrier {
|
||||||
vk::AccessFlagBits::eShaderWrite,
|
vk::AccessFlagBits::eShaderWrite,
|
||||||
vk::AccessFlagBits::eVertexAttributeRead | vk::AccessFlagBits::eIndirectCommandRead,
|
vk::AccessFlagBits::eVertexAttributeRead | vk::AccessFlagBits::eIndirectCommandRead,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace fgl::engine
|
|||||||
|
|
||||||
~CullingSystem();
|
~CullingSystem();
|
||||||
|
|
||||||
void pass( FrameInfo& info );
|
void pass( const FrameInfo& info );
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert( is_system< CullingSystem > );
|
static_assert( is_system< CullingSystem > );
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "EngineContext.hpp"
|
#include "EngineContext.hpp"
|
||||||
#include "assets/model/ModelVertex.hpp"
|
#include "assets/model/ModelVertex.hpp"
|
||||||
#include "engine/assets/material/Material.hpp"
|
#include "engine/assets/material/Material.hpp"
|
||||||
#include "engine/camera/Camera.hpp"
|
#include "engine/camera/RenderCamera.hpp"
|
||||||
#include "engine/debug/timing/FlameGraph.hpp"
|
#include "engine/debug/timing/FlameGraph.hpp"
|
||||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||||
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
|
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
|
||||||
@@ -29,7 +29,7 @@ namespace fgl::engine
|
|||||||
|
|
||||||
addGBufferAttachments( builder );
|
addGBufferAttachments( builder );
|
||||||
|
|
||||||
builder.addDescriptorSet( Camera::getDescriptorLayout() );
|
builder.addDescriptorSet( RenderCamera::getDescriptorLayout() );
|
||||||
builder.addDescriptorSet( Texture::getDescriptorLayout() );
|
builder.addDescriptorSet( Texture::getDescriptorLayout() );
|
||||||
builder.addDescriptorSet( Material::getDescriptorLayout() );
|
builder.addDescriptorSet( Material::getDescriptorLayout() );
|
||||||
|
|
||||||
@@ -92,18 +92,17 @@ namespace fgl::engine
|
|||||||
|
|
||||||
const std::vector< vk::Buffer > vert_buffers {
|
const std::vector< vk::Buffer > vert_buffers {
|
||||||
model_buffers.m_vertex_buffer->getVkBuffer(),
|
model_buffers.m_vertex_buffer->getVkBuffer(),
|
||||||
model_buffers.m_generated_instance_info[ info.in_flight_idx ].getVkBuffer()
|
info.camera->m_generated_instance_info[ info.in_flight_idx ].getVkBuffer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
command_buffer->bindVertexBuffers(
|
command_buffer->bindVertexBuffers(
|
||||||
0, vert_buffers, { 0, model_buffers.m_generated_instance_info[ info.in_flight_idx ].getOffset() } );
|
0, vert_buffers, { 0, info.camera->m_generated_instance_info[ info.in_flight_idx ].getOffset() } );
|
||||||
command_buffer->bindIndexBuffer( model_buffers.m_index_buffer->getVkBuffer(), 0, vk::IndexType::eUint32 );
|
command_buffer->bindIndexBuffer( model_buffers.m_index_buffer->getVkBuffer(), 0, vk::IndexType::eUint32 );
|
||||||
|
|
||||||
command_buffer->drawIndexedIndirect(
|
const auto& commands { info.camera->m_gpu_draw_commands[ info.in_flight_idx ] };
|
||||||
info.m_commands.getVkBuffer(),
|
|
||||||
info.m_commands.getOffset(),
|
command_buffer
|
||||||
info.m_commands.size(),
|
->drawIndexedIndirect( commands.getVkBuffer(), commands.getOffset(), commands.size(), commands.stride() );
|
||||||
info.m_commands.stride() );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fgl::engine
|
} // namespace fgl::engine
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "engine/FrameInfo.hpp"
|
#include "engine/FrameInfo.hpp"
|
||||||
#include "engine/assets/model/SimpleVertex.hpp"
|
#include "engine/assets/model/SimpleVertex.hpp"
|
||||||
#include "engine/camera/Camera.hpp"
|
#include "engine/camera/RenderCamera.hpp"
|
||||||
#include "engine/debug/drawers.hpp"
|
#include "engine/debug/drawers.hpp"
|
||||||
#include "engine/primitives/points/Coordinate.hpp"
|
#include "engine/primitives/points/Coordinate.hpp"
|
||||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||||
@@ -27,7 +27,7 @@ namespace fgl::engine
|
|||||||
{
|
{
|
||||||
PipelineBuilder builder { 0 };
|
PipelineBuilder builder { 0 };
|
||||||
|
|
||||||
builder.addDescriptorSet( Camera::getDescriptorLayout() );
|
builder.addDescriptorSet( RenderCamera::getDescriptorLayout() );
|
||||||
|
|
||||||
addGBufferAttachments( builder );
|
addGBufferAttachments( builder );
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
import objects.camera;
|
import objects.camera;
|
||||||
|
import objects.gbuffer;
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
vec4 position : SV_Position;
|
vec4 position : SV_Position;
|
||||||
@@ -24,13 +25,6 @@ struct CompositeFragment {
|
|||||||
vec4 color;
|
vec4 color;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBufferInput {
|
|
||||||
SubpassInput<vec4> color : COLOR;
|
|
||||||
SubpassInput<vec4> position : POSITION;
|
|
||||||
SubpassInput<vec4> normal : NORMAL;
|
|
||||||
SubpassInput<vec4> metallic : METALLIC;
|
|
||||||
SubpassInput<vec4> emissive : EMISSIVE;
|
|
||||||
};
|
|
||||||
|
|
||||||
// SubpassInput< vec4 > test : TEST;
|
// SubpassInput< vec4 > test : TEST;
|
||||||
|
|
||||||
@@ -46,6 +40,12 @@ ParameterBlock<GBufferInput> gbuffer : GBUFFER;
|
|||||||
[[vk::binding(0,1)]]
|
[[vk::binding(0,1)]]
|
||||||
ParameterBlock< CameraData > camera : CAMERA;
|
ParameterBlock< CameraData > camera : CAMERA;
|
||||||
|
|
||||||
|
[[vk::binding(0,2)]]
|
||||||
|
ParameterBlock< CameraData > sun_camera;
|
||||||
|
|
||||||
|
[[vk::binding(1,2)]]
|
||||||
|
Sampler2D shadow_sampler;
|
||||||
|
|
||||||
//TODO: constant flags
|
//TODO: constant flags
|
||||||
|
|
||||||
// Direction the sun is facing
|
// Direction the sun is facing
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void computeMain( uint3 dispatch_id : SV_DispatchThreadID)
|
|||||||
out_instances[ instance_index ].material_id = instance.material_id;
|
out_instances[ instance_index ].material_id = instance.material_id;
|
||||||
|
|
||||||
const ModelInstanceInfo model_instance = model_instances[ instance.model_index ];
|
const ModelInstanceInfo model_instance = model_instances[ instance.model_index ];
|
||||||
out_instances[ instance_index ].model_matrix = model_instance.model_matrix;
|
out_instances[ instance_index ].model_matrix = {model_instance.model_matrix};
|
||||||
// out_instances[ instance_index ].normal_matrix = model_instance.normal_matrix;
|
// out_instances[ instance_index ].normal_matrix = model_instance.normal_matrix;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ public struct CameraData
|
|||||||
return vec3( inverse_view[ 0 ][ 3 ], inverse_view[ 1 ][ 3 ], inverse_view[ 2 ][ 3 ] );
|
return vec3( inverse_view[ 0 ][ 3 ], inverse_view[ 1 ][ 3 ], inverse_view[ 2 ][ 3 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public vec4 toCameraSpace(const vec4 world_coordinate)
|
||||||
|
{
|
||||||
|
return mul(mat(), world_coordinate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public mat4x4 mat()
|
public mat4x4 mat()
|
||||||
{
|
{
|
||||||
return mul( projection, view );
|
return mul( projection, view );
|
||||||
|
|||||||
@@ -11,6 +11,41 @@ public struct PrimitiveRenderInfo {
|
|||||||
public uint32_t index_count;
|
public uint32_t index_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public struct ModelMatrix
|
||||||
|
{
|
||||||
|
mat4x4 matrix;
|
||||||
|
|
||||||
|
public mat3 toNormalMatrix()
|
||||||
|
{
|
||||||
|
return transpose( inverse( mat3( matrix ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public vec3 normalizeNormal( vec3 normal )
|
||||||
|
{
|
||||||
|
return normalize( mul( toNormalMatrix(), normal ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public vec4 toWorldSpace( vec4 position )
|
||||||
|
{
|
||||||
|
return mul(matrix, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public __init( mat4x4 matrix_in )
|
||||||
|
{
|
||||||
|
matrix = matrix_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
public mat4x4 mat()
|
||||||
|
{
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ModelMatrix operator=(mat4x4 matrix)
|
||||||
|
{
|
||||||
|
return {matrix};
|
||||||
|
}
|
||||||
|
|
||||||
// Each primitive has one instance
|
// Each primitive has one instance
|
||||||
public struct PrimitiveInstanceInfo
|
public struct PrimitiveInstanceInfo
|
||||||
{
|
{
|
||||||
@@ -22,7 +57,7 @@ public struct PrimitiveInstanceInfo
|
|||||||
// One object exists for each render instance
|
// One object exists for each render instance
|
||||||
public struct InstanceRenderInfo
|
public struct InstanceRenderInfo
|
||||||
{
|
{
|
||||||
public mat4x4 model_matrix;
|
public ModelMatrix model_matrix;
|
||||||
// public mat4x4 normal_matrix;
|
// public mat4x4 normal_matrix;
|
||||||
public uint32_t material_id;
|
public uint32_t material_id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,3 +11,10 @@ public struct GBufferFragment
|
|||||||
public vec3 emissive : EMISSIVE;
|
public vec3 emissive : EMISSIVE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public struct GBufferInput {
|
||||||
|
public SubpassInput<vec4> color : COLOR;
|
||||||
|
public SubpassInput<vec4> position : POSITION;
|
||||||
|
public SubpassInput<vec4> normal : NORMAL;
|
||||||
|
public SubpassInput<vec4> metallic : METALLIC;
|
||||||
|
public SubpassInput<vec4> emissive : EMISSIVE;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,15 +1,36 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
import model.vertex;
|
import model.vertex;
|
||||||
|
import objects.camera;
|
||||||
|
|
||||||
struct CoarseVertex {
|
struct CoarseVertex {
|
||||||
float4 position : SV_Position;
|
float4 position : SV_Position;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
struct Fragment
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
[ [ vk::binding( 0, 1 ) ] ]
|
||||||
|
ConstantBuffer< CameraData > camera : CAMERA;
|
||||||
|
|
||||||
[shader("vertex")]
|
[shader("vertex")]
|
||||||
CoarseVertex vertexMain( ModelVertex in_vertex )
|
CoarseVertex vertexMain(ModelVertex in_vertex)
|
||||||
{
|
{
|
||||||
|
CoarseVertex out_vertex;
|
||||||
|
|
||||||
|
vec4 world_pos = in_vertex.instance.model_matrix.toWorldSpace( vec4(in_vertex.simple.position, 1.0) );
|
||||||
|
|
||||||
|
out_vertex.position = camera.toCameraSpace( world_pos );
|
||||||
|
|
||||||
|
return out_vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[shader("fragment")]
|
||||||
|
Fragment fragmentMain(CoarseVertex vertex)
|
||||||
|
{
|
||||||
|
Fragment fragment;
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,18 +23,20 @@ CoarseVertex vertexMain( ModelVertex in_vertex )
|
|||||||
{
|
{
|
||||||
CoarseVertex out_vertex;
|
CoarseVertex out_vertex;
|
||||||
|
|
||||||
vec4 world_pos = mul(in_vertex.instance.model_matrix, vec4(in_vertex.simple.position, 1.0));
|
// vec4 world_pos = mul(in_vertex.instance.model_matrix, vec4(in_vertex.simple.position, 1.0));
|
||||||
|
vec4 world_pos = in_vertex.instance.model_matrix.toWorldSpace( vec4(in_vertex.simple.position, 1.0) );
|
||||||
const float4 transformed_pos = mul( camera.mat(), world_pos );
|
|
||||||
out_vertex.position = transformed_pos;
|
|
||||||
out_vertex.world_pos = world_pos.xyz;
|
out_vertex.world_pos = world_pos.xyz;
|
||||||
|
|
||||||
mat3 normal_matrix = transpose( inverse( mat3( in_vertex.instance.model_matrix ) ) );
|
out_vertex.position = camera.toCameraSpace( world_pos) ;
|
||||||
|
|
||||||
out_vertex.normal = normalize( mul(normal_matrix, in_vertex.normal) );
|
// mat3 normal_matrix = transpose( inverse( mat3( in_vertex.instance.model_matrix ) ) );
|
||||||
|
mat3 normal_matrix = in_vertex.instance.model_matrix.toNormalMatrix();
|
||||||
|
|
||||||
|
// out_vertex.normal = normalize( mul(normal_matrix, in_vertex.normal) );
|
||||||
|
out_vertex.normal = in_vertex.instance.model_matrix.normalizeNormal( in_vertex.normal );
|
||||||
out_vertex.tex_coord = in_vertex.uv;
|
out_vertex.tex_coord = in_vertex.uv;
|
||||||
out_vertex.material_id = in_vertex.instance.material_id;
|
out_vertex.material_id = in_vertex.instance.material_id;
|
||||||
out_vertex.matrix = in_vertex.instance.model_matrix;
|
out_vertex.matrix = in_vertex.instance.model_matrix.mat();
|
||||||
out_vertex.tangent = in_vertex.tangent;
|
out_vertex.tangent = in_vertex.tangent;
|
||||||
|
|
||||||
return out_vertex;
|
return out_vertex;
|
||||||
|
|||||||
Reference in New Issue
Block a user