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},
160 tilemap_tx.ensure_2d(gpu::TextureFormat::UINT_32, extent, usage);
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;
339 min_diagonal_tilemap_size =
max(min_diagonal_tilemap_size, 0.5f);
343 int lod_level =
ceil(
log2(
max_ff(min_depth_tilemap_size, min_diagonal_tilemap_size)) + 0.5);
349 int tilemap_len =
ceil(0.5f + depth_range_in_shadow_space / per_tilemap_coverage);
350 return IndexRange(lod_level, tilemap_len);
353void ShadowDirectional::cascade_tilemaps_distribution(
Light &light,
const Camera &camera)
355 using namespace blender::math;
357 float4x4 object_mat = light.object_to_world;
364 float3 near_point, far_point;
365 cascade_tilemaps_distribution_near_far_points(camera, light, near_point, far_point);
367 float2 local_view_direction =
normalize(far_point.xy() - near_point.xy());
368 float2 farthest_tilemap_center = local_view_direction * half_size * (levels_range.size() - 1);
371 light.object_to_world.x.w = near_point.
x;
372 light.object_to_world.y.w = near_point.
y;
373 light.object_to_world.z.w = near_point.
z;
378 int2 offset_vector =
int2(
round(farthest_tilemap_center / tile_size));
380 light.sun.clipmap_base_offset_neg =
int2(0);
381 light.sun.clipmap_base_offset_pos = (offset_vector * (1 << 16)) /
382 max_ii(levels_range.size() - 1, 1);
385 int level = levels_range.first();
386 for (
int i : IndexRange(levels_range.size())) {
387 ShadowTileMap *tilemap = tilemaps_[
i];
390 int2 level_offset = origin_offset +
392 tilemap->sync_orthographic(
396 shadows_.tilemap_pool.tilemaps_data.append(*tilemap);
397 tilemap->set_updated();
400 light.sun.clipmap_origin =
float2(origin_offset) * tile_size;
406 light.sun.clipmap_lod_min = levels_range.first();
407 light.sun.clipmap_lod_max = levels_range.last();
414IndexRange ShadowDirectional::clipmap_level_range(
const Camera &cam)
416 using namespace blender::math;
421 int max_level =
ceil(
log2(cam.bound_radius() +
distance(cam.bound_center(), cam.position())));
423 max_level =
max(min_level, max_level) + 1;
424 IndexRange range(min_level, max_level - min_level + 1);
427 const int max_tilemap_per_shadows = 24;
429 range = range.take_back(max_tilemap_per_shadows);
434void ShadowDirectional::clipmap_tilemaps_distribution(
Light &light,
const Camera &camera)
436 float4x4 object_mat = light.object_to_world;
439 for (
int lod : IndexRange(levels_range.size())) {
440 ShadowTileMap *tilemap = tilemaps_[lod];
442 int level = levels_range.first() + lod;
447 float2 light_space_camera_position = camera.position() *
float2x3(object_mat.
view<2, 3>());
450 tilemap->sync_orthographic(
454 shadows_.tilemap_pool.tilemaps_data.append(*tilemap);
455 tilemap->set_updated();
460 for (
int lod : IndexRange(levels_range.size() - 1)) {
466 int2 lvl_offset_next = tilemaps_[lod + 1]->grid_offset;
467 int2 lvl_offset = tilemaps_[lod]->grid_offset;
468 int2 lvl_delta = lvl_offset - (lvl_offset_next * 2);
475 light.sun.clipmap_base_offset_pos = pos_offset;
476 light.sun.clipmap_base_offset_neg = neg_offset;
479 int2 level_offset_max = tilemaps_[levels_range.size() - 1]->grid_offset;
486 light.object_to_world.x.w = location.
x;
487 light.object_to_world.y.w = location.
y;
488 light.object_to_world.z.w = location.
z;
490 light.sun.clipmap_origin =
float2(level_offset_max * tile_size_max);
492 light.sun.clipmap_lod_min = levels_range.first();
493 light.sun.clipmap_lod_max = levels_range.last();
499 cascade_level_range(light, camera) :
500 clipmap_level_range(camera);
502 if (levels_range == levels_new) {
507 IndexRange before_range(levels_range.start(), isect_range.
start() - levels_range.start());
511 auto span = tilemaps_.as_span();
512 shadows_.tilemap_pool.release(span.slice(before_range.
shift(-levels_range.start())));
513 shadows_.tilemap_pool.release(span.slice(after_range.
shift(-levels_range.start())));
514 tilemaps_ = span.slice(isect_range.
shift(-levels_range.start()));
515 levels_range = isect_range;
522 cascade_level_range(light, camera) :
523 clipmap_level_range(camera);
525 if (levels_range != levels_new) {
534 tilemaps_.append(tilemap_pool.
acquire());
537 tilemaps_.extend(cached_tilemaps);
539 tilemaps_.append(tilemap_pool.
acquire());
541 levels_range = levels_new;
545 light.clip_near = 0x7F7FFFFF;
546 light.clip_far = int(0xFF7FFFFFu ^ 0x7FFFFFFFu);
549 cascade_tilemaps_distribution(light, camera);
552 clipmap_tilemaps_distribution(light, camera);
565 for (
int i = 0;
i < statistics_buf_.size();
i++) {
567 statistics_buf_.current().clear_to_zero();
568 statistics_buf_.swap();
581 if (is_metal_backend && is_tile_based_arch) {
594 bool update_lights =
false;
596 bool use_jitter = enable_shadow &&
597 (inst_.is_image_render ||
598 (!inst_.is_navigating && !inst_.is_transforming && !inst_.is_playback &&
604 for (
Light &light : inst_.lights.light_map_.values()) {
605 light.initialized =
false;
614 const size_t page_byte_size =
square_i(shadow_page_size_) *
sizeof(int);
615 shadow_page_len_ = int(
divide_ceil_ul(pool_byte_size, page_byte_size));
625 if (atlas_tx_.ensure_2d_array(atlas_type, atlas_extent, atlas_layers, tex_usage)) {
627 do_full_update_ =
true;
631 if (!atlas_tx_.is_valid()) {
632 atlas_tx_.ensure_2d_array(ShadowModule::atlas_type,
int2(1), 1);
633 inst_.info_append_i18n(
634 "Error: Could not allocate shadow atlas. Most likely out of GPU memory.");
638 if (inst_.is_viewport()) {
639 if (inst_.sampling.finished_viewport()) {
641 for (
int i = 0;
i < statistics_buf_.size();
i++) {
642 statistics_buf_.swap();
646 statistics_buf_.swap();
648 statistics_buf_.current().read();
652 inst_.info_append_i18n(
653 "Error: Shadow buffer full, may result in missing shadows and lower "
654 "performance. ({} / {})",
659 inst_.info_append_i18n(
"Error: Too many shadow updates, some shadows might be incorrect.");
663 atlas_tx_.filter_mode(
false);
667 for (
int i = 0;
i < multi_viewports_.size();
i++) {
671 multi_viewports_[
i][0] = 0;
672 multi_viewports_[
i][1] = 0;
673 multi_viewports_[
i][2] = size_in_tile * shadow_page_size_;
674 multi_viewports_[
i][3] = size_in_tile * shadow_page_size_;
680 past_casters_updated_.clear();
681 curr_casters_updated_.clear();
682 curr_casters_.clear();
683 jittered_transparent_casters_.clear();
684 update_casters_ =
true;
686 if (box_batch_ ==
nullptr) {
691 Manager &manager = *inst_.manager;
696 if (inst_.is_baking()) {
697 SurfelBuf &surfels_buf = inst_.volume_probes.bake.surfels_buf_;
698 CaptureInfoBuf &capture_info_buf = inst_.volume_probes.bake.capture_info_buf_;
699 float surfel_coverage_area = inst_.volume_probes.bake.surfel_density_;
703 int directional_level = std::max(0,
int(std::ceil(
log2(surfel_coverage_area / texel_size))));
709 sub.
bind_ssbo(
"surfel_buf", &surfels_buf);
710 sub.
bind_ssbo(
"capture_info_buf", &capture_info_buf);
714 sub.
dispatch(&inst_.volume_probes.bake.dispatch_per_surfel_);
727 sub.
push_constant(
"input_depth_extent", &input_depth_extent_);
731 sub.
dispatch(&dispatch_depth_scan_size_);
745 sub.
push_constant(
"fb_resolution", &usage_tag_fb_resolution_);
751 tilemap_usage_transparent_ps_ = ⊂
760 bool has_transparent_shadows)
763 if (!is_shadow_caster && !is_alpha_blend) {
768 shadow_ob.
used =
true;
770 const bool has_jittered_transparency = has_transparent_shadows && data_.use_jitter;
771 if (is_shadow_caster && (handle.
recalc || !is_initialized || has_jittered_transparency)) {
772 if (handle.
recalc && is_initialized) {
776 if (has_jittered_transparency) {
777 jittered_transparent_casters_.append(resource_handle.
raw());
780 curr_casters_updated_.append(resource_handle.
raw());
785 if (is_shadow_caster) {
786 curr_casters_.append(resource_handle.
raw());
789 if (is_alpha_blend && !inst_.is_baking()) {
790 tilemap_usage_transparent_ps_->draw(box_batch_, resource_handle);
797 for (
Light &light : inst_.lights.light_map_.values()) {
799 if ((!light.used || !enabled_) && !inst_.is_baking()) {
800 light.shadow_discard_safe(*
this);
802 else if (light.directional !=
nullptr) {
803 light.directional->release_excess_tilemaps(light, inst_.camera);
805 else if (light.punctual !=
nullptr) {
806 light.punctual->release_excess_tilemaps(light);
812 for (
Light &light : inst_.lights.light_map_.values()) {
813 if (enabled_ ==
false) {
816 else if (light.directional !=
nullptr) {
817 light.directional->end_sync(light, inst_.camera);
819 else if (light.punctual !=
nullptr) {
820 light.punctual->end_sync(light);
829 auto it_end = objects_.items().end();
830 for (
auto it = objects_.items().begin(); it != it_end; ++it) {
833 if (!shadow_ob.
used && !inst_.is_baking()) {
840 shadow_ob.
used =
false;
843 past_casters_updated_.push_update();
844 curr_casters_updated_.push_update();
845 jittered_transparent_casters_.push_update();
847 curr_casters_.push_update();
849 if (do_full_update_) {
850 do_full_update_ =
false;
859 pages_free_data_[
i] = 0xFFFFFFFFu;
861 pages_free_data_.push_update();
871 pages_infos_data_.page_free_count = shadow_page_len_;
872 pages_infos_data_.page_alloc_count = 0;
873 pages_infos_data_.page_cached_next = 0u;
874 pages_infos_data_.page_cached_start = 0u;
875 pages_infos_data_.page_cached_end = 0u;
876 pages_infos_data_.push_update();
880 Manager &manager = *inst_.manager;
903 sub.
bind_ssbo(
"casters_id_buf", curr_casters_);
905 sub.
push_constant(
"resource_len",
int(curr_casters_.size()));
920 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
939 if (past_casters_updated_.size() > 0) {
941 pass.
bind_ssbo(
"resource_ids_buf", past_casters_updated_);
945 if (curr_casters_updated_.size() > 0) {
947 pass.
bind_ssbo(
"resource_ids_buf", curr_casters_updated_);
955 PassSimple &pass = jittered_transparent_caster_update_ps_;
957 if (jittered_transparent_casters_.size() > 0) {
962 pass.
bind_ssbo(
"resource_ids_buf", jittered_transparent_casters_);
964 int3(jittered_transparent_casters_.size(), 1,
tilemap_pool.tilemaps_data.size()));
972 if (inst_.volume.needs_shadow_tagging() && !inst_.is_baking()) {
994 sub.
push_constant(
"max_view_per_tilemap", &max_view_per_tilemap_);
1006 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1007 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1008 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1021 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1022 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1023 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1024 sub.
bind_ssbo(
"statistics_buf", statistics_buf_.current());
1025 sub.
bind_ssbo(
"clear_dispatch_buf", clear_dispatch_buf_);
1026 sub.
bind_ssbo(
"tile_draw_buf", tile_draw_buf_);
1036 sub.
bind_ssbo(
"statistics_buf", statistics_buf_.current());
1037 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1038 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1039 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1049 sub.
bind_ssbo(
"pages_infos_buf", &pages_infos_data_);
1050 sub.
bind_ssbo(
"statistics_buf", &statistics_buf_.current());
1051 sub.
bind_ssbo(
"view_infos_buf", &shadow_multi_view_.matrices_ubo_get());
1052 sub.
bind_ssbo(
"render_view_buf", &render_view_buf_);
1063 sub.
bind_ssbo(
"statistics_buf", &statistics_buf_.current());
1064 sub.
bind_ssbo(
"render_view_buf", &render_view_buf_);
1066 sub.
bind_ssbo(
"clear_dispatch_buf", &clear_dispatch_buf_);
1067 sub.
bind_ssbo(
"tile_draw_buf", &tile_draw_buf_);
1068 sub.
bind_ssbo(
"dst_coord_buf", &dst_coord_buf_);
1069 sub.
bind_ssbo(
"src_coord_buf", &src_coord_buf_);
1070 sub.
bind_ssbo(
"render_map_buf", &render_map_buf_);
1093 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1094 sub.
bind_ssbo(
"dst_coord_buf", dst_coord_buf_);
1095 sub.
bind_image(
"shadow_atlas_img", atlas_tx_);
1107 if (!
ELEM(inst_.debug_mode,
1117 debug_draw_ps_.init();
1119 Object *object_active = inst_.draw_ctx->obact;
1120 if (object_active ==
nullptr) {
1126 if (inst_.lights.light_map_.contains(object_key) ==
false) {
1130 Light &light = inst_.lights.light_map_.lookup(object_key);
1139 debug_draw_ps_.state_set(
state);
1140 debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(
SHADOW_DEBUG));
1141 debug_draw_ps_.push_constant(
"debug_mode",
int(inst_.debug_mode));
1142 debug_draw_ps_.push_constant(
"debug_tilemap_index", light.tilemap_index);
1143 debug_draw_ps_.bind_ssbo(
"tilemaps_buf", &
tilemap_pool.tilemaps_data);
1144 debug_draw_ps_.bind_ssbo(
"tiles_buf", &
tilemap_pool.tiles_data);
1145 debug_draw_ps_.bind_resources(inst_.uniform_data);
1146 debug_draw_ps_.bind_resources(inst_.hiz_buffer.front);
1147 debug_draw_ps_.bind_resources(inst_.lights);
1148 debug_draw_ps_.bind_resources(inst_.shadows);
1153 bool is_perspective,
1156 float min_dim =
float(
min_ii(extent.x, extent.y));
1162 if (is_perspective) {
1169bool ShadowModule::shadow_update_finished(
int loop_count)
1192 statistics_buf_.current().async_flush_to_host();
1193 statistics_buf_.current().read();
1194 ShadowStatistics stats = statistics_buf_.current();
1196 if (stats.page_used_count > shadow_page_len_) {
1197 inst_.info_append_i18n(
1198 "Error: Shadow buffer full, may result in missing shadows and lower "
1199 "performance. ({} / {})",
1200 stats.page_used_count,
1208int ShadowModule::max_view_per_tilemap()
1210 if (inst_.is_image_render) {
1217 int potential_view_count = 0;
1218 for (
auto i : IndexRange(
tilemap_pool.tilemaps_data.size())) {
1223 potential_view_count += 1;
1228 if (inst_.is_transforming || inst_.is_navigating) {
1229 max_view_count =
math::min(2, max_view_count);
1232 if (inst_.is_playback) {
1233 max_view_count =
math::min(1, max_view_count);
1236 return max_view_count;
1239void ShadowModule::ShadowView::compute_visibility(
ObjectBoundsBuf &bounds,
1249 resource_len * word_per_draw;
1278 if (enabled_ ==
false) {
1283 input_depth_extent_ = extent;
1289 max_view_per_tilemap_ = max_view_per_tilemap();
1292 inst_.uniform_data.push_update();
1295 usage_tag_fb.ensure(usage_tag_fb_resolution_);
1303 shadow_depth_fb_tx_.free();
1304 shadow_depth_accum_tx_.free();
1305 render_fb_.ensure(fb_size);
1309 shadow_depth_fb_tx_.ensure_2d_array(
1310 gpu::TextureFormat::SFLOAT_32_DEPTH, fb_size, fb_layers, usage);
1311 shadow_depth_accum_tx_.ensure_2d_array(
1312 gpu::TextureFormat::SFLOAT_32, fb_size, fb_layers, usage);
1320 inst_.hiz_buffer.update();
1328 inst_.manager->submit(tilemap_setup_ps_,
view);
1333 inst_.manager->submit(caster_update_ps_,
view);
1335 if (loop_count == 0) {
1336 inst_.manager->submit(jittered_transparent_caster_update_ps_,
view);
1338 inst_.manager->submit(tilemap_usage_ps_,
view);
1339 inst_.manager->submit(tilemap_update_ps_,
view);
1341 shadow_multi_view_.compute_procedural_bounds();
1343 statistics_buf_.current().async_flush_to_host();
1350 use_flush |= loop_count != 0;
1357 if (shadow_depth_fb_tx_.is_valid() && shadow_depth_accum_tx_.is_valid()) {
1368 else if (shadow_depth_fb_tx_.is_valid()) {
1381 reinterpret_cast<int (*)[4]
>(multi_viewports_.data()));
1383 inst_.pipelines.shadow.render(shadow_multi_view_);
1395 }
while (!shadow_update_finished(loop_count));
1404 if (!
ELEM(inst_.debug_mode,
1413 switch (inst_.debug_mode) {
1415 inst_.info_append(
"Debug Mode: Shadow Tilemap");
1418 inst_.info_append(
"Debug Mode: Shadow Values");
1421 inst_.info_append(
"Debug Mode: Shadow Tile Random Color");
1424 inst_.info_append(
"Debug Mode: Shadow Tilemap Random Color");
1430 inst_.hiz_buffer.update();
1433 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(blender::gpu::Shader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
GPUBackendType GPU_backend_get_type()
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
#define GPU_ATTACHMENT_TEXTURE(_texture)
#define GPU_framebuffer_bind_ex(_fb,...)
void GPU_framebuffer_multi_viewports_set(blender::gpu::FrameBuffer *gpu_fb, const int viewport_rects[GPU_MAX_VIEWPORTS][4])
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
blender::gpu::FrameBuffer * GPU_framebuffer_active_get()
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
int GPU_shader_get_ssbo_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_1i(blender::gpu::Shader *sh, const char *name, int value)
@ GPU_BARRIER_SHADER_STORAGE
@ GPU_BARRIER_TEXTURE_FETCH
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
void GPU_memory_barrier(GPUBarrier barrier)
void GPU_storagebuf_clear(blender::gpu::StorageBuf *ssbo, uint32_t clear_value)
void GPU_storagebuf_bind(blender::gpu::StorageBuf *ssbo, int slot)
@ 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_resources(U &resources)
void framebuffer_set(gpu::FrameBuffer **framebuffer)
void shader_set(gpu::Shader *shader)
void bind_texture(const char *name, gpu::Texture *texture, GPUSamplerState state=sampler_auto)
void bind_image(const char *name, gpu::Texture *image)
PassBase< DrawCommandBufType > & sub(const char *name)
void dispatch(int group_len)
void state_set(DRWState state, int clip_plane_count=0)
void barrier(GPUBarrier type)
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, gpu::StorageBuf *buffer)
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 sync_object(const Object *ob, const ObjectHandle &handle, const ResourceHandleRange &resource_handle, bool is_alpha_blend, bool has_transparent_shadows)
static float screen_pixel_radius(const float4x4 &wininv, bool is_perspective, const int2 &extent)
void set_view(View &view, int2 extent)
void debug_draw(View &view, gpu::FrameBuffer *view_fb)
static ShadowTechnique shadow_technique
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
ResourceHandleRange 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))