Blender V4.3
eevee_lightprobe_planar.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6#include "eevee_instance.hh"
7
8namespace blender::eevee {
9
10using namespace blender::math;
11
12/* -------------------------------------------------------------------- */
16void PlanarProbe::set_view(const draw::View &view, int layer_id)
17{
18 this->viewmat = view.viewmat() * reflection_matrix_get();
19 this->winmat = view.winmat();
21 this->normal = normalize(plane_to_world.z_axis());
22
23 bool view_is_below_plane = dot(view.location() - plane_to_world.location(),
24 plane_to_world.z_axis()) < 0.0;
25 if (view_is_below_plane) {
26 this->normal = -this->normal;
27 }
28 this->layer_id = layer_id;
29}
30
33/* -------------------------------------------------------------------- */
38{
39 /* This triggers the compilation of clipped shader only if we can detect light-probe planes. */
40 if (inst_.is_viewport()) {
41 /* This check needs to happen upfront before sync, so we use the previous sync result. */
42 update_probes_ = !inst_.light_probes.planar_map_.is_empty();
43 }
44 else {
45 /* TODO(jbakker): should we check on the subtype as well? Now it also populates even when
46 * there are other light probes in the scene. */
47 update_probes_ = DEG_id_type_any_exists(inst_.depsgraph, ID_LP);
48 }
49
50 do_display_draw_ = false;
51}
52
54{
55 /* When first planar probes are enabled it can happen that the first sample is off. */
56 if (!update_probes_ && !inst_.light_probes.planar_map_.is_empty()) {
58 }
59}
60
61void PlanarProbeModule::set_view(const draw::View &main_view, int2 main_view_extent)
62{
63 GBuffer &gbuf = inst_.gbuffer;
64
65 const int64_t num_probes = inst_.light_probes.planar_map_.size();
66
67 /* TODO resolution percentage. */
68 int2 extent = main_view_extent;
69 int layer_count = num_probes;
70
71 if (num_probes == 0) {
72 /* Create valid dummy texture. */
73 extent = int2(1);
74 layer_count = 1;
75 }
76
78 radiance_tx_.ensure_2d_array(GPU_R11F_G11F_B10F, extent, layer_count, usage);
79 depth_tx_.ensure_2d_array(GPU_DEPTH_COMPONENT32F, extent, layer_count, usage);
80 depth_tx_.ensure_layer_views();
81
82 do_display_draw_ = DRW_state_draw_support() && num_probes > 0;
83
84 int resource_index = 0;
85 int display_index = 0;
86 for (PlanarProbe &probe : inst_.light_probes.planar_map_.values()) {
87 if (resource_index == PLANAR_PROBE_MAX) {
88 break;
89 }
90
91 PlanarResources &res = resources_[resource_index];
92
93 /* TODO Cull out of view planars. */
94
95 probe.set_view(main_view, resource_index);
96 probe_planar_buf_[resource_index] = probe;
97
98 res.view.sync(probe.viewmat, probe.winmat);
99
100 world_clip_buf_.plane = probe.reflection_clip_plane_get();
101 world_clip_buf_.push_update();
102
103 gbuf.acquire(extent,
106
107 res.combined_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx_, resource_index),
108 GPU_ATTACHMENT_TEXTURE_LAYER(radiance_tx_, resource_index));
109
110 res.gbuffer_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx_, resource_index),
111 GPU_ATTACHMENT_TEXTURE_LAYER(radiance_tx_, resource_index),
116
117 inst_.pipelines.planar.render(
118 res.view, depth_tx_.layer_view(resource_index), res.gbuffer_fb, res.combined_fb, extent);
119
120 if (do_display_draw_ && probe.viewport_display) {
121 display_data_buf_.get_or_resize(display_index++) = {probe.plane_to_world, resource_index};
122 }
123
124 resource_index++;
125 }
126
127 gbuf.release();
128
129 if (resource_index < PLANAR_PROBE_MAX) {
130 /* Tag the end of the array. */
131 probe_planar_buf_[resource_index].layer_id = -1;
132 }
133 probe_planar_buf_.push_update();
134
135 do_display_draw_ = display_index > 0;
136 if (do_display_draw_) {
137 display_data_buf_.resize(display_index);
138 display_data_buf_.push_update();
139 }
140}
141
142void PlanarProbeModule::viewport_draw(View &view, GPUFrameBuffer *view_fb)
143{
144 if (!do_display_draw_) {
145 return;
146 }
147
148 viewport_display_ps_.init();
151 viewport_display_ps_.framebuffer_set(&view_fb);
152 viewport_display_ps_.shader_set(inst_.shaders.static_shader_get(DISPLAY_PROBE_PLANAR));
153 SphereProbeData &world_data = *static_cast<SphereProbeData *>(&inst_.light_probes.world_sphere_);
154 viewport_display_ps_.push_constant("world_coord_packed",
155 reinterpret_cast<int4 *>(&world_data.atlas_coord));
156 viewport_display_ps_.bind_resources(*this);
157 viewport_display_ps_.bind_resources(inst_.sphere_probes);
158 viewport_display_ps_.bind_ssbo("display_data_buf", display_data_buf_);
159 viewport_display_ps_.draw_procedural(GPU_PRIM_TRIS, 1, display_data_buf_.size() * 6);
160
161 inst_.manager->submit(viewport_display_ps_, view);
162}
163
166} // namespace blender::eevee
bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
@ ID_LP
#define GPU_ATTACHMENT_TEXTURE(_texture)
#define GPU_ATTACHMENT_TEXTURE_LAYER(_texture, _layer)
@ GPU_PRIM_TRIS
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_DEPTH_COMPONENT32F
btMatrix3x3 transpose() const
Return the transpose of the matrix.
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
void ensure(GPUAttachment depth=GPU_ATTACHMENT_NONE, GPUAttachment color1=GPU_ATTACHMENT_NONE, GPUAttachment color2=GPU_ATTACHMENT_NONE, GPUAttachment color3=GPU_ATTACHMENT_NONE, GPUAttachment color4=GPU_ATTACHMENT_NONE, GPUAttachment color5=GPU_ATTACHMENT_NONE, GPUAttachment color6=GPU_ATTACHMENT_NONE, GPUAttachment color7=GPU_ATTACHMENT_NONE, GPUAttachment color8=GPU_ATTACHMENT_NONE)
void submit(PassSimple &pass, View &view)
bool ensure_2d_array(eGPUTextureFormat format, int2 extent, int layers, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
bool ensure_layer_views(bool cube_as_array=false)
GPUTexture * layer_view(int layer)
const float4x4 & winmat(int view_id=0) const
Definition draw_view.hh:145
const float4x4 & viewmat(int view_id=0) const
Definition draw_view.hh:133
void sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id=0)
Definition draw_view.cc:20
void bind_resources(U &resources)
Definition draw_pass.hh:426
void draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
Definition draw_pass.hh:833
void state_set(DRWState state, int clip_plane_count=0)
Definition draw_pass.hh:954
void framebuffer_set(GPUFrameBuffer **framebuffer)
Definition draw_pass.hh:977
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
Definition draw_pass.hh:971
SphereProbeModule sphere_probes
LightProbeModule light_probes
void set_view(const draw::View &main_view, int2 main_view_extent)
void viewport_draw(View &view, GPUFrameBuffer *view_fb)
void render(View &view, GPUTexture *depth_layer_tx, Framebuffer &gbuffer, Framebuffer &combined_fb, int2 extent)
GPUShader * static_shader_get(eShaderType shader_type)
bool DRW_state_draw_support()
void DRW_viewport_request_redraw()
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition draw_state.hh:38
@ DRW_STATE_CULL_BACK
Definition draw_state.hh:43
#define PLANAR_PROBE_MAX
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
MatBase< float, 3, 4 > float3x4
VecBase< int32_t, 2 > int2
__int64 int64_t
Definition stdint.h:89
void acquire(int2 extent, int data_count, int normal_count)
void set_view(const draw::View &view, int layer_id)