33 uint2 shadow_set_membership_)
35 if ((
projection_type != projection_type_) || (level != clipmap_level) ||
41 level = clipmap_level;
76 uint2 shadow_set_membership_)
122 const float4 debug_color[6] = {
123 {1.0f, 0.1f, 0.1f, 1.0f},
124 {0.1f, 1.0f, 0.1f, 1.0f},
125 {0.0f, 0.2f, 1.0f, 1.0f},
126 {1.0f, 1.0f, 0.3f, 1.0f},
127 {0.1f, 0.1f, 0.1f, 1.0f},
128 {1.0f, 1.0f, 1.0f, 1.0f},
130 float4 color = debug_color
192 module.do_full_update_ = true;
197 if (newly_unused_count > 0) {
201 for (
uint index : newly_unused_indices) {
228 if (tilemaps_.size() <= tilemaps_needed) {
231 auto span = tilemaps_.as_span();
233 tilemaps_ = span.take_front(tilemaps_needed);
240 float4x4 object_to_world = light.object_to_world;
244 while (tilemaps_.size() < tilemaps_needed) {
245 tilemaps_.append(tilemap_pool.
acquire());
250 for (
int i : tilemaps_.index_range()) {
252 tilemaps_[face]->sync_cubeface(
253 light.type, object_to_world, near, far, face, light.shadow_set_membership);
256 light.local.tilemaps_count = tilemaps_needed;
261 tilemap->set_updated();
294void ShadowDirectional::cascade_tilemaps_distribution_near_far_points(
const Camera &camera,
299 const CameraData &cam_data = camera.data_get();
302 light.object_to_world, camera.position() - camera.forward() * cam_data.clip_far);
304 light.object_to_world, camera.position() - camera.forward() * cam_data.clip_near);
307IndexRange ShadowDirectional::cascade_level_range(
const Light &light,
const Camera &camera)
315 const int max_tilemap_per_shadows = 16;
316 const CameraData &cam_data = camera.data_get();
318 float3 near_point, far_point;
319 cascade_tilemaps_distribution_near_far_points(camera, light, near_point, far_point);
323 float depth_range_in_shadow_space =
distance(far_point.xy(), near_point.xy());
324 float min_depth_tilemap_size = 2 * (depth_range_in_shadow_space / max_tilemap_per_shadows);
327 float min_diagonal_tilemap_size = cam_data.screen_diagonal_length;
329 if (camera.is_perspective()) {
331 min_diagonal_tilemap_size *= cam_data.clip_far / cam_data.clip_near;
336 int lod_level =
ceil(log2(
max_ff(min_depth_tilemap_size, min_diagonal_tilemap_size)) + 0.5);
342 int tilemap_len =
ceil(0.5f + depth_range_in_shadow_space / per_tilemap_coverage);
346void ShadowDirectional::cascade_tilemaps_distribution(
Light &light,
const Camera &camera)
350 float4x4 object_mat = light.object_to_world;
357 float3 near_point, far_point;
358 cascade_tilemaps_distribution_near_far_points(camera, light, near_point, far_point);
360 float2 local_view_direction =
normalize(far_point.xy() - near_point.xy());
361 float2 farthest_tilemap_center = local_view_direction * half_size * (levels_range.
size() - 1);
364 light.object_to_world.
x.w = near_point.
x;
365 light.object_to_world.y.w = near_point.
y;
366 light.object_to_world.z.w = near_point.
z;
371 int2 offset_vector =
int2(
round(farthest_tilemap_center / tile_size));
373 light.sun.clipmap_base_offset_neg =
int2(0);
374 light.sun.clipmap_base_offset_pos = (offset_vector * (1 << 16)) /
378 int level = levels_range.
first();
379 for (
int i :
IndexRange(levels_range.size())) {
380 ShadowTileMap *tilemap = tilemaps_[i];
383 int2 level_offset = origin_offset +
385 tilemap->sync_orthographic(
390 tilemap->set_updated();
393 light.sun.clipmap_origin =
float2(origin_offset) * tile_size;
399 light.sun.clipmap_lod_min = levels_range.
first();
400 light.sun.clipmap_lod_max = levels_range.
last();
412 int min_level =
max(0.0f,
floor(log2(
abs(cam.data_get().clip_near))));
414 int max_level =
ceil(log2(cam.bound_radius() + distance(cam.bound_center(), cam.position())));
416 max_level =
max(min_level, max_level) + 1;
420 const int max_tilemap_per_shadows = 24;
422 range = range.take_back(max_tilemap_per_shadows);
427void ShadowDirectional::clipmap_tilemaps_distribution(
Light &light,
const Camera &camera)
429 float4x4 object_mat = light.object_to_world;
432 for (
int lod :
IndexRange(levels_range.size())) {
433 ShadowTileMap *tilemap = tilemaps_[lod];
435 int level = levels_range.
first() + lod;
440 float2 light_space_camera_position = camera.position() *
float2x3(object_mat.
view<2, 3>());
443 tilemap->sync_orthographic(
448 tilemap->set_updated();
453 for (
int lod :
IndexRange(levels_range.size() - 1)) {
459 int2 lvl_offset_next = tilemaps_[lod + 1]->grid_offset;
460 int2 lvl_offset = tilemaps_[lod]->grid_offset;
461 int2 lvl_delta = lvl_offset - (lvl_offset_next * 2);
468 light.sun.clipmap_base_offset_pos = pos_offset;
469 light.sun.clipmap_base_offset_neg = neg_offset;
472 int2 level_offset_max = tilemaps_[levels_range.
size() - 1]->grid_offset;
479 light.object_to_world.x.w = location.x;
480 light.object_to_world.y.w = location.y;
481 light.object_to_world.z.w = location.z;
483 light.sun.clipmap_origin =
float2(level_offset_max * tile_size_max);
485 light.sun.clipmap_lod_min = levels_range.
first();
486 light.sun.clipmap_lod_max = levels_range.
last();
492 cascade_level_range(light, camera) :
493 clipmap_level_range(camera);
495 if (levels_range == levels_new) {
504 auto span = tilemaps_.as_span();
507 tilemaps_ = span.slice(isect_range.
shift(-levels_range.
start()));
508 levels_range = isect_range;
515 cascade_level_range(light, camera) :
516 clipmap_level_range(camera);
518 if (levels_range != levels_new) {
526 for (
int64_t i = 0; i < before_range; i++) {
527 tilemaps_.append(tilemap_pool.
acquire());
530 tilemaps_.extend(cached_tilemaps);
531 for (
int64_t i = 0; i < after_range; i++) {
532 tilemaps_.append(tilemap_pool.
acquire());
534 levels_range = levels_new;
538 light.clip_near = 0x7F7FFFFF;
539 light.clip_far =
int(0xFF7FFFFFu ^ 0x7FFFFFFFu);
542 cascade_tilemaps_distribution(light, camera);
545 clipmap_tilemaps_distribution(light, camera);
558 for (
int i = 0; i < statistics_buf_.size(); i++) {
560 statistics_buf_.current().clear_to_zero();
561 statistics_buf_.swap();
574 if (is_metal_backend && is_tile_based_arch) {
587 bool update_lights =
false;
589 bool use_jitter = enable_shadow &&
597 for (
Light &light : inst_.
lights.light_map_.values()) {
598 light.initialized =
false;
606 const size_t pool_byte_size = enabled_ ? scene.eevee.shadow_pool_size *
square_i(1024) : 1;
607 const size_t page_byte_size =
square_i(shadow_page_size_) *
sizeof(
int);
618 if (atlas_tx_.
ensure_2d_array(atlas_type, atlas_extent, atlas_layers, tex_usage)) {
620 do_full_update_ =
true;
627 "Error: Could not allocate shadow atlas. Most likely out of GPU memory.");
634 for (
int i = 0; i < statistics_buf_.size(); i++) {
635 statistics_buf_.swap();
639 statistics_buf_.swap();
641 statistics_buf_.current().read();
646 "Error: Shadow buffer full, may result in missing shadows and lower "
647 "performance. ({} / {})",
652 inst_.
info_append_i18n(
"Error: Too many shadow updates, some shadows might be incorrect.");
660 for (
int i = 0; i < multi_viewports_.size(); i++) {
664 multi_viewports_[i][0] = 0;
665 multi_viewports_[i][1] = 0;
666 multi_viewports_[i][2] = size_in_tile * shadow_page_size_;
667 multi_viewports_[i][3] = size_in_tile * shadow_page_size_;
673 past_casters_updated_.
clear();
674 curr_casters_updated_.
clear();
675 curr_casters_.
clear();
676 jittered_transparent_casters_.
clear();
677 update_casters_ =
true;
692 int directional_level = std::max(0,
int(std::ceil(log2(surfel_coverage_area / texel_size))));
698 sub.
bind_ssbo(
"surfel_buf", &surfels_buf);
716 sub.
push_constant(
"input_depth_extent", &input_depth_extent_);
720 sub.
dispatch(&dispatch_depth_scan_size_);
734 sub.
push_constant(
"fb_resolution", &usage_tag_fb_resolution_);
741 tilemap_usage_transparent_ps_ = ⊂
750 bool has_transparent_shadows)
753 if (!is_shadow_caster && !is_alpha_blend) {
757 ShadowObject &shadow_ob = objects_.lookup_or_add_default(handle.object_key);
758 shadow_ob.
used =
true;
760 const bool has_jittered_transparency = has_transparent_shadows && data_.
use_jitter;
761 if (is_shadow_caster && (handle.recalc || !
is_initialized || has_jittered_transparency)) {
766 if (has_jittered_transparency) {
767 jittered_transparent_casters_.
append(resource_handle.
raw);
770 curr_casters_updated_.
append(resource_handle.
raw);
775 if (is_shadow_caster) {
776 curr_casters_.
append(resource_handle.
raw);
779 if (is_alpha_blend && !inst_.
is_baking()) {
780 tilemap_usage_transparent_ps_->
draw(box_batch_, resource_handle);
787 for (
Light &light : inst_.
lights.light_map_.values()) {
789 if ((!light.used || !enabled_) && !inst_.
is_baking()) {
790 light.shadow_discard_safe(*
this);
792 else if (light.directional !=
nullptr) {
793 light.directional->release_excess_tilemaps(light, inst_.
camera);
795 else if (light.punctual !=
nullptr) {
796 light.punctual->release_excess_tilemaps(light);
802 for (
Light &light : inst_.
lights.light_map_.values()) {
803 if (enabled_ ==
false) {
806 else if (light.directional !=
nullptr) {
807 light.directional->end_sync(light, inst_.
camera);
809 else if (light.punctual !=
nullptr) {
810 light.punctual->end_sync(light);
819 auto it_end = objects_.items().end();
820 for (
auto it = objects_.items().begin(); it != it_end; ++it) {
830 shadow_ob.
used =
false;
839 if (do_full_update_) {
840 do_full_update_ =
false;
849 pages_free_data_[i] = 0xFFFFFFFFu;
893 sub.
bind_ssbo(
"casters_id_buf", curr_casters_);
910 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
929 if (past_casters_updated_.
size() > 0) {
930 pass.bind_ssbo(
"bounds_buf", &manager.
bounds_buf.previous());
931 pass.bind_ssbo(
"resource_ids_buf", past_casters_updated_);
935 if (curr_casters_updated_.
size() > 0) {
936 pass.bind_ssbo(
"bounds_buf", &manager.
bounds_buf.current());
937 pass.bind_ssbo(
"resource_ids_buf", curr_casters_updated_);
945 PassSimple &pass = jittered_transparent_caster_update_ps_;
947 if (jittered_transparent_casters_.
size() > 0) {
951 pass.bind_ssbo(
"bounds_buf", &manager.
bounds_buf.current());
952 pass.bind_ssbo(
"resource_ids_buf", jittered_transparent_casters_);
984 sub.
push_constant(
"max_view_per_tilemap", &max_view_per_tilemap_);
996 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
997 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
998 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1011 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1012 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1013 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1014 sub.
bind_ssbo(
"statistics_buf", statistics_buf_.current());
1015 sub.
bind_ssbo(
"clear_dispatch_buf", clear_dispatch_buf_);
1016 sub.
bind_ssbo(
"tile_draw_buf", tile_draw_buf_);
1026 sub.
bind_ssbo(
"statistics_buf", statistics_buf_.current());
1027 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1028 sub.
bind_ssbo(
"pages_free_buf", pages_free_data_);
1029 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
1039 sub.
bind_ssbo(
"pages_infos_buf", &pages_infos_data_);
1040 sub.
bind_ssbo(
"statistics_buf", &statistics_buf_.current());
1042 sub.
bind_ssbo(
"render_view_buf", &render_view_buf_);
1053 sub.
bind_ssbo(
"statistics_buf", &statistics_buf_.current());
1054 sub.
bind_ssbo(
"render_view_buf", &render_view_buf_);
1056 sub.
bind_ssbo(
"clear_dispatch_buf", &clear_dispatch_buf_);
1057 sub.
bind_ssbo(
"tile_draw_buf", &tile_draw_buf_);
1058 sub.
bind_ssbo(
"dst_coord_buf", &dst_coord_buf_);
1059 sub.
bind_ssbo(
"src_coord_buf", &src_coord_buf_);
1060 sub.
bind_ssbo(
"render_map_buf", &render_map_buf_);
1083 sub.
bind_ssbo(
"pages_infos_buf", pages_infos_data_);
1084 sub.
bind_ssbo(
"dst_coord_buf", dst_coord_buf_);
1085 sub.
bind_image(
"shadow_atlas_img", atlas_tx_);
1107 debug_draw_ps_.
init();
1110 if (object_active ==
nullptr) {
1116 if (inst_.
lights.light_map_.contains(object_key) ==
false) {
1120 Light &light = inst_.
lights.light_map_.lookup(object_key);
1132 debug_draw_ps_.
push_constant(
"debug_tilemap_index", light.tilemap_index);
1143 bool is_perspective,
1146 float min_dim =
float(
min_ii(extent.x, extent.y));
1152 if (is_perspective) {
1159bool ShadowModule::shadow_update_finished(
int loop_count)
1182 statistics_buf_.current().async_flush_to_host();
1183 statistics_buf_.current().read();
1186 if (stats.page_used_count > shadow_page_len_) {
1188 "Error: Shadow buffer full, may result in missing shadows and lower "
1189 "performance. ({} / {})",
1190 stats.page_used_count,
1198int ShadowModule::max_view_per_tilemap()
1207 int potential_view_count = 0;
1213 potential_view_count += 1;
1219 max_view_count =
math::min(2, max_view_count);
1223 max_view_count =
math::min(1, max_view_count);
1226 return max_view_count;
1229void ShadowModule::ShadowView::compute_visibility(
ObjectBoundsBuf &bounds,
1239 resource_len * word_per_draw;
1268 if (enabled_ ==
false) {
1273 input_depth_extent_ = extent;
1279 max_view_per_tilemap_ = max_view_per_tilemap();
1285 usage_tag_fb.
ensure(usage_tag_fb_resolution_);
1293 shadow_depth_fb_tx_.
free();
1294 shadow_depth_accum_tx_.
free();
1295 render_fb_.
ensure(fb_size);
1323 if (loop_count == 0) {
1324 inst_.
manager->
submit(jittered_transparent_caster_update_ps_, view);
1331 statistics_buf_.current().async_flush_to_host();
1338 use_flush |= loop_count != 0;
1356 else if (shadow_depth_fb_tx_.
is_valid()) {
1369 reinterpret_cast<int(*)[4]
>(multi_viewports_.data()));
1383 }
while (!shadow_update_finished(loop_count));
1409 inst_.
info_append(
"Debug Mode: Shadow Tile Random Color");
1412 inst_.
info_append(
"Debug Mode: Shadow Tilemap Random Color");
#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])
Object * DEG_get_original_object(Object *object)
@ SCE_EEVEE_SHADOW_ENABLED
@ SCE_EEVEE_SHADOW_JITTERED_VIEWPORT
@ GPU_STOREACTION_DONT_CARE
void GPU_compute_dispatch(GPUShader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len)
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 *framebuffer)
#define GPU_framebuffer_bind_ex(_fb,...)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
void GPU_shader_bind(GPUShader *shader)
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
struct GPUShader GPUShader
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
constexpr int64_t first() const
constexpr int64_t one_after_last() const
constexpr IndexRange shift(int64_t n) const
constexpr IndexRange intersect(IndexRange other) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr int64_t start() const
void append(const T &value)
void reserve(const int64_t min_capacity)
Span< T > as_span() const
void ensure(GPUAttachment depth=GPU_ATTACHMENT_NONE, GPUAttachment color1=GPU_ATTACHMENT_NONE, GPUAttachment color2=GPU_ATTACHMENT_NONE, GPUAttachment color3=GPU_ATTACHMENT_NONE, GPUAttachment color4=GPU_ATTACHMENT_NONE, GPUAttachment color5=GPU_ATTACHMENT_NONE, GPUAttachment color6=GPU_ATTACHMENT_NONE, GPUAttachment color7=GPU_ATTACHMENT_NONE, GPUAttachment color8=GPU_ATTACHMENT_NONE)
SwapChain< ObjectBoundsBuf, 2 > bounds_buf
void submit(PassSimple &pass, View &view)
void resize(int64_t new_size)
void append(const T &value)
void clear(float4 values)
void filter_mode(bool do_filter)
bool ensure_2d_array(eGPUTextureFormat format, int2 extent, int layers, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
bool ensure_2d(eGPUTextureFormat format, int2 extent, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
UniformArrayBuffer< ViewCullingData, DRW_VIEW_MAX > culling_
VisibilityBuf visibility_buf_
void compute_procedural_bounds()
UniformArrayBuffer< ViewMatrices, DRW_VIEW_MAX > data_
UniformArrayBuffer< ViewMatrices, DRW_VIEW_MAX > & matrices_ubo_get()
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)
void draw(gpu::Batch *batch, uint instance_len=-1, uint vertex_len=-1, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
void draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
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)
struct blender::eevee::HiZBuffer::@195 front
A running instance of the engine.
VolumeProbeModule volume_probes
void info_append_i18n(const char *msg, Args &&...args)
bool is_transforming() const
bool is_image_render() const
void info_append(const char *msg, Args &&...args)
bool is_navigating() const
UniformDataModule uniform_data
bool finished_viewport() const
GPUShader * static_shader_get(eShaderType shader_type)
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)
struct blender::eevee::VolumeModule::@197 properties
bool needs_shadow_tagging() const
struct blender::eevee::VolumeModule::@196 result
blender::gpu::Batch * DRW_cache_cube_get()
Simple API to draw debug shapes and log in the viewport.
#define drw_debug_matrix_as_bbox(...)
#define DRW_VISIBILITY_GROUP_SIZE
#define DRW_VIEW_CULLING_UBO_SLOT
#define DRW_OBJ_INFOS_SLOT
#define DRW_VIEW_UBO_SLOT
const DRWContextState * DRW_context_state_get()
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end()
@ DRW_STATE_DEPTH_LESS_EQUAL
@ 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
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
tiles_buf[] pages_free_buf[] clear_dispatch_buf ShadowStatistics
SHADOW_TILEMAP_RES tiles_buf[] statistics_buf render_view_buf[SHADOW_VIEW_MAX] GPU_R32UI
smooth(Type::VEC3, "prev") .smooth(Type CameraData
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)
@ 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, 4 > uint4
MatBase< float, 2, 3 > float2x3
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
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))