Engine²
Open-source game engine written in C++.
Loading...
Searching...
No Matches
Shadow.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Logger.hpp"
8#include "core/Core.hpp"
9#include "entity/Entity.hpp"
15#include "utils/PointLights.hpp"
19#include <entt/core/hashed_string.hpp>
20#include <string_view>
21
23static inline constexpr std::string_view SHADOW_PASS_OUTPUT = "SHADOW_PASS_OUTPUT";
24static inline const entt::hashed_string SHADOW_PASS_OUTPUT_ID{SHADOW_PASS_OUTPUT.data(), SHADOW_PASS_OUTPUT.size()};
25static inline constexpr std::string_view SHADOW_PASS_NAME = "SHADOW_PASS";
26static inline const entt::hashed_string SHADOW_PASS_ID{SHADOW_PASS_NAME.data(), SHADOW_PASS_NAME.size()};
27static inline constexpr std::string_view SHADOW_SHADER_NAME = "SHADOW_SHADER";
28static inline const entt::hashed_string SHADOW_SHADER_ID =
29 entt::hashed_string{SHADOW_SHADER_NAME.data(), SHADOW_SHADER_NAME.size()};
30
31static inline constexpr std::string_view SHADOW_BINDGROUP_TEXTURES_NAME = "SHADOW_BINDGROUP_TEXTURES";
32static inline const entt::hashed_string SHADOW_BINDGROUP_TEXTURES_ID =
33 entt::hashed_string{SHADOW_BINDGROUP_TEXTURES_NAME.data(), SHADOW_BINDGROUP_TEXTURES_NAME.size()};
34
35static inline constexpr std::string_view SHADOW_SHADER_CONTENT = R"(
36const MAX_POINT_LIGHTS: u32 = 64u;
37
38struct Input {
39 @location(0) position: vec3f,
40 @location(1) normal: vec3f,
41 @location(2) uv: vec2f,
42};
43
44struct Object {
45 model : mat4x4<f32>,
46 normal : mat4x4<f32>,
47}
48
49struct Light {
50 viewProjection: mat4x4f,
51};
52
53@group(0) @binding(0) var<uniform> light: Light;
54@group(1) @binding(0) var<uniform> object: Object;
55
56@vertex
57fn vs_main(
58 input : Input
59) -> @builtin(position) vec4f {
60 return light.viewProjection * object.model * vec4f(input.position, 1.0);
61}
62
63@fragment
64fn fs_main() {}
65)";
66
68 public:
69 explicit Shadow(std::string_view name = SHADOW_PASS_NAME) : AMultipleExecutionRenderPass<Shadow>(name) {}
70
71 uint16_t GetNumberOfPasses(Engine::Core &core) override
72 {
73 uint16_t count = 0;
74 core.GetRegistry().view<Component::GPUDirectionalLight>().each([&count](auto, const auto &) { count++; });
75 return std::min(count, static_cast<uint16_t>(1));
76 }
77
78 void perPass(uint16_t passIndex, Engine::Core &core) override
79 {
80 auto view = core.GetRegistry().view<Component::GPUDirectionalLight>();
81 if (view.empty())
82 {
83 return;
84 }
85 uint16_t i = 0;
86 for (auto &&[e, light] : view.each())
87 {
88 Engine::Entity entity{core, e};
89 if (i == passIndex)
90 {
91 auto &lightGPUComponent = entity.GetComponents<Component::GPUDirectionalLight>();
92 auto &outputs = this->GetOutputs();
93 outputs.depthBuffer->depthTextureView = lightGPUComponent.shadowTextureView;
94 lightGPUComponent.shadowTextureIndex = passIndex;
95 return;
96 }
97 i++;
98 }
99 };
100
101 void UniqueRenderCallback(wgpu::RenderPassEncoder &renderPass, Engine::Core &core) override
102 {
103 const auto &bindGroupManager = core.GetResource<Graphic::Resource::BindGroupManager>();
104 const auto &bufferContainer = core.GetResource<Graphic::Resource::GPUBufferContainer>();
105
106 auto light = core.GetRegistry().view<Component::GPUDirectionalLight>();
107 if (light.empty())
108 {
109 return;
110 }
111 Engine::Entity lightEntity{core, light.front()};
112 const auto &lightGPUComponent = lightEntity.GetComponents<Component::GPUDirectionalLight>();
113 const auto &lightBindGroup = bindGroupManager.Get(lightGPUComponent.bindGroupData);
114 renderPass.setBindGroup(0, lightBindGroup.GetBindGroup(), 0, nullptr);
115
116 auto view = core.GetRegistry().view<Component::GPUTransform, Component::GPUMesh>();
117
118 for (auto &&[e, transform, gpuMesh] : view.each())
119 {
120 Engine::Entity entity{core, e};
121
122 const auto &transformBindGroup = bindGroupManager.Get(transform.bindGroup);
123 renderPass.setBindGroup(1, transformBindGroup.GetBindGroup(), 0, nullptr);
124 const auto &pointBuffer = bufferContainer.Get(gpuMesh.pointBufferId);
125 const auto &pointBufferSize = pointBuffer->GetBuffer().getSize();
126 renderPass.setVertexBuffer(0, pointBuffer->GetBuffer(), 0, pointBufferSize);
127 const auto &indexBuffer = bufferContainer.Get(gpuMesh.indexBufferId);
128 const auto &indexBufferSize = indexBuffer->GetBuffer().getSize();
129 renderPass.setIndexBuffer(indexBuffer->GetBuffer(), wgpu::IndexFormat::Uint32, 0, indexBufferSize);
130 renderPass.drawIndexed(indexBufferSize / sizeof(uint32_t), 1, 0, 0, 0);
131 }
132 }
133
135 {
137
138 auto lightLayout = Graphic::Utils::BindGroupLayout("light").addEntry(
140 .setType(wgpu::BufferBindingType::Uniform)
142 .setVisibility(wgpu::ShaderStage::Vertex)
143 .setBinding(0));
144 auto objectLayout = Graphic::Utils::BindGroupLayout("object").addEntry(
146 .setType(wgpu::BufferBindingType::Uniform)
147 .setMinBindingSize(sizeof(glm::mat4) + sizeof(glm::mat4))
148 .setVisibility(wgpu::ShaderStage::Vertex)
149 .setBinding(0));
150
151 auto vertexLayout = Graphic::Utils::VertexBufferLayout()
152 .addVertexAttribute(wgpu::VertexFormat::Float32x3, 0, 0)
153 .addVertexAttribute(wgpu::VertexFormat::Float32x3, 3 * sizeof(float), 1)
154 .addVertexAttribute(wgpu::VertexFormat::Float32x2, 6 * sizeof(float), 2)
155 .setArrayStride(8 * sizeof(float))
156 .setStepMode(wgpu::VertexStepMode::Vertex);
157
158 auto depthOutput = Graphic::Utils::DepthStencilState("SHADOW_OUTPUT")
159 .setFormat(wgpu::TextureFormat::Depth32Float)
160 .setCompareFunction(wgpu::CompareFunction::Less)
161 .setDepthWriteEnabled(wgpu::OptionalBool::True);
162
163 shaderDescriptor.setShader(SHADOW_SHADER_CONTENT)
165 .addVertexBufferLayout(vertexLayout)
166 .setVertexEntryPoint("vs_main")
167 .setFragmentEntryPoint("fs_main")
168 .addBindGroupLayout(lightLayout)
169 .addBindGroupLayout(objectLayout)
170 .setOutputDepthFormat(depthOutput);
171 const auto validations = shaderDescriptor.validate();
172 if (!validations.empty())
173 {
174 for (const auto &validation : validations)
175 {
176 if (validation.severity == Graphic::Utils::ValidationError::Severity::Error)
177 {
178 Log::Error(fmt::format("Shader Descriptor Validation Error: {} at {}", validation.message,
179 validation.location));
180 }
181 else if (validation.severity == Graphic::Utils::ValidationError::Severity::Warning)
182 {
183 Log::Warning(fmt::format("Shader Descriptor Validation Warning: {} at {}", validation.message,
184 validation.location));
185 }
186 }
187 }
188 return Graphic::Resource::Shader::Create(shaderDescriptor, graphicContext);
189 }
190};
191
192} // namespace DefaultPipeline::Resource
static int count
Definition SystemSetTest.cpp:7
Shadow(std::string_view name=SHADOW_PASS_NAME)
Definition Shadow.hpp:69
void perPass(uint16_t passIndex, Engine::Core &core) override
Definition Shadow.hpp:78
uint16_t GetNumberOfPasses(Engine::Core &core) override
Definition Shadow.hpp:71
static Graphic::Resource::Shader CreateShader(Graphic::Resource::Context &graphicContext)
Definition Shadow.hpp:134
void UniqueRenderCallback(wgpu::RenderPassEncoder &renderPass, Engine::Core &core) override
Definition Shadow.hpp:101
The core is the place where all the data of the engine is stored. It contains the registry (entities)...
Definition Core.hpp:33
TResource & GetResource()
Get a reference of a resource.
Definition Core.inl:14
Registry & GetRegistry()
Get the entt::registry that contains all components. It should be used to update component through sy...
Definition Core.hpp:50
Wrapper class providing a convenient interface for entity manipulation with the Core....
Definition Entity.hpp:20
decltype(auto) GetComponents()
Get components of type TComponent from the entity.
Definition Entity.hpp:118
Definition AMultipleExecutionRenderPass.hpp:9
AMultipleExecutionRenderPass(std::string_view name)
Definition AMultipleExecutionRenderPass.hpp:11
const auto & GetOutputs(void) const
Definition ARenderPass.hpp:148
Definition Context.hpp:8
Definition ShaderDescriptor.hpp:21
ShaderDescriptor & setVertexEntryPoint(std::string_view entryPoint)
Definition ShaderDescriptor.hpp:50
ShaderDescriptor & setName(std::string_view name)
Definition ShaderDescriptor.hpp:108
ShaderDescriptor & setFragmentEntryPoint(std::string_view entryPoint)
Definition ShaderDescriptor.hpp:56
ShaderDescriptor & addBindGroupLayout(const Utils::BindGroupLayout &layout)
Definition ShaderDescriptor.hpp:73
std::vector< Utils::ValidationError > validate(void) const override
Validate the ShaderDescriptor and all contained layouts/states.
Definition ShaderDescriptor.hpp:127
ShaderDescriptor & addVertexBufferLayout(const Utils::VertexBufferLayout &layout)
Definition ShaderDescriptor.hpp:62
ShaderDescriptor & setShader(std::string_view source)
Definition ShaderDescriptor.hpp:26
ShaderDescriptor & setOutputDepthFormat(const Utils::DepthStencilState &state)
Definition ShaderDescriptor.hpp:90
Definition Shader.hpp:14
static Shader Create(const ShaderDescriptor &descriptor, Context &context)
Definition Shader.hpp:45
Definition BindGroupLayout.hpp:13
BindGroupLayout & addEntry(const TEntry &entry)
Definition BindGroupLayout.hpp:18
Definition BufferBindGroupLayoutEntry.hpp:7
Definition DepthStencilState.hpp:8
DepthStencilState & setDepthWriteEnabled(wgpu::OptionalBool enabled)
Definition DepthStencilState.hpp:35
DepthStencilState & setCompareFunction(wgpu::CompareFunction func)
Definition DepthStencilState.hpp:29
DepthStencilState & setFormat(wgpu::TextureFormat format)
Definition DepthStencilState.hpp:41
Definition VertexBufferLayout.hpp:11
VertexBufferLayout & setArrayStride(uint32_t stride)
Definition VertexBufferLayout.hpp:26
VertexBufferLayout & addVertexAttribute(wgpu::VertexFormat format, uint32_t offset, uint32_t shaderLocation)
Definition VertexBufferLayout.hpp:16
VertexBufferLayout & setStepMode(wgpu::VertexStepMode mode)
Definition VertexBufferLayout.hpp:32
ResourceType & Get(const entt::hashed_string &id)
Get the reference to a stored resource.
Definition ResourceManager.hpp:73
Definition AmbientLight.cpp:6
static constexpr std::string_view SHADOW_SHADER_CONTENT
Definition Shadow.hpp:35
static constexpr std::string_view SHADOW_PASS_OUTPUT
Definition Shadow.hpp:23
static const entt::hashed_string SHADOW_BINDGROUP_TEXTURES_ID
Definition Shadow.hpp:32
static constexpr std::string_view SHADOW_BINDGROUP_TEXTURES_NAME
Definition Shadow.hpp:31
static constexpr std::string_view SHADOW_PASS_NAME
Definition Shadow.hpp:25
static constexpr std::string_view SHADOW_SHADER_NAME
Definition Shadow.hpp:27
static const entt::hashed_string SHADOW_PASS_OUTPUT_ID
Definition Shadow.hpp:24
static const entt::hashed_string SHADOW_SHADER_ID
Definition Shadow.hpp:28
static const entt::hashed_string SHADOW_PASS_ID
Definition Shadow.hpp:26
Object::Resource::ResourceManager< std::unique_ptr< AGPUBuffer > > GPUBufferContainer
GPUBufferContainer is a resource that stores GPUBuffer resources.
Definition GPUBufferContainer.hpp:17
Object::Resource::ResourceManager< BindGroup > BindGroupManager
BindGroupManager is a resource that stores BindGroup resources.
Definition BindGroupManager.hpp:17
void Warning(const T &msg) noexcept
Definition Logger.hpp:49
void Error(const T &msg) noexcept
Definition Logger.hpp:51
Definition GPUDirectionalLight.hpp:11
wgpu::TextureView shadowTextureView
Definition GPUDirectionalLight.hpp:17
Definition GPUMesh.hpp:6
Definition GPUTransform.hpp:6
static uint32_t GPUSize()
Definition DirectionalLightBuffer.hpp:24
@ Warning
Definition IValidable.hpp:13
@ Error
Definition IValidable.hpp:14