Files
Seele/src/Engine/Scene/LightEnvironment.cpp
T

137 lines
6.5 KiB
C++
Raw Normal View History

2023-10-26 18:37:29 +02:00
#include "LightEnvironment.h"
2025-05-06 19:36:43 +02:00
#include "Asset/AssetRegistry.h"
2025-04-06 09:57:47 +02:00
#include "Asset/EnvironmentMapAsset.h"
2023-10-26 18:37:29 +02:00
#include "Graphics/Graphics.h"
using namespace Seele;
2025-04-06 09:57:47 +02:00
LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
: graphics(graphics), environment(AssetRegistry::findEnvironmentMap("", "newport_loft")) {
2024-04-19 18:23:36 +02:00
layout = graphics->createDescriptorLayout("pLightEnv");
2024-06-09 12:20:04 +02:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
2025-02-28 16:56:51 +09:00
.name = "directionalLights",
2024-06-09 12:20:04 +02:00
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
});
2025-05-09 14:59:58 +02:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.name = "shadowMap",
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
});
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.name = "shadowSampler",
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
});
2024-06-09 12:20:04 +02:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
2025-02-28 16:56:51 +09:00
.name = "numDirectionalLights",
2025-03-07 21:48:27 +01:00
.uniformLength = sizeof(uint32),
2025-02-28 16:56:51 +09:00
});
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.name = "pointLights",
2024-06-09 12:20:04 +02:00
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
});
2025-02-28 16:56:51 +09:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.name = "numPointLights",
2025-03-07 21:48:27 +01:00
.uniformLength = sizeof(uint32),
2025-02-28 16:56:51 +09:00
});
2025-04-06 09:57:47 +02:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.name = "irradianceMap",
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
});
2025-04-13 14:41:42 +02:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.name = "irradianceSampler",
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
});
2023-10-31 16:16:23 +01:00
layout->create();
2025-02-28 16:56:51 +09:00
2023-10-31 16:16:23 +01:00
directionalLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
2024-10-01 11:15:38 +02:00
.name = "DirectionalLights",
2023-10-31 16:16:23 +01:00
});
pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
2024-10-01 11:15:38 +02:00
.name = "PointLights",
2023-10-31 16:16:23 +01:00
});
2025-04-06 09:57:47 +02:00
environmentSampler = graphics->createSampler({
.magFilter = Gfx::SE_FILTER_LINEAR,
.minFilter = Gfx::SE_FILTER_LINEAR,
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
});
2023-10-26 18:37:29 +02:00
}
2024-06-09 12:20:04 +02:00
LightEnvironment::~LightEnvironment() {}
2023-10-26 18:37:29 +02:00
2024-06-09 12:20:04 +02:00
void LightEnvironment::reset() {
2023-10-31 16:16:23 +01:00
layout->reset();
set = layout->allocateDescriptorSet();
dirs.clear();
2025-05-07 16:08:12 +02:00
directionalTransforms.clear();
2023-10-31 16:16:23 +01:00
points.clear();
2023-10-26 18:37:29 +02:00
}
2025-05-07 16:08:12 +02:00
void LightEnvironment::addDirectionalLight(const Component::DirectionalLight& dirLight, const Component::Transform& transform) {
2025-05-09 14:59:58 +02:00
Vector eyePos = transform.getPosition();
Vector lookAt = eyePos + transform.getForward();
Matrix4 cameraMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
Matrix4 correctionMatrix = Matrix4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 / 2.f, 0, 0, 0, 1 / 2.f, 1);
2025-05-07 16:08:12 +02:00
dirs.add(ShaderDirectionalLight{
.color = Vector4(dirLight.color, dirLight.intensity),
.direction = Vector4(transform.getForward(), 0),
2025-05-09 14:59:58 +02:00
.lightSpaceMatrix = correctionMatrix * glm::ortho(-20.f, 20.f, 20.f, -20.f, 10.0f, -20.0f) * cameraMatrix,
2025-05-07 16:08:12 +02:00
});
directionalTransforms.add(transform);
if (shadowMaps.size() < dirs.size()) {
shadowMaps.add(graphics->createTexture2D(TextureCreateInfo{
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.width = 2048,
.height = 2048,
.elements = (uint32)dirs.size(),
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
.name = "ShadowMap",
}));
2025-05-09 14:59:58 +02:00
shadowMaps.back()->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
2025-05-07 16:08:12 +02:00
shadowSamplers.add(graphics->createSampler(SamplerCreateInfo{
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
.name = "ShadowSampler",
}));
}
}
2023-10-26 18:37:29 +02:00
2025-05-07 16:08:12 +02:00
void LightEnvironment::addPointLight(const Component::PointLight& pointLight, const Component::Transform& transform) {
points.add(ShaderPointLight{
.position_WS = Vector4(transform.getPosition(), pointLight.intensity),
.colorRange = Vector4(pointLight.color, pointLight.attenuation),
});
}
2023-10-26 18:37:29 +02:00
2024-06-09 12:20:04 +02:00
void LightEnvironment::commit() {
2025-05-09 14:59:58 +02:00
directionalLights->rotateBuffer(sizeof(ShaderDirectionalLight) * dirs.size());
directionalLights->updateContents(0, sizeof(ShaderDirectionalLight) * dirs.size(), dirs.data());
2024-07-15 08:32:50 +02:00
directionalLights->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
2024-07-16 15:32:51 +02:00
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
2024-10-14 18:14:08 +02:00
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
2025-05-09 14:59:58 +02:00
pointLights->rotateBuffer(sizeof(ShaderPointLight) * points.size());
pointLights->updateContents(0, sizeof(ShaderPointLight) * points.size(), points.data());
2024-07-16 15:32:51 +02:00
pointLights->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
2024-10-14 18:14:08 +02:00
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
2025-03-20 20:15:38 +01:00
uint32 numPointLights = (uint32)points.size();
uint32 numDirectionalLights = (uint32)dirs.size();
2025-02-28 16:56:51 +09:00
set->updateConstants("numDirectionalLights", 0, &numDirectionalLights);
set->updateBuffer("directionalLights", 0, directionalLights);
2025-05-09 14:59:58 +02:00
set->updateTexture("shadowMap", 0, Gfx::PTexture2D(shadowMaps[0]));
set->updateSampler("shadowSampler", 0, Gfx::PSampler(shadowSamplers[0]));
set->updateConstants("numPointLights", 0, &numPointLights);
set->updateBuffer("pointLights", 0, pointLights);
2025-04-06 09:57:47 +02:00
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap());
2025-04-13 14:41:42 +02:00
set->updateSampler("irradianceSampler", 0, environmentSampler);
2023-11-08 23:27:21 +01:00
set->writeChanges();
2023-10-26 18:37:29 +02:00
}
2023-11-05 10:36:01 +01:00
2024-06-09 12:20:04 +02:00
const Gfx::PDescriptorLayout LightEnvironment::getDescriptorLayout() const { return layout; }
2023-11-05 10:36:01 +01:00
2024-06-09 12:20:04 +02:00
Gfx::PDescriptorSet LightEnvironment::getDescriptorSet() { return set; }