29 world_sphere_.clipping_distances =
float2(1.0f, 10.0f);
34 world_sphere_.influence_scale = 0.0f;
35 world_sphere_.influence_bias = 1.0f;
36 world_sphere_.parallax_distance = 1e10f;
38 world_sphere_.use_for_render =
true;
63 const SceneEEVEE &sce_eevee = inst_.scene->eevee;
69 auto_bake_enabled_ = inst_.is_viewport() &&
90 grid.
view_bias = lightprobe.grid_view_bias;
103 1.0f /
float3(cache_size + 1));
114 SphereProbe &
cube = sphere_map_.lookup_or_add_default(handle.object_key);
116 if (handle.recalc != 0 ||
cube.initialized ==
false) {
119 cube.initialized =
true;
121 cube.do_render =
true;
125 int subdivision_lvl = probe_module.subdivision_level_get(probe_resolution);
127 if (
cube.atlas_coord.subdivision_lvl != subdivision_lvl) {
128 cube.atlas_coord.free();
129 cube.atlas_coord = find_empty_atlas_region(subdivision_lvl);
130 SphereProbeData &cube_data = *
static_cast<SphereProbeData *
>(&
cube);
132 cube_data.atlas_coord =
cube.atlas_coord.as_sampling_coord();
134 cube.use_for_render =
false;
138 float influence_distance = light_probe.distinf;
139 float influence_falloff = light_probe.falloff;
140 float parallax_distance = light_probe.distpar;
141 parallax_distance = use_custom_parallax ?
max_ff(parallax_distance, influence_distance) :
144 auto to_eevee_shape = [](
int bl_shape_type) {
147 cube.influence_shape = to_eevee_shape(light_probe.attenuation_type);
148 cube.parallax_shape = to_eevee_shape(use_custom_parallax ? light_probe.parallax_type :
149 light_probe.attenuation_type);
155 cube.influence_scale = 1.0 /
max_ff(1e-8f, influence_falloff);
156 cube.influence_bias =
cube.influence_scale;
157 cube.parallax_distance = parallax_distance / influence_distance;
158 cube.clipping_distances =
float2(light_probe.clipsta, light_probe.clipend);
168 PlanarProbe &plane = planar_map_.lookup_or_add_default(handle.object_key);
170 if (handle.recalc != 0 || plane.initialized ==
false) {
173 plane.initialized =
true;
174 plane.updated =
true;
175 plane.plane_to_world = ob->object_to_world();
176 plane.plane_to_world.z_axis() =
math::normalize(plane.plane_to_world.z_axis()) *
178 plane.world_to_plane =
math::invert(plane.plane_to_world);
179 plane.clipping_offset = light_probe.clipsta;
187 switch (lightprobe.type) {
189 sync_sphere(ob, handle);
192 sync_planar(ob, handle);
195 sync_volume(ob, handle);
204 world->probe_resolution);
207 int subdivision_lvl = sph_module.subdivision_level_get(probe_resolution);
209 if (subdivision_lvl != world_sphere_.atlas_coord.subdivision_lvl) {
210 world_sphere_.atlas_coord.free();
211 world_sphere_.atlas_coord = find_empty_atlas_region(subdivision_lvl);
213 world_data.
atlas_coord = world_sphere_.atlas_coord.as_sampling_coord();
218 world_sphere_.do_render =
true;
225 volume_update_ =
false;
228 bool remove_grid = !grid.
used;
229 if (grid.
updated || remove_grid) {
230 volume_update_ =
true;
238 sphere_update_ =
false;
241 bool remove_cube = !
cube.used;
242 if (
cube.updated || remove_cube) {
243 sphere_update_ =
true;
245 cube.updated =
false;
251 planar_update_ =
false;
254 bool remove_plane = !plane.
used;
255 if (plane.
updated || remove_plane) {
256 planar_update_ =
true;
266 int layer_count = sphere_layer_count();
269 location_finder.mark_space_used(world_sphere_.
atlas_coord);
270 for (
const SphereProbe &probe : sphere_map_.values()) {
271 location_finder.mark_space_used(probe.atlas_coord);
273 return location_finder.first_free_spot();
276int LightProbeModule::sphere_layer_count()
const
279 for (
const SphereProbe &probe : sphere_map_.values()) {
280 max_layer =
max_ii(max_layer, probe.atlas_coord.atlas_layer);
282 int layer_count = max_layer + 1;
293 int subdivision_level)
295 subdivision_level_ = subdivision_level;
296 areas_per_dimension_ = 1 << subdivision_level_;
297 areas_per_layer_ =
square_i(areas_per_dimension_);
300 int area_len = (allocated_layer_count + 1) * areas_per_layer_;
301 areas_occupancy_.resize(area_len,
false);
314 const int2 pos_in_location_finder = (coord.
area_location() >> shift_right) << shift_left;
316 const int layer_offset = coord.
atlas_layer * areas_per_layer_;
317 const int areas_overlapped_per_dim = 1 << shift_left;
318 for (
const int y :
IndexRange(areas_overlapped_per_dim)) {
319 for (
const int x :
IndexRange(areas_overlapped_per_dim)) {
322 areas_occupancy_[
area_index + layer_offset].set();
330 result.subdivision_lvl = subdivision_level_;
331 for (
int index : areas_occupancy_.index_range()) {
332 if (!areas_occupancy_[index]) {
333 result.atlas_layer = index / areas_per_layer_;
334 result.area_index = index % areas_per_layer_;
345 std::ostream &os = std::cout;
346 int layer = 0, row = 0, column = 0;
347 os <<
"subdivision " << subdivision_level_ <<
"\n";
348 for (
bool spot_taken : areas_occupancy_) {
349 if (row == 0 && column == 0) {
350 os <<
"layer " << layer <<
"\n";
352 os << (spot_taken ?
'X' :
'-');
354 if (column == areas_per_dimension_) {
359 if (row == areas_per_dimension_) {
#define BLI_assert_unreachable()
MINLINE float max_ff(float a, float b)
MINLINE int square_i(int a)
MINLINE int max_ii(int a, int b)
@ LIGHTPROBE_FLAG_SHOW_DATA
@ LIGHTPROBE_FLAG_CUSTOM_PARALLAX
@ LIGHT_PROBE_RESOLUTION_128
@ LIGHT_PROBE_RESOLUTION_512
@ LIGHT_PROBE_RESOLUTION_4096
@ LIGHT_PROBE_RESOLUTION_256
@ LIGHT_PROBE_RESOLUTION_2048
@ LIGHT_PROBE_RESOLUTION_1024
T & DRW_object_get_data_for_drawing(const Object &object)
MutableMapItem< Key, Value > MutableItem
A running instance of the engine.
VolumeProbeModule volume_probes
void sync_world(const ::World *world, bool has_update)
friend class SphereProbeModule
void sync_probe(const Object *ob, ObjectHandle &handle)
LightProbeModule(Instance &inst)
void mark_space_used(const SphereProbeAtlasCoord &coord)
LocationFinder(int allocated_layer_count, int subdivision_level)
SphereProbeAtlasCoord first_free_spot() const
void bricks_free(Vector< IrradianceBrickPacked > &bricks)
static eLightProbeResolution resolution_to_probe_resolution_enum(int resolution)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
T reduce_min(const VecBase< T, Size > &a)
CartesianBasis invert(const CartesianBasis &basis)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
T reduce_add(const VecBase< T, Size > &a)
T determinant(const MatBase< T, Size, Size > &mat)
MatBase< float, 4, 4 > float4x4
MatBase< float, 3, 4 > float3x4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
struct LightProbeGridCacheFrame * grid_static_cache
struct LightProbeObjectCache * lightprobe_cache
int gi_cubemap_resolution
static MatBase identity()
float viewport_display_size
int2 area_location() const
SphereProbeUvArea atlas_coord
SphereProbeAtlasCoord atlas_coord
Vector< IrradianceBrickPacked > bricks
const LightProbeObjectCache * cache