27 do_display_draw_ =
false;
32 update_probes_this_sample_ = update_probes_next_sample_;
41 pass.specialize_constant(shader,
"extract_sh", &extract_sh_);
42 pass.specialize_constant(shader,
"extract_sun", &extract_sh_);
43 pass.shader_set(shader);
44 pass.bind_texture(
"cubemap_tx", &cubemap_tx_);
45 pass.bind_texture(
"atlas_tx", &probes_tx_);
46 pass.bind_image(
"atlas_img", &probes_tx_);
47 pass.bind_ssbo(
"out_sh", &tmp_spherical_harmonics_);
48 pass.bind_ssbo(
"out_sun", &tmp_sunlight_);
49 pass.push_constant(
"probe_coord_packed",
reinterpret_cast<int4 *
>(&probe_sampling_coord_));
50 pass.push_constant(
"write_coord_packed",
reinterpret_cast<int4 *
>(&probe_write_coord_));
51 pass.push_constant(
"world_coord_packed",
reinterpret_cast<int4 *
>(&world_data.
atlas_coord));
53 pass.dispatch(&dispatch_probe_pack_);
59 pass.bind_texture(
"cubemap_tx", &cubemap_tx_);
60 pass.bind_texture(
"in_atlas_mip_tx", &convolve_input_);
61 pass.bind_image(
"out_atlas_mip_img", &convolve_output_);
62 pass.push_constant(
"probe_coord_packed",
reinterpret_cast<int4 *
>(&probe_sampling_coord_));
63 pass.push_constant(
"write_coord_packed",
reinterpret_cast<int4 *
>(&probe_write_coord_));
64 pass.push_constant(
"read_coord_packed",
reinterpret_cast<int4 *
>(&probe_read_coord_));
65 pass.push_constant(
"read_lod", &convolve_lod_);
67 pass.dispatch(&dispatch_probe_convolve_);
73 pass.push_constant(
"probe_remap_dispatch_size", &dispatch_probe_pack_);
74 pass.bind_ssbo(
"in_sh", &tmp_spherical_harmonics_);
75 pass.bind_ssbo(
"out_sh", &spherical_harmonics_);
83 pass.push_constant(
"probe_remap_dispatch_size", &dispatch_probe_pack_);
84 pass.bind_ssbo(
"in_sun", &tmp_sunlight_);
94 pass.push_constant(
"lightprobe_sphere_count", &lightprobe_sphere_count_);
95 pass.bind_ssbo(
"lightprobe_sphere_buf", &data_buf_);
99 pass.dispatch(&dispatch_probe_select_);
104bool SphereProbeModule::ensure_atlas()
133 const bool atlas_resized = ensure_atlas();
139 update_probes_next_sample_ =
false;
141 if (atlas_resized || world_updated) {
143 probe.do_render =
true;
145 if (probe.do_render) {
149 update_probes_next_sample_ =
true;
167void SphereProbeModule::ensure_cubemap_render_target(
int resolution)
174SphereProbeModule::UpdateInfo SphereProbeModule::update_info_from_probe(SphereProbe &probe)
176 SphereProbeModule::UpdateInfo info = {};
177 info.atlas_coord = probe.atlas_coord;
178 info.cube_target_extent = probe.atlas_coord.area_extent() / 2;
179 info.clipping_distances = probe.clipping_distances;
180 info.probe_pos = probe.location;
181 info.do_render = probe.do_render;
183 probe.do_render =
false;
184 probe.use_for_render =
true;
186 ensure_cubemap_render_target(info.cube_target_extent);
190std::optional<SphereProbeModule::UpdateInfo> SphereProbeModule::world_update_info_pop()
192 SphereProbe &world_probe = instance_.
light_probes.world_sphere_;
193 if (world_probe.do_render) {
194 return update_info_from_probe(world_probe);
199std::optional<SphereProbeModule::UpdateInfo> SphereProbeModule::probe_update_info_pop()
206 for (SphereProbe &probe : instance_.light_probes.sphere_map_.values()) {
207 if (!probe.do_render) {
210 return update_info_from_probe(probe);
216void SphereProbeModule::remap_to_octahedral_projection(
const SphereProbeAtlasCoord &atlas_coord,
217 bool extract_spherical_harmonics)
220 probe_sampling_coord_ = atlas_coord.as_sampling_coord();
221 probe_write_coord_ = atlas_coord.as_write_coord(0);
222 int resolution = probe_write_coord_.
extent;
223 dispatch_probe_pack_ =
int3(
225 extract_sh_ = extract_spherical_harmonics;
231 convolve_input_ = probes_tx_.
mip_view(i);
232 convolve_output_ = probes_tx_.
mip_view(i + 1);
233 probe_read_coord_ = atlas_coord.as_write_coord(i);
234 probe_write_coord_ = atlas_coord.as_write_coord(i + 1);
235 int out_mip_res = probe_write_coord_.
extent;
236 dispatch_probe_convolve_ =
int3(
241 if (extract_spherical_harmonics) {
255 for (
auto &probe : instance_.
light_probes.sphere_map_.values()) {
260 if (!probe.use_for_render) {
264 probe_active.
append(&probe);
270 if (a->volume != b->volume) {
272 return a->volume < b->volume;
294 for (
auto &probe : probe_active) {
295 data_buf_[probe_id++] = *probe;
298 data_buf_[probe_id++] = instance_.light_probes.world_sphere_;
301 data_buf_[probe_id].atlas_coord.layer = -1;
303 data_buf_.push_update();
305 lightprobe_sphere_count_ = probe_id;
306 dispatch_probe_select_.x =
divide_ceil_u(lightprobe_sphere_count_,
308 instance_.manager->submit(select_ps_);
310 sync_display(probe_active);
313void SphereProbeModule::sync_display(Vector<SphereProbe *> &probe_active)
315 do_display_draw_ =
false;
320 int display_index = 0;
321 for (
int i : probe_active.index_range()) {
322 if (probe_active[i]->viewport_display) {
324 sph_data.probe_index = i;
325 sph_data.display_size = probe_active[i]->viewport_display_size;
329 if (display_index == 0) {
332 do_display_draw_ =
true;
333 display_data_buf_.resize(display_index);
334 display_data_buf_.push_update();
337void SphereProbeModule::viewport_draw(
View &view, GPUFrameBuffer *view_fb)
339 if (!do_display_draw_) {
343 viewport_display_ps_.init();
346 viewport_display_ps_.framebuffer_set(&view_fb);
348 viewport_display_ps_.bind_resources(*
this);
349 viewport_display_ps_.bind_ssbo(
"display_data_buf", display_data_buf_);
350 viewport_display_ps_.draw_procedural(
GPU_PRIM_TRIS, 1, display_data_buf_.size() * 6);
352 instance_.manager->submit(viewport_display_ps_, view);
MINLINE uint divide_ceil_u(uint a, uint b)
bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_SHADER_STORAGE
@ GPU_BARRIER_TEXTURE_FETCH
void GPU_texture_clear(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
@ GPU_TEXTURE_USAGE_ATTACHMENT
void GPU_texture_mipmap_mode(GPUTexture *texture, bool use_mipmap, bool use_filter)
struct GPUShader GPUShader
void append(const T &value)
void submit(PassSimple &pass, View &view)
bool ensure_mip_views(bool cube_as_array=false)
bool ensure_cube(eGPUTextureFormat format, int extent, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, float *data=nullptr, int mip_len=1)
bool ensure_2d_array(eGPUTextureFormat format, int2 extent, int layers, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
GPUTexture * mip_view(int miplvl)
VolumeProbeModule volume_probes
bool do_lightprobe_sphere_sync() const
UniformDataModule uniform_data
LightProbeModule light_probes
void bind_resources(PassType &pass)
GPUShader * static_shader_get(eShaderType shader_type)
void set_view(View &view)
int probe_render_extent() const
void bind_resources(PassType &pass)
void update_world_irradiance()
UniformBuffer< LightData > sunlight
local_group_size(16, 16) .push_constant(Type b
bool DRW_state_draw_support()
void DRW_viewport_request_redraw()
@ DRW_STATE_DEPTH_LESS_EQUAL
#define SPHERE_PROBE_REMAP_GROUP_SIZE
#define SPHERE_PROBE_ATLAS_RES
#define SPHERE_PROBE_SELECT_GROUP_SIZE
#define SPHERE_PROBE_MIPMAP_LEVELS
#define SPHERE_PROBE_GROUP_SIZE
local_group_size(SPHERE_PROBE_GROUP_SIZE, SPHERE_PROBE_GROUP_SIZE) .additional_info("eevee_shared") .push_constant(Type smooth(Type::VEC3, "P") .smooth(Type SphereProbeDisplayData
@ SPHERE_PROBE_IRRADIANCE
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< int32_t, 2 > int2
VecBase< int32_t, 3 > int3
int gi_cubemap_resolution
SphereProbeUvArea atlas_coord