32 world_sphere_.clipping_distances =
float2(1.0f, 10.0f);
37 world_sphere_.influence_scale = 0.0f;
38 world_sphere_.influence_bias = 1.0f;
39 world_sphere_.parallax_distance = 1e10f;
41 world_sphere_.use_for_render =
true;
66 const SceneEEVEE &sce_eevee = inst_.scene->eevee;
72 auto_bake_enabled_ = inst_.is_viewport() &&
81 const ::LightProbe *lightprobe =
static_cast<const ::
LightProbe *
>(ob->
data);
93 grid.
view_bias = lightprobe->grid_view_bias;
106 1.0f /
float3(cache_size + 1));
117 SphereProbe &cube = sphere_map_.lookup_or_add_default(handle.object_key);
119 if (handle.recalc != 0 || cube.initialized ==
false) {
122 cube.initialized =
true;
124 cube.do_render =
true;
128 int subdivision_lvl = probe_module.subdivision_level_get(probe_resolution);
130 if (cube.atlas_coord.subdivision_lvl != subdivision_lvl) {
131 cube.atlas_coord.free();
132 cube.atlas_coord = find_empty_atlas_region(subdivision_lvl);
135 cube_data.atlas_coord = cube.atlas_coord.as_sampling_coord();
137 cube.use_for_render =
false;
141 float influence_distance = light_probe.distinf;
142 float influence_falloff = light_probe.falloff;
143 float parallax_distance = light_probe.distpar;
144 parallax_distance = use_custom_parallax ?
max_ff(parallax_distance, influence_distance) :
147 auto to_eevee_shape = [](
int bl_shape_type) {
150 cube.influence_shape = to_eevee_shape(light_probe.attenuation_type);
151 cube.parallax_shape = to_eevee_shape(use_custom_parallax ? light_probe.parallax_type :
152 light_probe.attenuation_type);
155 cube.location = object_to_world.
location();
158 cube.influence_scale = 1.0 /
max_ff(1e-8f, influence_falloff);
159 cube.influence_bias = cube.influence_scale;
160 cube.parallax_distance = parallax_distance / influence_distance;
161 cube.clipping_distances =
float2(light_probe.clipsta, light_probe.clipend);
171 PlanarProbe &plane = planar_map_.lookup_or_add_default(handle.object_key);
173 if (handle.recalc != 0 || plane.initialized ==
false) {
176 plane.initialized =
true;
177 plane.updated =
true;
178 plane.plane_to_world = ob->object_to_world();
179 plane.plane_to_world.z_axis() =
math::normalize(plane.plane_to_world.z_axis()) *
180 light_probe->distinf;
181 plane.world_to_plane =
math::invert(plane.plane_to_world);
182 plane.clipping_offset = light_probe->clipsta;
189 const ::LightProbe *lightprobe =
static_cast<const ::
LightProbe *
>(ob->
data);
190 switch (lightprobe->type) {
192 sync_sphere(ob, handle);
195 sync_planar(ob, handle);
198 sync_volume(ob, handle);
207 world->probe_resolution);
210 int subdivision_lvl = sph_module.subdivision_level_get(probe_resolution);
212 if (subdivision_lvl != world_sphere_.atlas_coord.subdivision_lvl) {
213 world_sphere_.atlas_coord.free();
214 world_sphere_.atlas_coord = find_empty_atlas_region(subdivision_lvl);
216 world_data.
atlas_coord = world_sphere_.atlas_coord.as_sampling_coord();
221 world_sphere_.do_render =
true;
228 volume_update_ =
false;
231 bool remove_grid = !grid.
used;
232 if (grid.
updated || remove_grid) {
233 volume_update_ =
true;
241 sphere_update_ =
false;
244 bool remove_cube = !cube.
used;
245 if (cube.
updated || remove_cube) {
246 sphere_update_ =
true;
254 planar_update_ =
false;
257 bool remove_plane = !plane.
used;
258 if (plane.
updated || remove_plane) {
259 planar_update_ =
true;
269 int layer_count = sphere_layer_count();
272 location_finder.mark_space_used(world_sphere_.
atlas_coord);
273 for (
const SphereProbe &probe : sphere_map_.values()) {
274 location_finder.mark_space_used(probe.atlas_coord);
276 return location_finder.first_free_spot();
279int LightProbeModule::sphere_layer_count()
const
282 for (
const SphereProbe &probe : sphere_map_.values()) {
283 max_layer =
max_ii(max_layer, probe.atlas_coord.atlas_layer);
285 int layer_count = max_layer + 1;
296 int subdivision_level)
298 subdivision_level_ = subdivision_level;
299 areas_per_dimension_ = 1 << subdivision_level_;
300 areas_per_layer_ =
square_i(areas_per_dimension_);
303 int area_len = (allocated_layer_count + 1) * areas_per_layer_;
304 areas_occupancy_.resize(area_len,
false);
317 const int2 pos_in_location_finder = (coord.
area_location() >> shift_right) << shift_left;
319 const int layer_offset = coord.
atlas_layer * areas_per_layer_;
320 const int areas_overlapped_per_dim = 1 << shift_left;
321 for (
const int y :
IndexRange(areas_overlapped_per_dim)) {
322 for (
const int x :
IndexRange(areas_overlapped_per_dim)) {
325 areas_occupancy_[
area_index + layer_offset].set();
333 result.subdivision_lvl = subdivision_level_;
334 for (
int index : areas_occupancy_.index_range()) {
335 if (!areas_occupancy_[index]) {
336 result.atlas_layer = index / areas_per_layer_;
337 result.area_index = index % areas_per_layer_;
348 std::ostream &os = std::cout;
349 int layer = 0, row = 0, column = 0;
350 os <<
"subdivision " << subdivision_level_ <<
"\n";
351 for (
bool spot_taken : areas_occupancy_) {
352 if (row == 0 && column == 0) {
353 os <<
"layer " << layer <<
"\n";
355 os << (spot_taken ?
'X' :
'-');
357 if (column == areas_per_dimension_) {
362 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
struct LightProbe LightProbe
@ LIGHT_PROBE_RESOLUTION_128
@ LIGHT_PROBE_RESOLUTION_512
@ LIGHT_PROBE_RESOLUTION_4096
@ LIGHT_PROBE_RESOLUTION_256
@ LIGHT_PROBE_RESOLUTION_2048
@ LIGHT_PROBE_RESOLUTION_1024
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 world
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)
Simple API to draw debug shapes and log in the viewport.
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