PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
forward_lit_scene_mesh_subrender_internal.h
1#pragma once
2
3#include "pixelbullet/assets/material.h"
5#include "pixelbullet/private/graphics/rendering/buffers/buffer.h"
6#include "pixelbullet/private/graphics/rendering/buffers/morph_mesh_resource.h"
7#include "pixelbullet/private/graphics/rendering/buffers/skinned_mesh_resource.h"
8#include "pixelbullet/private/graphics/rendering/buffers/skinned_morph_mesh_resource.h"
9#include "pixelbullet/private/graphics/rendering/buffers/static_mesh_resource.h"
10#include "pixelbullet/private/graphics/rendering/buffers/storage_buffer.h"
11#include "pixelbullet/private/graphics/rendering/buffers/uniform_handler.h"
12#include "pixelbullet/private/graphics/rendering/descriptors/descriptors_handler.h"
13#include "pixelbullet/private/graphics/runtime_support/images/image_2d.h"
14#include "pixelbullet/private/graphics/rendering/images/image_cube.h"
15#include "pixelbullet/private/graphics/rendering/images/image_depth.h"
16#include "pixelbullet/private/graphics/rendering/pipelines/pipeline_graphics.h"
17#include "pixelbullet/private/scene/rendering/forward_lit_scene_mesh_subrender.h"
18#include "pixelbullet/private/scene/rendering/render_resource_resolver.h"
19
20#include <algorithm>
21#include <array>
22#include <cstddef>
23#include <memory>
24#include <optional>
25#include <string>
26#include <vector>
27
28namespace pixelbullet
29{
30namespace forward_lit_scene_mesh_internal
31{
32constexpr uint32_t k_max_point_light_count = 8;
33constexpr uint32_t k_max_spot_light_count = 8;
34
35enum class MeshDrawKind
36{
37 None,
38 Static,
39 Morph,
40 Skinned,
41 SkinnedMorph,
42};
43
45{
46 glm::mat4 view_projection{ 1.0f };
47 glm::vec4 camera_position_ambient_intensity{ 0.0f, 0.0f, 0.0f, 0.32f };
48 glm::vec4 ambient_color{ 0.18f, 0.19f, 0.24f, 0.0f };
49 glm::vec4 environment_params{ 0.0f };
50};
51
53{
54 glm::vec4 direction_intensity{ 0.0f, 0.0f, -1.0f, 0.0f };
55 glm::vec4 color{ 1.0f, 1.0f, 1.0f, 0.0f };
56};
57
59{
60 glm::vec4 position_range{ 0.0f };
61 glm::vec4 color_intensity{ 0.0f };
62};
63
65{
66 glm::vec4 position_range{ 0.0f };
67 glm::vec4 direction_outer_cos{ 0.0f, 0.0f, -1.0f, 0.0f };
68 glm::vec4 color_intensity{ 0.0f };
69 glm::vec4 angle_params{ 1.0f, 0.0f, 0.0f, 0.0f };
70};
71
73{
74 DirectionalLightGpu directional_light{};
75 std::array<PointLightGpu, k_max_point_light_count> point_lights{};
76 std::array<SpotLightGpu, k_max_spot_light_count> spot_lights{};
77 glm::vec4 light_counts{ 0.0f };
78 glm::mat4 shadow_view_projection{ 1.0f };
79 glm::vec4 shadow_params0{ 0.0f };
80 glm::vec4 shadow_params1{ 0.0f };
81};
82
84{
85 glm::mat4 model{ 1.0f };
86 glm::vec4 base_color_factor{ 1.0f };
87 glm::vec4 material_factors{ 0.0f, 1.0f, 0.0f, 0.0f };
88 glm::vec4 emissive_factor{ 0.0f };
89 glm::vec4 material_strengths{ 1.0f, 1.0f, 1.0f, 0.0f };
90 glm::vec4 ior_factor{ 1.5f, 0.0f, 0.0f, 0.0f };
91 glm::vec4 transmission_factors{ 0.0f };
92 glm::vec4 transmission_semantics{ 0.0f };
93 glm::vec4 transmission_texture_uv_sets{ 0.0f };
94 glm::vec4 transmission_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
95 glm::vec4 transmission_uv_rotations{ 0.0f };
96 glm::vec4 volume_factors{ 0.0f };
97 glm::vec4 volume_attenuation_color{ 1.0f, 1.0f, 1.0f, 0.0f };
98 glm::vec4 volume_semantics{ 0.0f };
99 glm::vec4 volume_texture_uv_sets{ 0.0f };
100 glm::vec4 volume_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
101 glm::vec4 volume_uv_rotations{ 0.0f };
102 glm::vec4 material_semantics{ 0.0f, 0.5f, 0.0f, 0.0f };
103 glm::vec4 texture_uv_sets{ 0.0f };
104 glm::vec4 base_color_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
105 glm::vec4 normal_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
106 glm::vec4 orm_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
107 glm::vec4 emissive_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
108 glm::vec4 texture_uv_rotations{ 0.0f };
109 glm::vec4 specular_factors{ 1.0f, 1.0f, 1.0f, 1.0f };
110 glm::vec4 specular_semantics{ 0.0f };
111 glm::vec4 specular_texture_uv_sets{ 0.0f };
112 glm::vec4 specular_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
113 glm::vec4 specular_color_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
114 glm::vec4 specular_uv_rotations{ 0.0f };
115 glm::vec4 clearcoat_factors{ 0.0f, 0.0f, 1.0f, 0.0f };
116 glm::vec4 clearcoat_semantics{ 0.0f };
117 glm::vec4 clearcoat_texture_uv_sets{ 0.0f };
118 glm::vec4 clearcoat_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
119 glm::vec4 clearcoat_roughness_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
120 glm::vec4 clearcoat_normal_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
121 glm::vec4 clearcoat_uv_rotations{ 0.0f };
122 glm::vec4 sheen_factors{ 0.0f };
123 glm::vec4 sheen_semantics{ 0.0f };
124 glm::vec4 sheen_texture_uv_sets{ 0.0f };
125 glm::vec4 sheen_color_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
126 glm::vec4 sheen_roughness_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
127 glm::vec4 sheen_uv_rotations{ 0.0f };
128 glm::vec4 iridescence_factors{ 0.0f, 1.3f, 100.0f, 400.0f };
129 glm::vec4 iridescence_semantics{ 0.0f };
130 glm::vec4 iridescence_texture_uv_sets{ 0.0f };
131 glm::vec4 iridescence_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
132 glm::vec4 iridescence_thickness_uv_transform{ 0.0f, 0.0f, 1.0f, 1.0f };
133 glm::vec4 iridescence_uv_rotations{ 0.0f };
134};
135
137{
138 std::string mesh_path;
139 std::string material_path;
140 std::vector<std::string> material_texture_paths;
141};
142
144{
145 std::shared_ptr<StaticMeshResource> static_mesh;
146 std::shared_ptr<MorphMeshResource> morph_mesh;
147 std::shared_ptr<SkinnedMeshResource> skinned_mesh;
148 std::shared_ptr<SkinnedMorphMeshResource> skinned_morph_mesh;
149 std::shared_ptr<Image2D> base_color_texture;
150 std::shared_ptr<Image2D> normal_texture;
151 std::shared_ptr<Image2D> orm_texture;
152 std::shared_ptr<Image2D> emissive_texture;
153 std::shared_ptr<Image2D> transmission_texture;
154 std::shared_ptr<Image2D> volume_thickness_texture;
155 std::shared_ptr<Image2D> specular_texture;
156 std::shared_ptr<Image2D> specular_color_texture;
157 std::shared_ptr<Image2D> clearcoat_texture;
158 std::shared_ptr<Image2D> clearcoat_roughness_texture;
159 std::shared_ptr<Image2D> clearcoat_normal_texture;
160 std::shared_ptr<Image2D> sheen_color_texture;
161 std::shared_ptr<Image2D> sheen_roughness_texture;
162 std::shared_ptr<Image2D> iridescence_texture;
163 std::shared_ptr<Image2D> iridescence_thickness_texture;
164 std::vector<std::unique_ptr<StorageBuffer>> joint_palette_buffers;
165 std::vector<std::unique_ptr<StorageBuffer>> morph_weights_buffers;
166
167 void ResetResolvedBindings() noexcept
168 {
169 static_mesh.reset();
170 morph_mesh.reset();
171 skinned_mesh.reset();
172 skinned_morph_mesh.reset();
173 base_color_texture.reset();
174 normal_texture.reset();
175 orm_texture.reset();
176 emissive_texture.reset();
177 transmission_texture.reset();
178 volume_thickness_texture.reset();
179 specular_texture.reset();
180 specular_color_texture.reset();
181 clearcoat_texture.reset();
182 clearcoat_roughness_texture.reset();
183 clearcoat_normal_texture.reset();
184 sheen_color_texture.reset();
185 sheen_roughness_texture.reset();
186 iridescence_texture.reset();
187 iridescence_thickness_texture.reset();
188 }
189
190 [[nodiscard]] StorageBuffer* GetJointPaletteBuffer(const uint32_t image_index) const noexcept
191 {
192 return image_index < joint_palette_buffers.size() ? joint_palette_buffers[image_index].get() : nullptr;
193 }
194
195 [[nodiscard]] StorageBuffer* GetMorphWeightsBuffer(const uint32_t image_index) const noexcept
196 {
197 return image_index < morph_weights_buffers.size() ? morph_weights_buffers[image_index].get() : nullptr;
198 }
199
200 [[nodiscard]] const Buffer* GetVertexBuffer() const noexcept
201 {
202 if (static_mesh)
203 {
204 return static_mesh->GetVertexBuffer();
205 }
206 if (morph_mesh)
207 {
208 return morph_mesh->GetVertexBuffer();
209 }
210 if (skinned_mesh)
211 {
212 return skinned_mesh->GetVertexBuffer();
213 }
214 if (skinned_morph_mesh)
215 {
216 return skinned_morph_mesh->GetVertexBuffer();
217 }
218 return nullptr;
219 }
220
221 [[nodiscard]] const Buffer* GetIndexBuffer() const noexcept
222 {
223 if (static_mesh)
224 {
225 return static_mesh->GetIndexBuffer();
226 }
227 if (morph_mesh)
228 {
229 return morph_mesh->GetIndexBuffer();
230 }
231 if (skinned_mesh)
232 {
233 return skinned_mesh->GetIndexBuffer();
234 }
235 if (skinned_morph_mesh)
236 {
237 return skinned_morph_mesh->GetIndexBuffer();
238 }
239 return nullptr;
240 }
241
242 [[nodiscard]] uint32_t GetIndexCount() const noexcept
243 {
244 if (static_mesh)
245 {
246 return static_mesh->GetIndexCount();
247 }
248 if (morph_mesh)
249 {
250 return morph_mesh->GetIndexCount();
251 }
252 if (skinned_mesh)
253 {
254 return skinned_mesh->GetIndexCount();
255 }
256 if (skinned_morph_mesh)
257 {
258 return skinned_morph_mesh->GetIndexCount();
259 }
260 return 0u;
261 }
262
263 [[nodiscard]] bool HasRenderableMesh() const noexcept
264 {
265 return GetVertexBuffer() != nullptr && GetIndexBuffer() != nullptr && GetIndexCount() > 0u;
266 }
267};
268
269static_assert(sizeof(SceneUniformState) == sizeof(float) * 28);
270static_assert(sizeof(LightingUniformState) == sizeof(float) * 228);
271static_assert(sizeof(MeshUniformState) == sizeof(float) * 208);
272
273VertexLayout CreateStaticMeshVertexInput();
274VertexLayout CreateSkinnedMeshVertexInput();
275std::vector<ShaderDefine> CreateLitSceneDefines();
276const VirtualPath& LitSceneVertexShader();
277const VirtualPath& LitSceneMorphVertexShader();
278const VirtualPath& LitSceneSkinnedVertexShader();
279const VirtualPath& LitSceneSkinnedMorphVertexShader();
280const VirtualPath& LitSceneFragmentShader();
281const std::string& ShadowMapAttachmentName();
282const VirtualPath& FlatWhiteTexture();
283const VirtualPath& FallbackEnvironmentCubemap();
284std::vector<std::string> CollectMaterialTexturePaths(const Material& material);
285std::vector<std::size_t> CollectMatchingSlotIndices(const std::vector<std::optional<SlotDependencies>>& slot_dependencies,
286 const ForwardLitSceneMeshAssetChangeSet& change_set);
287bool MatchesActiveEnvironmentCubemapRoot(const std::optional<std::string>& active_cubemap_root,
288 const std::vector<std::string>& changed_cubemaps) noexcept;
289bool MatchesActiveEnvironmentAsset(const std::optional<std::string>& active_environment_asset,
290 const std::vector<std::string>& changed_environment_assets) noexcept;
291
292void ValidatePipelineLayouts(ForwardLitSceneMeshSubrenderImpl& impl);
293void Render(ForwardLitSceneMeshSubrenderImpl& impl, const RenderFrameContext& frame_context);
294std::size_t RefreshAllAssetCaches(ForwardLitSceneMeshSubrenderImpl& impl);
295std::size_t RefreshAssetCaches(ForwardLitSceneMeshSubrenderImpl& impl, const ForwardLitSceneMeshAssetChangeSet& change_set);
296} // namespace forward_lit_scene_mesh_internal
297
298struct ForwardLitSceneMeshSubrenderImpl
299{
300 ForwardLitSceneMeshSubrenderImpl(const Subrender::Stage& stage, RenderDevice& render_device, Filesystem& filesystem,
301 ResourceCache& resource_cache, const SceneRenderData& render_data,
302 const ForwardLitMaterialOverrideProvider* material_override_provider);
303
304 void EnsureMeshCapacity(std::size_t mesh_count)
305 {
306 ASSERT(mesh_layout.has_value(), "Forward lit scene mesh layout must be initialized");
307 while (mesh_uniforms.size() < mesh_count)
308 {
309 UniformHandler mesh_uniform(render_device);
310 mesh_uniform.Update(mesh_layout);
311 mesh_uniforms.emplace_back(std::move(mesh_uniform));
312 mesh_descriptors.emplace_back(culled_pipeline);
313 resolved_resources.emplace_back();
314 slot_draw_kinds.emplace_back(forward_lit_scene_mesh_internal::MeshDrawKind::None);
315 slot_dependencies.emplace_back(std::nullopt);
316 }
317 }
318
319 void InvalidateSlotState(std::size_t slot_index)
320 {
321 if (slot_index >= resolved_resources.size())
322 {
323 return;
324 }
325
326 resolved_resources[slot_index].ResetResolvedBindings();
327 slot_draw_kinds[slot_index] = forward_lit_scene_mesh_internal::MeshDrawKind::None;
328 slot_dependencies[slot_index].reset();
329 }
330
331 void InvalidateAllSlotState()
332 {
333 for (std::size_t slot_index = 0; slot_index < resolved_resources.size(); ++slot_index)
334 {
335 InvalidateSlotState(slot_index);
336 }
337 }
338
339 void ClearUnusedSlotState(std::size_t mesh_count)
340 {
341 for (std::size_t mesh_index = mesh_count; mesh_index < resolved_resources.size(); ++mesh_index)
342 {
343 InvalidateSlotState(mesh_index);
344 }
345 }
346
347 [[nodiscard]] std::size_t CountActiveSlots() const noexcept
348 {
349 return static_cast<std::size_t>(
350 std::count_if(slot_dependencies.begin(), slot_dependencies.end(), [](const auto& slot) { return slot.has_value(); }));
351 }
352
353 [[nodiscard]] std::vector<std::size_t> CollectMatchingSlotIndices(const ForwardLitSceneMeshAssetChangeSet& change_set) const;
354
355 const SceneRenderData* render_data = nullptr;
356 RenderDevice& render_device;
357 RenderResourceResolver resource_resolver;
358 const ForwardLitMaterialOverrideProvider* material_override_provider = nullptr;
359 PipelineGraphics culled_pipeline;
360 PipelineGraphics double_sided_pipeline;
361 PipelineGraphics transparent_culled_pipeline;
362 PipelineGraphics transparent_double_sided_pipeline;
363 PipelineGraphics morph_culled_pipeline;
364 PipelineGraphics morph_double_sided_pipeline;
365 PipelineGraphics morph_transparent_culled_pipeline;
366 PipelineGraphics morph_transparent_double_sided_pipeline;
367 PipelineGraphics skinned_culled_pipeline;
368 PipelineGraphics skinned_double_sided_pipeline;
369 PipelineGraphics skinned_transparent_culled_pipeline;
370 PipelineGraphics skinned_transparent_double_sided_pipeline;
371 PipelineGraphics skinned_morph_culled_pipeline;
372 PipelineGraphics skinned_morph_double_sided_pipeline;
373 PipelineGraphics skinned_morph_transparent_culled_pipeline;
374 PipelineGraphics skinned_morph_transparent_double_sided_pipeline;
375 std::optional<BufferLayout> mesh_layout;
376 UniformHandler scene_uniforms;
377 UniformHandler lighting_uniforms;
378 std::vector<UniformHandler> mesh_uniforms;
379 std::vector<DescriptorsHandler> mesh_descriptors;
380 std::vector<forward_lit_scene_mesh_internal::ResolvedResources> resolved_resources;
381 std::vector<forward_lit_scene_mesh_internal::MeshDrawKind> slot_draw_kinds;
382 std::vector<std::optional<forward_lit_scene_mesh_internal::SlotDependencies>> slot_dependencies;
383 std::optional<std::string> environment_asset_path;
384 std::optional<std::string> environment_skybox_cubemap_root;
385 std::optional<std::string> environment_diffuse_irradiance_cubemap_root;
386 std::optional<std::string> environment_specular_prefilter_cubemap_root;
387 std::shared_ptr<ImageCube> environment_skybox_cubemap;
388 std::shared_ptr<ImageCube> environment_diffuse_irradiance_cubemap;
389 std::shared_ptr<ImageCube> environment_specular_prefilter_cubemap;
390};
391} // namespace pixelbullet
Provides assertion and panic mechanisms with optional custom formatting.
#define ASSERT(condition,...)
Asserts that a condition is true.
Definition assert.h:163
Definition filesystem.h:16
Definition material.h:395
Definition render_device.h:15
Definition render_frame_context.h:17
Definition resource_cache.h:16
Definition virtual_path.h:10
Definition forward_lit_scene_mesh_subrender_internal.h:299
Definition render_data.h:117
Definition forward_lit_scene_mesh_subrender_internal.h:53
Definition forward_lit_scene_mesh_subrender_internal.h:73
Definition forward_lit_scene_mesh_subrender_internal.h:84
Definition forward_lit_scene_mesh_subrender_internal.h:59
Definition forward_lit_scene_mesh_subrender_internal.h:144
Definition forward_lit_scene_mesh_subrender_internal.h:45
Definition forward_lit_scene_mesh_subrender_internal.h:137
Definition forward_lit_scene_mesh_subrender_internal.h:65