Spot started

This commit is contained in:
Confideo-IOM
2026-08-04 22:40:48 +01:00
parent f51b435a9d
commit 6d7d7571b5
48 changed files with 1086 additions and 1222 deletions
@@ -321,12 +321,12 @@ float SampleShadow(vec4 frag_clip_space, sampler2DArray sampler_shadow_map, uint
vec3 CalculateDirectionalShadow(vec4 world_pos, uint shadow_idx, vec3 normal, vec3 light_dir, vec3 viewer_pos)
{
float shadow = 0;
float shadow = 1;
//measure the distance of the fragment from the light
float frag_distance = abs(length(viewer_pos - world_pos.xyz));
uint shadow_trans_idx = 5;
uint shadow_trans_idx = 6;
uint ignore_shadow = 0;
//Work out which shadowmap is appropriate for this distance
for(uint i = 0; i < 6; i++)
@@ -340,7 +340,7 @@ vec3 CalculateDirectionalShadow(vec4 world_pos, uint shadow_idx, vec3 normal, ve
break;
}
}
if(ignore_shadow == 1)
{
vec4 translated_pixel = shadows[shadow_idx].light_space_proj[shadow_trans_idx] *
@@ -348,21 +348,29 @@ vec3 CalculateDirectionalShadow(vec4 world_pos, uint shadow_idx, vec3 normal, ve
world_pos;
uvec2 shadow_handle = textures[shadows[shadow_idx].shadow_texture_id];
shadow = 1.0 - SampleShadow(translated_pixel, sampler2DArray(shadow_handle), shadow_trans_idx, normal, light_dir);
}
return vec3(shadow);
//return 1.0 - shadow;
if(shadow_trans_idx == 0)
{
return vec3(1,0,0) * shadow;
}
if(shadow_trans_idx == 1)
{
return vec3(0,1,0) * shadow;
return vec3(1,1,0) * shadow;
}
if(shadow_trans_idx == 2)
{
return vec3(0,0,1) * shadow;
return vec3(0.5,0.5,1) * shadow;
}
if(shadow_trans_idx == 3)
{
return vec3(1,0,1) * shadow;
}
if(shadow_trans_idx == 4)
{
return vec3(1,1,1) * shadow;
}
return vec3(0,1,1) * shadow;
}
@@ -50,7 +50,7 @@ void main()
diffuse_val = diffuse_val * texture(sampler2D(diffuse_handle), geom_out.vsUV.xy);
if(mat.diffuse_texture_id== 10)
{
output_colour = vec4(0,0,1,1);
output_colour = vec4(0,0,1,1);
}
}
@@ -0,0 +1,63 @@
//*PIXEL*
#version 460
#extension GL_ARB_bindless_texture : require
const uint DIRECTIONAL_LIGHT = 1;
const uint POINT_LIGHT = 2;
const uint SPOT_LIGHT = 3;
uint INVALID_HYDRA_ID = 4294967295;
struct MaterialStore
{
vec4 diffuse_colour;
vec4 matalic_rough;
uint diffuse_texture_id;
uint metallic_rough_texture_id;
uint normal_texture_id;
uint padding[1];
};
layout(std430, binding = 2) readonly buffer material_buffer
{
MaterialStore materials[1000];
};
layout(std430, binding = 3) readonly buffer texture_buffer
{
uvec2 textures[1000];
};
layout (location=0) in VS_OUT
{
vec2 vsUV;
flat uint vsMaterialID;
}vs_out;
layout (location=0) out vec4 output_colour;
void main()
{
MaterialStore mat = materials[vs_out.vsMaterialID];
vec4 diffuse_val = mat.diffuse_colour;
output_colour = vec4(1,0,0,1);
if(mat.diffuse_texture_id != INVALID_HYDRA_ID)
{
output_colour = vec4(0,1,0,1);
uvec2 diffuse_handle = textures[mat.diffuse_texture_id];
diffuse_val = diffuse_val * texture(sampler2D(diffuse_handle), vs_out.vsUV.xy);
if(mat.diffuse_texture_id== 10)
{
output_colour = vec4(0,0,1,1);
}
}
if(diffuse_val[3] < 1.0)
{
discard;
output_colour = vec4(0,1,1,1);
}
}
@@ -0,0 +1,30 @@
//*VERTEX*
#version 460
layout(binding = 1) readonly buffer positions_buffer
{
mat4 model_matrix[];
};
layout (location = 0) in vec3 inPos; //12 bytes : 0
layout (location = 1) in vec2 inUV; //8 Bytes : 12
layout (location = 2) in uvec3 inChunkID; //12 Bytes : 20
layout (location = 3) in vec3 inNormal; //8 Bytes : 12
layout (location = 4) in vec3 inBiTangent;
layout (location = 5) in vec3 inTangent;
layout (location=0) out VS_OUT
{
vec2 vsUV;
flat uint vsMaterialID;
}vs_out;
void main()
{
uint chunkid = inChunkID[0];
mat4 model = model_matrix[chunkid];
gl_Position = model * vec4(inPos, 1.0);
vs_out.vsUV = inUV;
vs_out.vsMaterialID = inChunkID[1];
}
@@ -8,7 +8,7 @@
#include "../ecs/components/HydraRenderableComponent.h"
#include "../ecs/components/HydraMaterialComponent.h"
#include "../ecs/components/HydraLightComponent.h"
#include "../ecs/components/HydraDirectionalShadowSourceComponent.h"
#include "../ecs/components/HydraSpotShadowSourceComponent.h"
#include "../buffer/HydraLightBufferManager.h"
#include "../buffer/HydraLightBuffer.h"
@@ -33,8 +33,8 @@ void HydraSpotLightActor::InitialiseComponents()
HydraPositionComponent position_component;
ecs->AddComponent<HydraPositionComponent>(GetID(), position_component);
HydraDirectionalShadowSourceComponent shadow_component = {};
ecs->AddComponent<HydraDirectionalShadowSourceComponent>(GetID(), shadow_component);
HydraSpotShadowSourceComponent shadow_component = {};
ecs->AddComponent<HydraSpotShadowSourceComponent>(GetID(), shadow_component);
}
void HydraSpotLightActor::Destroy()
@@ -0,0 +1,16 @@
#ifndef HYDRASPOTSHADOWCOMPONENT
#define HYDRASPOTSHADOWCOMPONENT
#include "../../engine/HydraEngine.h"
struct HydraSpotShadowSourceComponent
{
uint32_t entity_id;
uint32_t shadow_texture_id;
uint32_t frame_buffer_id;
float far_plane;
glm::mat4 light_space_proj;
glm::mat4 light_space_view;
};
#endif /* HYDRASPOTSHADOWCOMPONENT */
@@ -50,12 +50,8 @@ void HydraDirectionalShadowSourceSystem::InitialiseComponent(HydraID entity_id)
light_comp.shadow_caster = 1;
}
switch (light_comp.light_type)
{
case (int)HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL:
_InitialiseDirectionalLight(entity_id);
break;
}
_InitialiseShadowMap(entity_id);
}
@@ -68,12 +64,8 @@ void HydraDirectionalShadowSourceSystem::UpdateSystem(float delta_t_seconds)
{
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
switch (light_comp.light_type)
{
case (int)HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL:
_UpdateDirectionalLight(entity_id);
break;
}
_UpdateShadowMap(entity_id);
HydraDirectionalShadowSourceComponent shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
m_shadows[light_comp.shadow_map_id] = shad_comp;
@@ -81,19 +73,16 @@ void HydraDirectionalShadowSourceSystem::UpdateSystem(float delta_t_seconds)
_WriteToGPU();
}
void HydraDirectionalShadowSourceSystem::_UpdateDirectionalLight(HydraID entity_id)
void HydraDirectionalShadowSourceSystem::_UpdateShadowMap(HydraID entity_id)
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraPositionComponent pos_comp = ecs->GetComponent<HydraPositionComponent>(entity_id);
HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
float view_size = 20.0f;
float view_size = 4.0f;
float view_near = 0.1f;
float view_far = 20.0f;
float PI = 3.1415927;
float TWO_PI = 6.2831854;
float view_far = 4.0f;
glm::mat4 light_rot = glm::eulerAngleXYZ(pos_comp.orientation.x, pos_comp.orientation.y, pos_comp.orientation.z);
glm::vec3 light_dir = glm::normalize(glm::vec3(light_rot * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)));
@@ -102,7 +91,7 @@ void HydraDirectionalShadowSourceSystem::_UpdateDirectionalLight(HydraID entity_
for (uint32_t i = 0; i < 6; i++)
{
glm::vec3 light_pos = camera_pos - (light_dir * 2.0f);
glm::vec3 light_pos = camera_pos;//- (light_dir * 2.0f);
glm::vec3 target_pos = light_pos + light_dir;
glm::vec3 up_vector = glm::vec3(0.0f, 1.0f, 0.0f);
@@ -121,20 +110,19 @@ void HydraDirectionalShadowSourceSystem::_UpdateDirectionalLight(HydraID entity_
shad_comp.light_space_view[i] = view;
// Scale bounds exponentially for the next cascade tier
view_size *= 3.5f;
view_far *= 3.5f;
view_size *= 3.0f;
view_far *= 3.0f;
}
}
void HydraDirectionalShadowSourceSystem::_InitialiseDirectionalLight(HydraID entity_id)
void HydraDirectionalShadowSourceSystem::_InitialiseShadowMap(HydraID entity_id)
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTextureBufferManager *tex_man = engine->TextureBufferManager();
HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
shad_comp.entity_id = entity_id;
shad_comp.cascade_count = 6;
@@ -16,8 +16,8 @@ class HydraDirectionalShadowSourceSystem : public HydraSystem
void InitialiseComponent(HydraID entity_id) override;
void UpdateSystem(float delta_t_seconds) override;
private:
void _UpdateDirectionalLight(HydraID entity_id);
void _InitialiseDirectionalLight(HydraID entity_id);
void _UpdateShadowMap(HydraID entity_id);
void _InitialiseShadowMap(HydraID entity_id);
void _WriteToGPU();
HydraID m_shadow_buffer_id = INVALID_HYDRA_ID;
std::queue<HydraID> m_available_shadows;
@@ -0,0 +1,147 @@
#include "HydraSpotShadowSourceSystem.h"
#include "../../engine/HydraEngine.h"
#include "../../camera/HydraCamera.h"
#include "../HydraECS.h"
#include "../components/HydraDirectionalShadowSourceComponent.h"
#include "../components/HydraPositionComponent.h"
#include "../components/HydraLightComponent.h"
#include "../../buffer/HydraShadowBuffer.h"
#include "../../buffer/HydraTextureBufferManager.h"
#include "../../scheduler/HydraTaskScheduler.h"
#include "../../task/buffer/HydraCreateGPUBufferTask.hpp"
#include "../../task/buffer/HydraUpdateWholeGPUBufferTask.hpp"
#include "../../task/buffer/HydraUpdatePartialGPUBufferTask.hpp"
#include "../../task/buffer/HydraCreateUnBoundTextureTask.hpp"
#include "../../task/renderer/HydraCreateCascadeShadowFrameBuffer.hpp"
#include "../../task/renderer/HydraCreateShadowFrameBuffer.hpp"
#include "../../actor/HydraActorManager.h"
void HydraSpotShadowSourceSystem::Initialise()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
for(uint32_t i = 0; i < MAX_SHADOWS; i++)
{
m_available_shadows.push(i);
}
m_shadows.resize(MAX_SHADOWS);
HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
task->Intialise("ShadowBuffer", 1, MAX_SHADOWS * sizeof(HydraSpotShadowSourceComponent), &m_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
}
void HydraSpotShadowSourceSystem::InitialiseComponent(HydraID entity_id)
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
{
std::lock_guard<std::mutex> lock(m_mutex);
assert(m_available_shadows.size() > 0 && "Run out of shadows");
uint32_t shad_id = m_available_shadows.front();
m_available_shadows.pop();
light_comp.shadow_map_id = shad_id;
light_comp.shadow_caster = 1;
}
_InitialiseShadowMap(entity_id);
}
void HydraSpotShadowSourceSystem::UpdateSystem(float delta_t_seconds)
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
for (HydraID entity_id : Entities)
{
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
_UpdateShadowMap(entity_id);
HydraSpotShadowSourceComponent shad_comp = ecs->GetComponent<HydraSpotShadowSourceComponent>(entity_id);
m_shadows[light_comp.shadow_map_id] = shad_comp;
}
_WriteToGPU();
}
void HydraSpotShadowSourceSystem::_UpdateShadowMap(HydraID entity_id)
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraPositionComponent pos_comp = ecs->GetComponent<HydraPositionComponent>(entity_id);
HydraSpotShadowSourceComponent &shad_comp = ecs->GetComponent<HydraSpotShadowSourceComponent>(entity_id);
float view_size = 50.0f;
float view_near = 0.1f;
float view_far = 50.0f;
float PI = 3.1415927;
float TWO_PI = 6.2831854;
glm::mat4 light_rot = glm::eulerAngleXYZ(pos_comp.orientation.x, pos_comp.orientation.y, pos_comp.orientation.z);
glm::vec3 light_dir = glm::normalize(glm::vec3(light_rot * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)));
glm::vec3 camera_pos = GetEngine()->Camera()->GetPosition();
glm::vec3 light_pos = pos_comp.position;
glm::vec3 target_pos = light_pos + light_dir;
glm::vec3 up_vector = glm::vec3(0.0f, 1.0f, 0.0f);
if (glm::abs(glm::dot(light_dir, up_vector)) > 0.99f)
{
up_vector = glm::vec3(1.0f, 0.0f, 0.0f); // Prevent gimbal lock
}
glm::mat4 view = glm::lookAt(light_pos, target_pos, up_vector);
glm::mat4 proj = glm::ortho(-view_size, view_size, -view_size, view_size, view_near, view_far);
// Save data to component
shad_comp.far_plane = view_far;
shad_comp.light_space_proj = proj;
shad_comp.light_space_view = view;
}
void HydraSpotShadowSourceSystem::_InitialiseShadowMap(HydraID entity_id)
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTextureBufferManager *tex_man = engine->TextureBufferManager();
HydraSpotShadowSourceComponent &shad_comp = ecs->GetComponent<HydraSpotShadowSourceComponent>(entity_id);
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
shad_comp.entity_id = entity_id;
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateShadowFrameBuffer *fb_task = static_cast<HydraCreateShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise(&shad_comp.shadow_texture_id, &depth_texture_id, &shad_comp.frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shad_comp.shadow_texture_id = depth_texture_id;
}
void HydraSpotShadowSourceSystem::_WriteToGPU()
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
void *buffer = static_cast<void *>(m_shadows.data());
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdateWholeGPUBufferTask *task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_shadow_buffer_id, buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
}
@@ -0,0 +1,31 @@
#ifndef HYDRASPOTSHADOWSOURCESYSTEM
#define HYDRASPOTSHADOWSOURCESYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include "../components/HydraSpotShadowSourceComponent.h"
#include <GLMIncludes.h>
#include <queue>
#include <vector>
#include <mutex>
class HydraSpotShadowSourceSystem : public HydraSystem
{
public:
virtual void Initialise() override;
protected:
void InitialiseComponent(HydraID entity_id) override;
void UpdateSystem(float delta_t_seconds) override;
private:
void _UpdateShadowMap(HydraID entity_id);
void _InitialiseShadowMap(HydraID entity_id);
void _WriteToGPU();
HydraID m_shadow_buffer_id = INVALID_HYDRA_ID;
std::queue<HydraID> m_available_shadows;
std::vector<HydraSpotShadowSourceComponent> m_shadows;
std::mutex m_mutex;
};
#endif /* HYDRASPOTSHADOWSOURCESYSTEM */
+23 -7
View File
@@ -21,6 +21,8 @@
#include "../ecs/systems/HydraMaterialSystem.h"
#include "../ecs/systems/HydraLightSystem.h"
#include "../ecs/systems/HydraDirectionalShadowSourceSystem.h"
#include "../ecs/systems/HydraSpotShadowSourceSystem.h"
#include "../ecs/components/HydraPositionComponent.h"
#include "../ecs/components/HydraMeshComponent.h"
#include "../ecs/components/HydraRenderableComponent.h"
@@ -28,6 +30,7 @@
#include "../ecs/components/HydraMaterialComponent.h"
#include "../ecs/components/HydraLightComponent.h"
#include "../ecs/components/HydraDirectionalShadowSourceComponent.h"
#include "../ecs/components/HydraSpotShadowSourceComponent.h"
#include "../camera/HydraCamera.h"
@@ -216,20 +219,23 @@ void HydraEngine::_InitialiseSystems()
m_ecs->RegisterComponentType<HydraMaterialComponent>();
m_ecs->RegisterComponentType<HydraLightComponent>();
m_ecs->RegisterComponentType<HydraDirectionalShadowSourceComponent>();
m_ecs->RegisterComponentType<HydraSpotShadowSourceComponent>();
m_mesh_system = m_ecs->RegisterSystem<HydraMeshSystem>();
m_transform_system = m_ecs->RegisterSystem<HydraTransformSystem>();
m_render_system = m_ecs->RegisterSystem<HydraRenderSystem>();
m_material_system = m_ecs->RegisterSystem<HydraMaterialSystem>();
m_light_system = m_ecs->RegisterSystem<HydraLightSystem>();
m_shadow_system = m_ecs->RegisterSystem<HydraDirectionalShadowSourceSystem>();
m_directional_shadow_system = m_ecs->RegisterSystem<HydraDirectionalShadowSourceSystem>();
m_spot_shadow_system = m_ecs->RegisterSystem<HydraSpotShadowSourceSystem>();
HydraSignature mesh_sig;
HydraSignature trans_sig;
HydraSignature render_sig;
HydraSignature material_sig;
HydraSignature light_sig;
HydraSignature shadow_sig;
HydraSignature directional_shadow_sig;
HydraSignature spot_shadow_sig;
mesh_sig.set(m_ecs->GetComponentType<HydraMeshComponent>(),true);
trans_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(),true);
@@ -239,16 +245,21 @@ void HydraEngine::_InitialiseSystems()
light_sig.set(m_ecs->GetComponentType<HydraLightComponent>(), true);
light_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(), true);
shadow_sig.set(m_ecs->GetComponentType<HydraLightComponent>(), true);
shadow_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(), true);
shadow_sig.set(m_ecs->GetComponentType<HydraDirectionalShadowSourceComponent>(), true);
directional_shadow_sig.set(m_ecs->GetComponentType<HydraLightComponent>(), true);
directional_shadow_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(), true);
directional_shadow_sig.set(m_ecs->GetComponentType<HydraDirectionalShadowSourceComponent>(), true);
spot_shadow_sig.set(m_ecs->GetComponentType<HydraLightComponent>(), true);
spot_shadow_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(), true);
spot_shadow_sig.set(m_ecs->GetComponentType<HydraSpotShadowSourceComponent>(), true);
m_ecs->SetSystemSignature<HydraMeshSystem>(mesh_sig);
m_ecs->SetSystemSignature<HydraTransformSystem>(trans_sig);
m_ecs->SetSystemSignature<HydraRenderSystem>(render_sig);
m_ecs->SetSystemSignature<HydraMaterialSystem>(material_sig);
m_ecs->SetSystemSignature<HydraLightSystem>(light_sig);
m_ecs->SetSystemSignature<HydraDirectionalShadowSourceSystem>(shadow_sig);
m_ecs->SetSystemSignature<HydraDirectionalShadowSourceSystem>(directional_shadow_sig);
m_ecs->SetSystemSignature<HydraSpotShadowSourceSystem>(spot_shadow_sig);
}
@@ -276,9 +287,14 @@ void HydraEngine::_InitialiseSystems()
HydraID update_shadow_id = m_task_scheduler->CreateTask<HydraUpdateSystemTask>(HydraThreadAffinity::General);
HydraUpdateSystemTask* update_shadow_task = static_cast<HydraUpdateSystemTask*>(m_task_scheduler->GetTask(update_shadow_id));
update_shadow_task->Initialise(m_delta_t, m_shadow_system);
update_shadow_task->Initialise(m_delta_t, m_directional_shadow_system);
m_task_scheduler->WaitForTask(update_shadow_id);
HydraID update_spot_shadow_id = m_task_scheduler->CreateTask<HydraUpdateSystemTask>(HydraThreadAffinity::General);
HydraUpdateSystemTask* update_spot_shadow_task = static_cast<HydraUpdateSystemTask*>(m_task_scheduler->GetTask(update_spot_shadow_id));
update_spot_shadow_task->Initialise(m_delta_t, m_spot_shadow_system);
m_task_scheduler->WaitForTask(update_spot_shadow_id);
}
void HydraEngine::_GameLoop()
+3 -1
View File
@@ -26,6 +26,7 @@ class HydraMaterialBufferManager;
class HydraLightBufferManager;
class HydraLightSystem;
class HydraDirectionalShadowSourceSystem;
class HydraSpotShadowSourceSystem;
class CLASS_DEFINE HydraEngine : public HydraObject
{
@@ -93,7 +94,8 @@ private:
std::shared_ptr<HydraRenderSystem> m_render_system;
std::shared_ptr<HydraMaterialSystem> m_material_system;
std::shared_ptr<HydraLightSystem> m_light_system;
std::shared_ptr<HydraDirectionalShadowSourceSystem> m_shadow_system;
std::shared_ptr<HydraDirectionalShadowSourceSystem> m_directional_shadow_system;
std::shared_ptr<HydraSpotShadowSourceSystem> m_spot_shadow_system;
bool m_running = true;
@@ -12,14 +12,18 @@
#include "../ecs/HydraECS.h"
#include "../ecs/systems/HydraRenderSystem.h"
#include "../ecs/systems/HydraDirectionalShadowSourceSystem.h"
#include "../ecs/systems/HydraSpotShadowSourceSystem.h"
#include "../ecs/components/HydraLightComponent.h"
#include "../mesh/StandardVertex.h"
#include "../actor/HydraActorManager.h"
#include "../actor/HydraOutputActor.h"
void HydraShadowPipeline::Initialise()
{
m_render_stages.resize(2);
_CreateUBOs();
_CreateRenderStage();
_CreateDirectionalRenderStage();
_CreateSpotRenderStage();
}
void HydraShadowPipeline::Shutdown()
@@ -28,48 +32,64 @@ void HydraShadowPipeline::Shutdown()
void HydraShadowPipeline::Render()
{
HydraECS *ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
std::shared_ptr<HydraDirectionalShadowSourceSystem> shadow_system = ecs->GetSystem<HydraDirectionalShadowSourceSystem>();
uint32_t shadow_idx = 0;
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
glEnable(GL_DEPTH_TEST); // Depth testing must be active
glDepthMask(GL_TRUE); // Depth buffer must be writable
glDepthFunc(GL_LESS);
//glEnable(GL_POLYGON_OFFSET_FILL);
//glPolygonOffset(2.5f, 1.0f);
_RenderDirectionalShadowMaps();
_RenderSpotShadowMaps();
}
void HydraShadowPipeline::_RenderDirectionalShadowMaps()
{
HydraECS *ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
std::shared_ptr<HydraDirectionalShadowSourceSystem> shadow_system = ecs->GetSystem<HydraDirectionalShadowSourceSystem>();
for (HydraID entity_id : shadow_system->Entities)
{
_UpdateUBO(shadow_idx);
// _BindFrameBufferAttachments(entity_id);
HydraDirectionalShadowSourceComponent shad_comp = GetEngine()->ECS()->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
HydraLightComponent light_comp = GetEngine()->ECS()->GetComponent<HydraLightComponent>(entity_id);
_UpdateUBO(light_comp.shadow_map_id);
glBindFramebuffer(GL_FRAMEBUFFER, shad_comp.frame_buffer_id);
// HydraTextureBuffer tex_buffer = GetEngine()->TextureBufferManager()->GetTexture(shad_comp.shadow_texture_id);
// glBindTextureUnit(tex_buffer.gl_tex_id, 0);
float depth_value = 1.0f;
float clear_colour[] = {0,0,0};
glClearNamedFramebufferfv(shad_comp.frame_buffer_id, GL_DEPTH, 0, &depth_value);
glClearNamedFramebufferfv(shad_comp.frame_buffer_id, GL_COLOR, 0, clear_colour);
for (uint32_t rs_idx = 0; rs_idx < m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->Render(render_system->Entities, INVALID_HYDRA_ID);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
shadow_idx++;
m_render_stages[DIRECTIONAL_RENDER_STAGE]->Render(render_system->Entities, INVALID_HYDRA_ID);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
// glDisable(GL_POLYGON_OFFSET_FILL);
}
void HydraShadowPipeline::_CreateRenderStage()
void HydraShadowPipeline::_RenderSpotShadowMaps()
{
HydraECS *ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
std::shared_ptr<HydraSpotShadowSourceSystem> shadow_system = ecs->GetSystem<HydraSpotShadowSourceSystem>();
for (HydraID entity_id : shadow_system->Entities)
{
HydraSpotShadowSourceComponent shad_comp = GetEngine()->ECS()->GetComponent<HydraSpotShadowSourceComponent>(entity_id);
HydraLightComponent light_comp = GetEngine()->ECS()->GetComponent<HydraLightComponent>(entity_id);
_UpdateUBO(light_comp.shadow_map_id);
glBindFramebuffer(GL_FRAMEBUFFER, shad_comp.frame_buffer_id);
float depth_value = 1.0f;
float clear_colour[] = {0,0,0};
glClearNamedFramebufferfv(shad_comp.frame_buffer_id, GL_DEPTH, 0, &depth_value);
glClearNamedFramebufferfv(shad_comp.frame_buffer_id, GL_COLOR, 0, clear_colour);
m_render_stages[SPOT_RENDER_STAGE]->Render(render_system->Entities, INVALID_HYDRA_ID);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
void HydraShadowPipeline::_CreateDirectionalRenderStage()
{
HydraRenderStage *render_stage = new HydraRenderStage();
std::string shader_path = std::string(shader_base);
@@ -120,9 +140,64 @@ void HydraShadowPipeline::_CreateRenderStage()
GL_FRONT,
true,
HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
m_render_stages.push_back(render_stage);
m_render_stages[DIRECTIONAL_RENDER_STAGE] = render_stage;
}
void HydraShadowPipeline::_CreateSpotRenderStage()
{
HydraRenderStage *render_stage = new HydraRenderStage();
std::string shader_path = std::string(shader_base);
HydraBufferManager *buffer_manager = GetEngine()->BufferManager();
HydraID pos_buffer_id = buffer_manager->FindBuffer("PositionsBuffer");
HydraID mat_buffer_id = buffer_manager->FindBuffer("MaterialBuffer");
HydraID tex_buffer_id = buffer_manager->FindBuffer("TextureBuffer");
HydraID shadow_buffer_id = buffer_manager->FindBuffer("ShadowBuffer");
HydraID per_frame_buffer_id = buffer_manager->FindBuffer("ShadowPerFrameUBO");
HydraShaderBinding shader_binding = {};
shader_binding.block_name.push_back("positions_buffer");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(pos_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("material_buffer");
shader_binding.binding_point.push_back(2);
shader_binding.buffer_id.push_back(mat_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("texture_buffer");
shader_binding.binding_point.push_back(3);
shader_binding.buffer_id.push_back(tex_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("shadow_map_sets");
shader_binding.binding_point.push_back(5);
shader_binding.buffer_id.push_back(shadow_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("shadow_per_frame");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(per_frame_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
std::vector<uint32_t> textures;
render_stage->Initialise(shader_path + "shadow_spot_shader.vert",
shader_path + "shadow_spot_shader.frag",
"",
shader_binding,
0,
textures,
true,
GL_FRONT,
true,
HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
m_render_stages[SPOT_RENDER_STAGE] = render_stage;
}
void HydraShadowPipeline::_UpdateUBO(uint32_t shadow_idx)
{
HydraBufferManager *buffer_manager = GetEngine()->BufferManager();
@@ -18,11 +18,16 @@ class HydraShadowPipeline : public HydraPipeline
void Render() override;
private:
void _CreateUBOs();
void _CreateRenderStage();
void _CreateSpotRenderStage();
void _CreateDirectionalRenderStage();
void _UpdateUBO(uint32_t shadow_idx);
void _BindFrameBufferAttachments(HydraID entity_id);
void _RenderDirectionalShadowMaps();
void _RenderSpotShadowMaps();
HydraID m_per_frame_ubo = INVALID_HYDRA_ID;
const uint32_t DIRECTIONAL_RENDER_STAGE = 0;
const uint32_t SPOT_RENDER_STAGE = 1;
};