35 uint2 shadow_set_membership_)
43 level = clipmap_level;
78 uint2 shadow_set_membership_)
124 const float4 debug_color[6] = {
125 {1.0f, 0.1f, 0.1f, 1.0f},
126 {0.1f, 1.0f, 0.1f, 1.0f},
127 {0.0f, 0.2f, 1.0f, 1.0f},
128 {1.0f, 1.0f, 0.3f, 1.0f},
129 {0.1f, 0.1f, 0.1f, 1.0f},
130 {1.0f, 1.0f, 1.0f, 1.0f},
194 module.do_full_update_ = true;
199 if (newly_unused_count > 0) {
203 for (
uint index : newly_unused_indices) {
230 if (tilemaps_.size() <= tilemaps_needed) {
233 auto span = tilemaps_.as_span();
234 shadows_.tilemap_pool.release(span.drop_front(tilemaps_needed));
235 tilemaps_ = span.take_front(tilemaps_needed);
242 float4x4 object_to_world = light.object_to_world;
246 while (tilemaps_.size() < tilemaps_needed) {
247 tilemaps_.append(tilemap_pool.
acquire());
252 for (
int i : tilemaps_.index_range()) {
254 tilemaps_[face]->sync_cubeface(
255 light.type, object_to_world, near, far, face, light.shadow_set_membership);
258 light.local.tilemaps_count = tilemaps_needed;
263 tilemap->set_updated();
296void ShadowDirectional::cascade_tilemaps_distribution_near_far_points(
const Camera &camera,
301 const CameraData &cam_data = camera.data_get();
304 light.object_to_world, camera.position() - camera.forward() * cam_data.clip_far);
306 light.object_to_world, camera.position() - camera.forward() * cam_data.clip_near);
317 const int max_tilemap_per_shadows = 16;
318 const CameraData &cam_data = camera.data_get();
320 float3 near_point, far_point;
321 cascade_tilemaps_distribution_near_far_points(camera, light, near_point, far_point);
325 float depth_range_in_shadow_space =
distance(far_point.xy(), near_point.xy());
326 float min_depth_tilemap_size = 2 * (depth_range_in_shadow_space / max_tilemap_per_shadows);
329 float min_diagonal_tilemap_size = cam_data.screen_diagonal_length;
331 if (camera.is_perspective()) {
333 min_diagonal_tilemap_size *= cam_data.clip_far / cam_data.clip_near;
338 int lod_level =
ceil(
log2(
max_ff(min_depth_tilemap_size, min_diagonal_tilemap_size)) + 0.5);
344 int tilemap_len =
ceil(0.5f + depth_range_in_shadow_space / per_tilemap_coverage);
345 return IndexRange(lod_level, tilemap_len);
348void ShadowDirectional::cascade_tilemaps_distribution(
Light &light,
const Camera &camera)
350 using namespace blender::math;
352 float4x4 object_mat = light.object_to_world;
359 float3 near_point, far_point;
360 cascade_tilemaps_distribution_near_far_points(camera, light, near_point, far_point);
362 float2 local_view_direction =
normalize(far_point.xy() - near_point.xy());
363 float2 farthest_tilemap_center = local_view_direction * half_size * (levels_range.size() - 1);
366 light.object_to_world.x.w = near_point.
x;
367 light.object_to_world.y.w = near_point.
y;
368 light.object_to_world.z.w = near_point.
z;
373 int2 offset_vector =
int2(
round(farthest_tilemap_center / tile_size));
375 light.sun.clipmap_base_offset_neg =
int2(0);
376 light.sun.clipmap_base_offset_pos = (offset_vector * (1 << 16)) /
377 max_ii(levels_range.size() - 1, 1);
380 int level = levels_range.first();
381 for (
int i : IndexRange(levels_range.size())) {
382 ShadowTileMap *tilemap = tilemaps_[
i];
385 int2 level_offset = origin_offset +
387 tilemap->sync_orthographic(
391 shadows_.tilemap_pool.tilemaps_data.append(*tilemap);
392 tilemap->set_updated();
395 light.sun.clipmap_origin =
float2(origin_offset) * tile_size;
401 light.sun.clipmap_lod_min = levels_range.first();
402 light.sun.clipmap_lod_max = levels_range.last();
409IndexRange ShadowDirectional::clipmap_level_range(
const Camera &cam)
411 using namespace blender::math;
416 int max_level =
ceil(
log2(cam.bound_radius() +
distance(cam.bound_center(), cam.position())));
418 max_level =
max(min_level, max_level) + 1;
419 IndexRange range(min_level, max_level - min_level + 1);
422 const int max_tilemap_per_shadows = 24;
424 range = range.take_back(max_tilemap_per_shadows);
429void ShadowDirectional::clipmap_tilemaps_distribution(
Light &light,
const Camera &camera)
431 float4x4 object_mat = light.object_to_world;
434 for (
int lod : IndexRange(levels_range.size())) {
435 ShadowTileMap *tilemap = tilemaps_[lod];
437 int level = levels_range.first() + lod;
442 float2 light_space_camera_position = camera.position() *
float2x3(object_mat.
view<2, 3>());
445 tilemap->sync_orthographic(
449 shadows_.tilemap_pool.tilemaps_data.append(*tilemap);
450 tilemap->set_updated();
455 for (
int lod : IndexRange(levels_range.size() - 1)) {
461 int2 lvl_offset_next = tilemaps_[lod + 1]->grid_offset;
462 int2 lvl_offset = tilemaps_[lod]->grid_offset;
463 int2 lvl_delta = lvl_offset - (lvl_offset_next * 2);
470 light.sun.clipmap_base_offset_pos = pos_offset;
471 light.sun.clipmap_base_offset_neg = neg_offset;
474 int2 level_offset_max = tilemaps_[levels_range.size() - 1]->grid_offset;
481 light.object_to_world.x.w = location.
x;
482 light.object_to_world.y.w = location.
y;
483 light.object_to_world.z.w = location.
z;
485 light.sun.clipmap_origin =
float2(level_offset_max * tile_size_max);
487 light.sun.clipmap_lod_min = levels_range.first();
488 light.sun.clipmap_lod_max = levels_range.last();
494 cascade_level_range(light, camera) :
495 clipmap_level_range(camera);
497 if (levels_range == levels_new) {
502 IndexRange before_range(levels_range.start(), isect_range.
start() - levels_range.start());
506 auto span = tilemaps_.as_span();
507 shadows_.tilemap_pool.release(span.slice(before_range.
shift(-levels_range.start())));
508 shadows_.tilemap_pool.release(span.slice(after_range.
shift(-levels_range.start())));
509 tilemaps_ = span.slice(isect_range.
shift(-levels_range.start()));
510 levels_range = isect_range;
517 cascade_level_range(light, camera) :
518 clipmap_level_range(camera);
520 if (levels_range != levels_new) {
529 tilemaps_.append(tilemap_pool.
acquire());
532 tilemaps_.extend(cached_tilemaps);
534 tilemaps_.append(tilemap_pool.
acquire());
536 levels_range = levels_new;
540 light.clip_near = 0x7F7FFFFF;
541 light.clip_far = int(0xFF7FFFFFu ^ 0x7FFFFFFFu);
544 cascade_tilemaps_distribution(light, camera);
547 clipmap_tilemaps_distribution(light, camera);
560 for (
int i = 0;
i < statistics_buf_.size();
i++) {
562 statistics_buf_.current().clear_to_zero();
563 statistics_buf_.swap();
576 if (is_metal_backend && is_tile_based_arch) {
589 bool update_lights =
false;
591 bool use_jitter = enable_shadow &&
592 (inst_.is_image_render ||
593 (!inst_.is_navigating && !inst_.is_transforming && !inst_.is_playback &&
599 for (
Light &light : inst_.lights.light_map_.values()) {
600 light.initialized =
false;
609 const size_t page_byte_size =
square_i(shadow_page_size_) *
sizeof(int);
610 shadow_page_len_ = int(
divide_ceil_ul(pool_byte_size, page_byte_size));
620 if (atlas_tx_.ensure_2d_array(atlas_type, atlas_extent, atlas_layers, tex_usage)) {
622 do_full_update_ =
true;
626 if (!atlas_tx_.is_valid()) {
627 atlas_tx_.ensure_2d_array(ShadowModule::atlas_type,
int2(1), 1);
628 inst_.info_append_i18n(
629 "Error: Could not allocate shadow atlas. Most likely out of GPU memory.");
633 if (inst_.is_viewport()) {
634 if (inst_.sampling.finished_viewport()) {
636 for (
int i = 0;
i < statistics_buf_.size();
i++) {
637 statistics_buf_.swap();
641 statistics_buf_.swap();
643 statistics_buf_.current().read();
647 inst_.info_append_i18n(
648 "Error: Shadow buffer full, may result in missing shadows and lower "
649 "performance. ({} / {})",
654 inst_.info_append_i18n(
"Error: Too many shadow updates, some shadows might be incorrect.");
658 atlas_tx_.filter_mode(
false);
662 for (
int i = 0;
i < multi_viewports_.size();
i++) {
666 multi_viewports_[
i][0] = 0;
667 multi_viewports_[
i][1] = 0;
668 multi_viewports_[
i][2] = size_in_tile * shadow_page_size_;
669 multi_viewports_[
i][3] = size_in_tile * shadow_page_size_;
675 past_casters_updated_.clear();
676 curr_casters_updated_.clear();
677 curr_casters_.clear();
678 jittered_transparent_casters_.clear();
679 update_casters_ =
true;
681 if (box_batch_ ==
nullptr) {
686 Manager &manager = *inst_.manager;
691 if (inst_.is_baking()) {
692 SurfelBuf &surfels_buf = inst_.volume_probes.bake.surfels_buf_;
693 CaptureInfoBuf &capture_info_buf = inst_.volume_probes.bake.capture_info_buf_;
694 float surfel_coverage_area = inst_.volume_probes.bake.surfel_density_;
698 int directional_level = std::max(0,
int(std::ceil(
log2(surfel_coverage_area / texel_size))));
704 sub.
bind_ssbo(
"surfel_buf", &surfels_buf);
705 sub.
bind_ssbo(
"capture_info_buf", &capture_info_buf);
709 sub.
dispatch(&inst_.volume_probes.bake.dispatch_per_surfel_);
722 sub.
push_constant(
"input_depth_extent", &input_depth_extent_);
726 sub.
dispatch(&dispatch_depth_scan_size_);
740 sub.
push_constant(
"fb_resolution", &usage_tag_fb_resolution_);
746 tilemap_usage_transparent_ps_ = ⊂
755 bool has_transparent_shadows)
758 if (!is_shadow_caster && !is_alpha_blend) {
763 shadow_ob.
used =
true;
765 const bool has_jittered_transparency = has_transparent_shadows && data_.use_jitter;
766 if (is_shadow_caster && (handle.
recalc || !is_initialized || has_jittered_transparency)) {
767 if (handle.
recalc && is_initialized) {
771 if (has_jittered_transparency) {
772 jittered_transparent_casters_.append(resource_handle.
raw);
775 curr_casters_updated_.append(resource_handle.
raw);
780 if (is_shadow_caster) {
781 curr_casters_.append(resource_handle.
raw);
784 if (is_alpha_blend && !inst_.is_baking()) {
785 tilemap_usage_transparent_ps_->draw(box_batch_, resource_handle);
792 for (
Light &light : inst_.lights.light_map_.values()) {
794 if ((!light.used || !enabled_) && !inst_.is_baking()) {
795 light.shadow_discard_safe(*
this);
797 else if (light.directional !=
nullptr) {
798 light.directional->release_excess_tilemaps(light, inst_.camera);
800 else if (light.punctual !=
nullptr) {
801 light.punctual->release_excess_tilemaps(light);
807 for (
Light &light : inst_.lights.light_map_.values()) {
808 if (enabled_ ==
false) {
811 else if (light.directional !=
nullptr) {
812 light.directional->end_sync(light, inst_.camera);
814 else if (light.punctual !=
nullptr) {
815 light.punctual->end_sync(light);
824 auto it_end = objects_.items().end();
825 for (
auto it = objects_.items().begin(); it != it_end; ++it) {
828 if (!shadow_ob.
used && !inst_.is_baking()) {
835 shadow_ob.
used =
false;
838 past_casters_updated_.push_update();
839 curr_casters_updated_.push_update();
840 jittered_transparent_casters_.push_update();
842 curr_casters_.push_update();
844 if (do_full_update_) {
845 do_full_update_ =
false;
854 pages_free_data_[
i] = 0xFFFFFFFFu;
856 pages_free_data_.push_update();
866 pages_infos_data_.page_free_count = shadow_page_len_;
867 pages_infos_data_.page_alloc_count = 0;
868 pages_infos_data_.page_cached_next = 0u;
869 pages_infos_data_.page_cached_start = 0u;
870 pages_infos_data_.page_cached_end = 0u;
871 pages_infos_data_.push_update();
875 Manager &manager = *inst_.manager;
898 sub.
bind_ssbo(
"casters_id_buf", curr_casters_);
900 sub.
push_constant(
"resource_len",
int(curr_casters_.size()));
915 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
934 if (past_casters_updated_.size() > 0) {
936 pass.
bind_ssbo(
"resource_ids_buf", past_casters_updated_);
940 if (curr_casters_updated_.size() > 0) {
942 pass.
bind_ssbo(
"resource_ids_buf", curr_casters_updated_);
950 PassSimple &pass = jittered_transparent_caster_update_ps_;
952 if (jittered_transparent_casters_.size() > 0) {
957 pass.
bind_ssbo(
"resource_ids_buf", jittered_transparent_casters_);
959 int3(jittered_transparent_casters_.size(), 1,
tilemap_pool.tilemaps_data.size()));
967 if (inst_.volume.needs_shadow_tagging() && !inst_.is_baking()) {
989 sub.
push_constant(
"max_view_per_tilemap", &max_view_per_tilemap_);
1001 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1002 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1003 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1016 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1017 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1018 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1019 sub.
bind_ssbo(
"statistics_buf", statistics_buf_.current());
1020 sub.
bind_ssbo(
"clear_dispatch_buf", clear_dispatch_buf_);
1021 sub.
bind_ssbo(
"tile_draw_buf", tile_draw_buf_);
1031 sub.
bind_ssbo(
"statistics_buf", statistics_buf_.current());
1032 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1033 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1034 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1044 sub.
bind_ssbo(
"pages_infos_buf", &pages_infos_data_);
1045 sub.
bind_ssbo(
"statistics_buf", &statistics_buf_.current());
1046 sub.
bind_ssbo(
"view_infos_buf", &shadow_multi_view_.matrices_ubo_get());
1047 sub.
bind_ssbo(
"render_view_buf", &render_view_buf_);
1058 sub.
bind_ssbo(
"statistics_buf", &statistics_buf_.current());
1059 sub.
bind_ssbo(
"render_view_buf", &render_view_buf_);
1061 sub.
bind_ssbo(
"clear_dispatch_buf", &clear_dispatch_buf_);
1062 sub.
bind_ssbo(
"tile_draw_buf", &tile_draw_buf_);
1063 sub.
bind_ssbo(
"dst_coord_buf", &dst_coord_buf_);
1064 sub.
bind_ssbo(
"src_coord_buf", &src_coord_buf_);
1065 sub.
bind_ssbo(
"render_map_buf", &render_map_buf_);
1088 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1089 sub.
bind_ssbo(
"dst_coord_buf", dst_coord_buf_);
1090 sub.
bind_image(
"shadow_atlas_img", atlas_tx_);
1102 if (!
ELEM(inst_.debug_mode,
1112 debug_draw_ps_.init();
1114 Object *object_active = inst_.draw_ctx->obact;
1115 if (object_active ==
nullptr) {
1121 if (inst_.lights.light_map_.contains(object_key) ==
false) {
1125 Light &light = inst_.lights.light_map_.lookup(object_key);
1134 debug_draw_ps_.state_set(
state);
1135 debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(
SHADOW_DEBUG));
1136 debug_draw_ps_.push_constant(
"debug_mode",
int(inst_.debug_mode));
1137 debug_draw_ps_.push_constant(
"debug_tilemap_index", light.tilemap_index);
1138 debug_draw_ps_.bind_ssbo(
"tilemaps_buf", &
tilemap_pool.tilemaps_data);
1139 debug_draw_ps_.bind_ssbo(
"tiles_buf", &
tilemap_pool.tiles_data);
1140 debug_draw_ps_.bind_resources(inst_.uniform_data);
1141 debug_draw_ps_.bind_resources(inst_.hiz_buffer.front);
1142 debug_draw_ps_.bind_resources(inst_.lights);
1143 debug_draw_ps_.bind_resources(inst_.shadows);
1148 bool is_perspective,
1151 float min_dim = float(
min_ii(extent.x, extent.y));
1157 if (is_perspective) {
1164bool ShadowModule::shadow_update_finished(
int loop_count)
1187 statistics_buf_.current().async_flush_to_host();
1188 statistics_buf_.current().read();
1189 ShadowStatistics stats = statistics_buf_.current();
1191 if (stats.page_used_count > shadow_page_len_) {
1192 inst_.info_append_i18n(
1193 "Error: Shadow buffer full, may result in missing shadows and lower "
1194 "performance. ({} / {})",
1195 stats.page_used_count,
1203int ShadowModule::max_view_per_tilemap()
1205 if (inst_.is_image_render) {
1212 int potential_view_count = 0;
1213 for (
auto i : IndexRange(
tilemap_pool.tilemaps_data.size())) {
1218 potential_view_count += 1;
1223 if (inst_.is_transforming || inst_.is_navigating) {
1224 max_view_count =
math::min(2, max_view_count);
1227 if (inst_.is_playback) {
1228 max_view_count =
math::min(1, max_view_count);
1231 return max_view_count;
1234void ShadowModule::ShadowView::compute_visibility(
ObjectBoundsBuf &bounds,
1244 resource_len * word_per_draw;
1273 if (enabled_ ==
false) {
1278 input_depth_extent_ = extent;
1284 max_view_per_tilemap_ = max_view_per_tilemap();
1287 inst_.uniform_data.push_update();
1290 usage_tag_fb.ensure(usage_tag_fb_resolution_);
1298 shadow_depth_fb_tx_.free();
1299 shadow_depth_accum_tx_.free();
1300 render_fb_.ensure(fb_size);
1305 shadow_depth_accum_tx_.ensure_2d_array(
GPU_R32F, fb_size, fb_layers, usage);
1313 inst_.hiz_buffer.update();
1321 inst_.manager->submit(tilemap_setup_ps_,
view);
1326 inst_.manager->submit(caster_update_ps_,
view);
1328 if (loop_count == 0) {
1329 inst_.manager->submit(jittered_transparent_caster_update_ps_,
view);
1331 inst_.manager->submit(tilemap_usage_ps_,
view);
1332 inst_.manager->submit(tilemap_update_ps_,
view);
1334 shadow_multi_view_.compute_procedural_bounds();
1336 statistics_buf_.current().async_flush_to_host();
1343 use_flush |= loop_count != 0;
1350 if (shadow_depth_fb_tx_.is_valid() && shadow_depth_accum_tx_.is_valid()) {
1361 else if (shadow_depth_fb_tx_.is_valid()) {
1374 reinterpret_cast<int(*)[4]
>(multi_viewports_.data()));
1376 inst_.pipelines.shadow.render(shadow_multi_view_);
1388 }
while (!shadow_update_finished(loop_count));
1397 if (!
ELEM(inst_.debug_mode,
1406 switch (inst_.debug_mode) {
1408 inst_.info_append(
"Debug Mode: Shadow Tilemap");
1411 inst_.info_append(
"Debug Mode: Shadow Values");
1414 inst_.info_append(
"Debug Mode: Shadow Tile Random Color");
1417 inst_.info_append(
"Debug Mode: Shadow Tilemap Random Color");
1423 inst_.hiz_buffer.update();
1426 inst_.manager->submit(debug_draw_ps_,
view);
#define BLI_assert_unreachable()
MINLINE uint ceil_to_multiple_u(uint a, uint b)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE int square_i(int a)
MINLINE int max_ii(int a, int b)
MINLINE uint64_t divide_ceil_ul(uint64_t a, uint64_t b)
MINLINE int clamp_i(int value, int min, int max)
MINLINE float int_as_float(int i)
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
T * DEG_get_original(T *id)
@ SCE_EEVEE_SHADOW_ENABLED
@ SCE_EEVEE_SHADOW_JITTERED_VIEWPORT
blender::gpu::Batch * GPU_batch_unit_cube() ATTR_WARN_UNUSED_RESULT
@ GPU_STOREACTION_DONT_CARE
void GPU_compute_dispatch(GPUShader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
eGPUBackendType GPU_backend_get_type()
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
void GPU_framebuffer_multi_viewports_set(GPUFrameBuffer *gpu_fb, const int viewport_rects[GPU_MAX_VIEWPORTS][4])
#define GPU_ATTACHMENT_TEXTURE(_texture)
GPUFrameBuffer * GPU_framebuffer_active_get()
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
#define GPU_framebuffer_bind_ex(_fb,...)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_SHADER_STORAGE
@ GPU_BARRIER_TEXTURE_FETCH
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
void GPU_storagebuf_bind(GPUStorageBuf *ssbo, int slot)
void GPU_storagebuf_clear(GPUStorageBuf *ssbo, uint32_t clear_value)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
@ GPU_TEXTURE_USAGE_MEMORYLESS
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_ATOMIC
BMesh const char void * data
constexpr int64_t one_after_last() const
constexpr IndexRange shift(int64_t n) const
constexpr IndexRange intersect(IndexRange other) const
constexpr int64_t start() const
SwapChain< ObjectBoundsBuf, 2 > bounds_buf
void append(const T &value)
UniformArrayBuffer< ViewCullingData, DRW_VIEW_MAX > culling_
VisibilityBuf visibility_buf_
UniformArrayBuffer< ViewMatrices, DRW_VIEW_MAX > data_
int visibility_word_per_draw() const
void bind_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
void bind_resources(U &resources)
void bind_image(const char *name, GPUTexture *image)
PassBase< DrawCommandBufType > & sub(const char *name)
void dispatch(int group_len)
void barrier(eGPUBarrier type)
void state_set(DRWState state, int clip_plane_count=0)
void framebuffer_set(GPUFrameBuffer **framebuffer)
void state_stencil(uint8_t write_mask, uint8_t reference, uint8_t compare_mask)
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
detail::PassBase< command::DrawMultiBuf > Sub
bool is_perspective() const
A running instance of the engine.
void info_append_i18n(const char *msg, Args &&...args)
static float coverage_get(int lvl)
static float tile_size_get(int lvl)
void end_sync(Light &light, const Camera &camera)
void release_excess_tilemaps(const Light &light, const Camera &camera)
ShadowModule(Instance &inst, ShadowSceneData &data)
ShadowTileMapPool tilemap_pool
void debug_draw(View &view, GPUFrameBuffer *view_fb)
static float screen_pixel_radius(const float4x4 &wininv, bool is_perspective, const int2 &extent)
void set_view(View &view, int2 extent)
static ShadowTechnique shadow_technique
void sync_object(const Object *ob, const ObjectHandle &handle, const ResourceHandle &resource_handle, bool is_alpha_blend, bool has_transparent_shadows)
void release_excess_tilemaps(const Light &light)
void end_sync(Light &light)
Simple API to draw debug shapes and log in the viewport.
#define DRW_VISIBILITY_GROUP_SIZE
#define DRW_VIEW_CULLING_UBO_SLOT
#define DRW_OBJ_INFOS_SLOT
#define DRW_VIEW_UBO_SLOT
@ DRW_STATE_WRITE_STENCIL
#define SHADOW_TILEMAP_RES
#define SHADOW_MAX_TILEMAP
#define SHADOW_PAGE_PER_ROW
#define SHADOW_CLIPMAP_GROUP_SIZE
#define SHADOW_DEPTH_SCAN_GROUP_SIZE
#define VOLUME_GROUP_SIZE
#define SHADOW_TILEDATA_PER_TILEMAP
#define SHADOW_BOUNDS_GROUP_SIZE
#define SHADOW_PAGE_PER_COL
#define SHADOW_PAGE_PER_LAYER
#define SHADOW_TILEMAP_LOD
VecBase< float, D > normalize(VecOp< float, D >) RET
detail::Pass< command::DrawCommandBuf > PassSimple
detail::Pass< command::DrawMultiBuf > PassMain
void drw_debug_matrix_as_bbox(const float4x4 &mat, const float4 color, const uint lifetime)
StorageArrayBuffer< ObjectBounds, 128 > ObjectBoundsBuf
StorageArrayBuffer< ObjectInfos, 128 > ObjectInfosBuf
@ SHADOW_TILEMAP_TAG_USAGE_SURFELS
@ SHADOW_TILEMAP_RENDERMAP
@ SHADOW_TILEMAP_FINALIZE
@ SHADOW_TILEMAP_TAG_USAGE_OPAQUE
@ SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT
@ SHADOW_TILEMAP_TAG_USAGE_VOLUME
@ SHADOW_TILEMAP_TAG_UPDATE
static constexpr const float shadow_face_mat[6][3][3]
static int2 shadow_cascade_grid_offset(int2 base_offset, int level_relative)
static int light_local_tilemap_count(LightData light)
static float3 transform_direction_transposed(Transform t, float3 direction)
draw::StorageArrayBuffer< Surfel, 64 > SurfelBuf
draw::StorageBuffer< CaptureInfoData > CaptureInfoBuf
@ DEBUG_SHADOW_TILE_RANDOM_COLOR
@ DEBUG_SHADOW_TILEMAP_RANDOM_COLOR
static uint shadow_page_pack(uint3 page)
@ SHADOW_PROJECTION_CLIPMAP
@ SHADOW_PROJECTION_CASCADE
@ SHADOW_PROJECTION_CUBEFACE
MatBase< T, 4, 4 > orthographic(T left, T right, T bottom, T top, T near_clip, T far_clip)
Create an orthographic projection matrix using OpenGL coordinate convention: Maps each axis range to ...
MatBase< T, 4, 4 > perspective(T left, T right, T bottom, T top, T near_clip, T far_clip)
Create a perspective projection matrix using OpenGL coordinate convention: Maps each axis range to [-...
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
T distance(const T &a, const T &b)
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
T min(const T &a, const T &b)
CartesianBasis invert(const CartesianBasis &basis)
VectorT project_point(const MatT &mat, const VectorT &point)
T max(const T &a, const T &b)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
VecBase< uint32_t, 2 > uint2
VecBase< uint32_t, 4 > uint4
MatBase< float, 2, 3 > float2x3
VecBase< uint32_t, 3 > uint3
bool assign_if_different(T &old_value, T new_value)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
static struct PyModuleDef module
float shadow_resolution_scale
const c_style_mat & ptr() const
const MatView< T, ViewNumCol, ViewNumRow, NumCol, NumRow, SrcStartCol, SrcStartRow, Alignment > view() const
ResourceHandle resource_handle
eShadowProjectionType projection_type
uint2 shadow_set_membership
ShadowTileMapDataBuf tilemaps_data
ShadowTileMapDataBuf tilemaps_unused
ShadowTileDataBuf tiles_data
void release(Span< ShadowTileMap * > free_list)
ShadowTileMapClipBuf tilemaps_clip
void end_sync(ShadowModule &module)
ShadowTileMap * acquire()
Vector< uint > free_indices
Pool< ShadowTileMap > tilemap_pool
static constexpr int64_t maps_per_row
void sync_orthographic(const float4x4 &object_mat_, int2 origin_offset, int clipmap_level, eShadowProjectionType projection_type_, uint2 shadow_set_membership_=~uint2(0))
static constexpr int64_t tile_map_resolution
void sync_cubeface(eLightType light_type_, const float4x4 &object_mat, float near, float far, eCubeFace face, uint2 shadow_set_membership_=~uint2(0))