33 short blender_area_type,
34 bool use_soft_falloff)
36 switch (blender_light_type) {
69 this->color =
float3(&la->r) * la->energy;
80 this->object_to_world = object_to_world;
83 la, scale, object_to_world.
z_axis(), threshold, shadows.get_data().use_jitter);
85 const bool diffuse_visibility = (visibility_flag &
OB_HIDE_DIFFUSE) == 0;
86 const bool glossy_visibility = (visibility_flag &
OB_HIDE_GLOSSY) == 0;
90 float shape_power = shape_radiance_get();
91 float point_power = point_radiance_get();
97 this->lod_bias = shadows.global_lod_bias();
98 this->lod_min = shadow_lod_min_get(la);
99 this->filter_radius = la->shadow_filter_radius;
122float Light::shadow_lod_min_get(const ::Light *la)
125 float max_res_unit = la->shadow_maximum_resolution;
150 else if (this->
punctual ==
nullptr) {
155float Light::attenuation_radius_get(const ::Light *la,
float light_threshold,
float light_power)
163 return sqrtf(light_power / light_threshold);
166void Light::shape_parameters_set(const ::Light *la,
169 const float threshold,
170 const bool use_jitter)
177 const float surface_max_power =
max(la->diff_fac, la->spec_fac) * max_power;
178 const float volume_max_power = la->volume_fac * max_power;
180 float influence_radius_surface = attenuation_radius_get(la, threshold, surface_max_power);
181 float influence_radius_volume = attenuation_radius_get(la, threshold, volume_max_power);
183 this->local.influence_radius_max =
max(influence_radius_surface, influence_radius_volume);
184 this->local.influence_radius_invsqr_surface =
safe_rcp(
square(influence_radius_surface));
185 this->local.influence_radius_invsqr_volume =
safe_rcp(
square(influence_radius_volume));
187 this->clip_far =
float_as_int(this->local.influence_radius_max);
188 this->clip_near =
float_as_int(this->local.influence_radius_max / 4000.0f);
192 la->shadow_jitter_overblur / 100.0f :
196 float sun_half_angle =
min_ff(la->sun_angle,
DEG2RADF(179.9f)) / 2.0f;
198 this->sun.shadow_angle = sun_half_angle * trace_scaling_fac;
200 this->sun.shadow_angle = (sun_half_angle > 0.0f) ?
max_ff(1e-8f, sun.shadow_angle) : 0.0f;
202 this->sun.shape_radius =
clamp(
tanf(sun_half_angle), 0.001f, 20.0f);
204 this->sun.direction = z_axis;
208 this->area.size =
float2(la->area_size, is_irregular ? la->area_sizey : la->area_size);
210 this->area.size *= scale.
xy() / 2.0f;
211 this->area.shadow_scale = trace_scaling_fac;
212 this->local.shadow_radius =
length(this->area.size) * trace_scaling_fac;
214 this->local.shadow_position =
float3(0.0f);
216 if (this->area.size.x * this->area.size.y < 0.00001f) {
218 this->local.influence_radius_max = 0.0f;
221 this->area.size =
max(
float2(0.003f), this->area.size);
223 this->local.shape_radius =
max(0.001f,
length(this->area.size) / 2.0f);
228 const float spot_size =
cosf(la->spotsize * 0.5f);
229 const float spot_blend = (1.0f - spot_size) * la->spotblend;
230 this->spot.spot_size_inv = scale.z /
max(scale.xy(),
float2(1e-8f));
231 this->spot.spot_mul = 1.0f /
max(1e-8f, spot_blend);
232 this->spot.spot_bias = -spot_size * this->spot.spot_mul;
233 this->spot.spot_tan =
tanf(
min(la->spotsize * 0.5f,
float(
M_PI_2 - 0.0001f)));
238 this->spot.spot_size_inv =
float2(1.0f);
239 this->spot.spot_mul = 0.0f;
240 this->spot.spot_bias = 1.0f;
241 this->spot.spot_tan = 0.0f;
244 this->local.shadow_radius =
max(0.0f, la->radius) * trace_scaling_fac;
246 this->local.shadow_radius = (la->radius > 0.0f) ?
max_ff(1e-8f, local.shadow_radius) : 0.0f;
248 this->local.shadow_position =
float3(0.0f);
249 this->local.shape_radius = la->radius;
251 this->local.shape_radius =
max(0.001f, this->local.shape_radius);
255float Light::shape_radiance_get()
260 switch (this->type) {
264 float area = this->area.size.x * this->area.size.y * 4.0f;
283 float inv_sin_sq = 1.0f + 1.0f /
square(this->sun.shape_radius);
292float Light::point_radiance_get()
295 switch (this->type) {
300 float area = this->area.size.x * this->area.size.y * 4.0f;
303 float mrp_scaling = tmp + (1.0f - tmp) *
M_1_PI;
323void Light::debug_draw()
327 local.influence_radius_max,
328 float4(0.8f, 0.3f, 0.0f, 1.0f));
341 for (
Light &light : light_map_.values()) {
342 light.shadow_discard_safe(inst_.
shadows);
356 for (
Light &light : light_map_.values()) {
358 light.initialized =
false;
364 local_lights_len_ = 0;
369 ::Light la = blender::dna::shallow_copy(
373 la.
r = la.
g = la.
b = -1.0f;
382 Light &light = light_map_.lookup_or_add_default(world_sunlight_key);
386 sun_lights_len_ += 1;
392 const ::Light *la =
static_cast<const ::
Light *
>(ob->
data);
393 if (use_scene_lights_ ==
false) {
397 if (use_sun_lights_ ==
false) {
403 Light &light = light_map_.lookup_or_add_default(handle.object_key);
405 if (handle.recalc != 0 || !light.initialized) {
406 light.initialized =
true;
408 ob->object_to_world(),
422 light_buf_.
resize(lights_allocated);
426 int sun_lights_idx = 0;
427 int local_lights_idx = sun_lights_len_;
430 auto it_end = light_map_.items().end();
431 for (
auto it = light_map_.items().begin(); it != it_end; ++it) {
432 Light &light = (*it).value;
435 light_map_.remove(it);
439 int dst_idx =
is_sun_light(light.type) ? sun_lights_idx++ : local_lights_idx++;
441 light_buf_[dst_idx] = light;
455 lights_len_ = sun_lights_len_ + local_lights_len_;
459 culling_key_buf_.
resize(lights_allocated);
460 culling_zdist_buf_.
resize(lights_allocated);
461 culling_light_buf_.
resize(lights_allocated);
474 bool tile_size_valid =
false;
478 uint tile_count = tiles_extent.x * tiles_extent.y;
479 if (tile_count > max_tile_count_threshold) {
482 total_word_count_ = tile_count * word_per_tile;
483 tile_size_valid =
true;
485 }
while (total_word_count_ > max_word_count_threshold || !tile_size_valid);
491 culling_data_buf_.
tile_x_len = tiles_extent.x;
492 culling_data_buf_.
tile_y_len = tiles_extent.y;
497 culling_tile_buf_.
resize(total_word_count_);
504void LightModule::culling_pass_sync()
506 uint safe_lights_len =
max_ii(lights_len_, 1);
515 auto &sub = culling_ps_.
sub(
"Select");
518 sub.bind_ssbo(
"light_cull_buf", &culling_data_buf_);
519 sub.bind_ssbo(
"in_light_buf", light_buf_);
520 sub.bind_ssbo(
"out_light_buf", culling_light_buf_);
521 sub.bind_ssbo(
"out_zdist_buf", culling_zdist_buf_);
522 sub.bind_ssbo(
"out_key_buf", culling_key_buf_);
523 sub.dispatch(
int3(culling_select_dispatch_size, 1, 1));
527 auto &sub = culling_ps_.
sub(
"Sort");
529 sub.bind_ssbo(
"light_cull_buf", &culling_data_buf_);
530 sub.bind_ssbo(
"in_light_buf", light_buf_);
531 sub.bind_ssbo(
"out_light_buf", culling_light_buf_);
532 sub.bind_ssbo(
"in_zdist_buf", culling_zdist_buf_);
533 sub.bind_ssbo(
"in_key_buf", culling_key_buf_);
534 sub.dispatch(
int3(culling_sort_dispatch_size, 1, 1));
538 auto &sub = culling_ps_.
sub(
"Zbin");
540 sub.bind_ssbo(
"light_cull_buf", &culling_data_buf_);
541 sub.bind_ssbo(
"light_buf", culling_light_buf_);
542 sub.bind_ssbo(
"out_zbin_buf", culling_zbin_buf_);
543 sub.dispatch(
int3(1, 1, 1));
547 auto &sub = culling_ps_.
sub(
"Tiles");
549 sub.bind_ssbo(
"light_cull_buf", &culling_data_buf_);
550 sub.bind_ssbo(
"light_buf", culling_light_buf_);
551 sub.bind_ssbo(
"out_light_tile_buf", culling_tile_buf_);
552 sub.dispatch(
int3(culling_tile_dispatch_size, 1, 1));
557void LightModule::update_pass_sync()
561 uint safe_lights_len =
max_ii(lights_len_, 1);
564 auto &pass = update_ps_;
567 pass.bind_ssbo(
"light_buf", &culling_light_buf_);
568 pass.bind_ssbo(
"light_cull_buf", &culling_data_buf_);
572 pass.bind_resources(inst_.
sampling);
573 pass.dispatch(
int3(shadow_setup_dispatch_size, 1, 1));
577void LightModule::debug_pass_sync()
580 debug_draw_ps_.
init();
585 debug_draw_ps_.
bind_ssbo(
"light_buf", &culling_light_buf_);
586 debug_draw_ps_.
bind_ssbo(
"light_cull_buf", &culling_data_buf_);
587 debug_draw_ps_.
bind_ssbo(
"light_zbin_buf", &culling_zbin_buf_);
588 debug_draw_ps_.
bind_ssbo(
"light_tile_buf", &culling_tile_buf_);
596 float far_z = view.far_clip();
597 float near_z = view.near_clip();
613 inst_.
info_append(
"Debug Mode: Light Culling Validation");
#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 float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
MINLINE int float_as_int(float f)
MINLINE void negate_v3(float r[3])
#define SET_FLAG_FROM_TEST(value, test, flag)
const void * DNA_default_table[SDNA_TYPE_MAX]
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
@ GPU_BARRIER_SHADER_STORAGE
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
void submit(PassSimple &pass, View &view)
void resize(int64_t new_size)
void bind_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
void bind_resources(U &resources)
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 state_set(DRWState state, int clip_plane_count=0)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
int2 render_extent_get() const
struct blender::eevee::HiZBuffer::@195 front
bool use_scene_lights() const
SphereProbeModule sphere_probes
void info_append_i18n(const char *msg, Args &&...args)
RenderBuffers render_buffers
void info_append(const char *msg, Args &&...args)
UniformDataModule uniform_data
void sync_light(const Object *ob, ObjectHandle &handle)
void set_view(View &view, const int2 extent)
void debug_draw(View &view, GPUFrameBuffer *view_fb)
GPUShader * static_shader_get(eShaderType shader_type)
ShadowTileMapPool tilemap_pool
Pool< ShadowDirectional > directional_pool
Pool< ShadowPunctual > punctual_pool
int probe_render_extent() const
UniformBuffer< LightData > sunlight
bool use_sun_shadow_jitter()
float sun_shadow_filter_radius()
bool has_volume_absorption() const
float sun_shadow_jitter_overblur()
float sun_shadow_max_resolution()
Simple API to draw debug shapes and log in the viewport.
#define drw_debug_sphere(...)
#define CULLING_SELECT_GROUP_SIZE
#define CULLING_SORT_GROUP_SIZE
#define CULLING_TILE_GROUP_SIZE
#define SHADOW_MAP_MAX_RES
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
#define CULLING_ZBIN_COUNT
ccl_device_inline float2 power(float2 v, float e)
static bool is_area_light(eLightType type)
static uint2 uint64_to_uint2(uint64_t data)
static bool is_sun_light(eLightType type)
static bool is_spot_light(eLightType type)
static eLightType to_light_type(short blender_light_type, short blender_area_type, bool use_soft_falloff)
static bool is_local_light(eLightType type)
static bool is_point_light(eLightType type)
static float3 transform_location(Transform t)
T clamp(const T &a, const T &min, const T &max)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
T reduce_max(const VecBase< T, Size > &a)
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatBase< T, NumCol, NumRow > normalize_and_get_size(const MatBase< T, NumCol, NumRow > &a, VectorT &r_size)
T max(const T &a, const T &b)
bool assign_if_different(T &old_value, T new_value)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
unsigned __int64 uint64_t
uint64_t light_set_membership
uint64_t shadow_set_membership
LightLinkingRuntime runtime
float shadow_filter_radius
float shadow_jitter_overblur
float shadow_maximum_resolution
LightLinking * light_linking
const MatView< T, ViewNumCol, ViewNumRow, NumCol, NumRow, SrcStartCol, SrcStartRow, Alignment > view() const
static MatBase identity()
VecBase< T, 2 > xy() const
void shadow_discard_safe(ShadowModule &shadows)
ShadowDirectional * directional
void shadow_ensure(ShadowModule &shadows)
ShadowPunctual * punctual
ShadowTileMapDataBuf tilemaps_data
ShadowTileMapClipBuf tilemaps_clip