33 uint2 shadow_set_membership_)
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},
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();
232 shadows_.tilemap_pool.release(span.drop_front(tilemaps_needed));
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,
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);
315 const int max_tilemap_per_shadows = 16;
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);
343 return IndexRange(lod_level, tilemap_len);
346void ShadowDirectional::cascade_tilemaps_distribution(
Light &light,
const Camera &
camera)
348 using namespace blender::math;
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)) /
375 max_ii(levels_range.size() - 1, 1);
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(
389 shadows_.tilemap_pool.tilemaps_data.append(*tilemap);
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();
407IndexRange ShadowDirectional::clipmap_level_range(
const Camera &cam)
409 using namespace blender::math;
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;
417 IndexRange range(min_level, max_level - min_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;
443 tilemap->sync_orthographic(
447 shadows_.tilemap_pool.tilemaps_data.append(*tilemap);
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) {
500 IndexRange before_range(levels_range.start(), isect_range.
start() - levels_range.start());
504 auto span = tilemaps_.as_span();
505 shadows_.tilemap_pool.release(span.slice(before_range.
shift(-levels_range.start())));
506 shadows_.tilemap_pool.release(span.slice(after_range.
shift(-levels_range.start())));
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 &&
590 (inst_.is_image_render() ||
591 (!inst_.is_navigating() && !inst_.is_transforming() && !inst_.is_playback() &&
597 for (
Light &light : inst_.lights.light_map_.values()) {
598 light.initialized =
false;
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;
624 if (!atlas_tx_.is_valid()) {
625 atlas_tx_.ensure_2d_array(ShadowModule::atlas_type,
int2(1), 1);
626 inst_.info_append_i18n(
627 "Error: Could not allocate shadow atlas. Most likely out of GPU memory.");
631 if (inst_.is_viewport()) {
632 if (inst_.sampling.finished_viewport()) {
634 for (
int i = 0; i < statistics_buf_.size(); i++) {
635 statistics_buf_.swap();
639 statistics_buf_.swap();
641 statistics_buf_.current().read();
645 inst_.info_append_i18n(
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.");
656 atlas_tx_.filter_mode(
false);
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;
680 Manager &manager = *inst_.manager;
685 if (inst_.is_baking()) {
686 SurfelBuf &surfels_buf = inst_.volume_probes.bake.surfels_buf_;
688 float surfel_coverage_area = inst_.volume_probes.bake.surfel_density_;
692 int directional_level = std::max(0,
int(std::ceil(log2(surfel_coverage_area / texel_size))));
698 sub.
bind_ssbo(
"surfel_buf", &surfels_buf);
703 sub.
dispatch(&inst_.volume_probes.bake.dispatch_per_surfel_);
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) {
758 shadow_ob.
used =
true;
760 const bool has_jittered_transparency = has_transparent_shadows && data_.use_jitter;
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) {
823 if (!shadow_ob.
used && !inst_.is_baking()) {
830 shadow_ob.
used =
false;
833 past_casters_updated_.push_update();
834 curr_casters_updated_.push_update();
835 jittered_transparent_casters_.push_update();
837 curr_casters_.push_update();
839 if (do_full_update_) {
840 do_full_update_ =
false;
849 pages_free_data_[i] = 0xFFFFFFFFu;
851 pages_free_data_.push_update();
861 pages_infos_data_.page_free_count = shadow_page_len_;
862 pages_infos_data_.page_alloc_count = 0;
863 pages_infos_data_.page_cached_next = 0u;
864 pages_infos_data_.page_cached_start = 0u;
865 pages_infos_data_.page_cached_end = 0u;
866 pages_infos_data_.push_update();
870 Manager &manager = *inst_.manager;
893 sub.
bind_ssbo(
"casters_id_buf", curr_casters_);
895 sub.
push_constant(
"resource_len",
int(curr_casters_.size()));
910 sub.
bind_ssbo(
"pages_cached_buf", pages_cached_data_);
929 if (past_casters_updated_.size() > 0) {
931 pass.
bind_ssbo(
"resource_ids_buf", past_casters_updated_);
935 if (curr_casters_updated_.size() > 0) {
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) {
952 pass.
bind_ssbo(
"resource_ids_buf", jittered_transparent_casters_);
954 int3(jittered_transparent_casters_.size(), 1,
tilemap_pool.tilemaps_data.size()));
962 if (inst_.volume.needs_shadow_tagging() && !inst_.is_baking()) {
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());
1041 sub.
bind_ssbo(
"view_infos_buf", &shadow_multi_view_.matrices_ubo_get());
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_);
1097 if (!
ELEM(inst_.debug_mode,
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);
1129 debug_draw_ps_.state_set(
state);
1130 debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(
SHADOW_DEBUG));
1131 debug_draw_ps_.push_constant(
"debug_mode",
int(inst_.debug_mode));
1132 debug_draw_ps_.push_constant(
"debug_tilemap_index", light.tilemap_index);
1133 debug_draw_ps_.bind_ssbo(
"tilemaps_buf", &
tilemap_pool.tilemaps_data);
1134 debug_draw_ps_.bind_ssbo(
"tiles_buf", &
tilemap_pool.tiles_data);
1135 debug_draw_ps_.bind_resources(inst_.uniform_data);
1136 debug_draw_ps_.bind_resources(inst_.hiz_buffer.front);
1137 debug_draw_ps_.bind_resources(inst_.lights);
1138 debug_draw_ps_.bind_resources(inst_.shadows);
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_) {
1187 inst_.info_append_i18n(
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()
1200 if (inst_.is_image_render()) {
1207 int potential_view_count = 0;
1208 for (
auto i : IndexRange(
tilemap_pool.tilemaps_data.size())) {
1213 potential_view_count += 1;
1218 if (inst_.is_transforming() || inst_.is_navigating()) {
1219 max_view_count =
math::min(2, max_view_count);
1222 if (inst_.is_playback()) {
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();
1282 inst_.uniform_data.push_update();
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);
1300 shadow_depth_accum_tx_.ensure_2d_array(
GPU_R32F, fb_size, fb_layers, usage);
1308 inst_.hiz_buffer.update();
1316 inst_.manager->submit(tilemap_setup_ps_,
view);
1321 inst_.manager->submit(caster_update_ps_,
view);
1323 if (loop_count == 0) {
1324 inst_.manager->submit(jittered_transparent_caster_update_ps_,
view);
1326 inst_.manager->submit(tilemap_usage_ps_,
view);
1327 inst_.manager->submit(tilemap_update_ps_,
view);
1329 shadow_multi_view_.compute_procedural_bounds();
1331 statistics_buf_.current().async_flush_to_host();
1338 use_flush |= loop_count != 0;
1345 if (shadow_depth_fb_tx_.is_valid() && shadow_depth_accum_tx_.is_valid()) {
1356 else if (shadow_depth_fb_tx_.is_valid()) {
1369 reinterpret_cast<int(*)[4]
>(multi_viewports_.data()));
1371 inst_.pipelines.shadow.render(shadow_multi_view_);
1383 }
while (!shadow_update_finished(loop_count));
1392 if (!
ELEM(inst_.debug_mode,
1401 switch (inst_.debug_mode) {
1403 inst_.info_append(
"Debug Mode: Shadow Tilemap");
1406 inst_.info_append(
"Debug Mode: Shadow Values");
1409 inst_.info_append(
"Debug Mode: Shadow Tile Random Color");
1412 inst_.info_append(
"Debug Mode: Shadow Tilemap Random Color");
1418 inst_.hiz_buffer.update();
1421 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])
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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
struct GPUShader GPUShader
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
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
A running instance of the engine.
void info_append_i18n(const char *msg, Args &&...args)
bool is_image_render() const
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)
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
detail::Pass< command::DrawCommandBuf > PassSimple
detail::Pass< command::DrawMultiBuf > PassMain
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))