EEVEE-Next: Per probe viewport display #114176

Merged
Miguel Pozo merged 8 commits from pragma37/blender:pull-eevee-probes-display into main 2023-11-02 17:08:22 +01:00
11 changed files with 121 additions and 4 deletions
Showing only changes of commit 248c1fd298 - Show all commits

View File

@ -172,9 +172,9 @@ class DATA_PT_lightprobe_eevee_next(DataButtonsPanel, Panel):
elif probe.type == 'PLANE':
col = layout.column()
row = col.row()
col.prop(probe, "clip_start", text="Clipping Offset")
col.prop(probe, "influence_distance", text="Distance")
col.prop(probe, "show_data", toggle=True)
pass
else:
# Currently unsupported

View File

@ -491,6 +491,8 @@ set(GLSL_SRC
engines/eevee_next/shaders/eevee_depth_of_field_tiles_flatten_comp.glsl
engines/eevee_next/shaders/eevee_display_probe_grid_frag.glsl
engines/eevee_next/shaders/eevee_display_probe_grid_vert.glsl
engines/eevee_next/shaders/eevee_display_probe_planar_frag.glsl
engines/eevee_next/shaders/eevee_display_probe_planar_vert.glsl
engines/eevee_next/shaders/eevee_display_probe_reflection_frag.glsl
engines/eevee_next/shaders/eevee_display_probe_reflection_vert.glsl
engines/eevee_next/shaders/eevee_film_comp.glsl

View File

@ -15,12 +15,14 @@ using namespace blender::math;
void PlanarProbe::sync(const float4x4 &world_to_object,
float clipping_offset,
float influence_distance)
float influence_distance,
bool viewport_display)
{
this->plane_to_world = float4x4(world_to_object);
this->plane_to_world.z_axis() = normalize(this->plane_to_world.z_axis()) * influence_distance;
this->world_to_plane = invert(this->plane_to_world);
this->clipping_offset = clipping_offset;
this->viewport_display = viewport_display;
}
void PlanarProbe::set_view(const draw::View &view, int layer_id)
@ -59,6 +61,8 @@ void PlanarProbeModule::init()
if (assign_if_different(update_probes_, !probes_.is_empty())) {
instance_.sampling.reset();
}
do_display_draw_ = false;
}
void PlanarProbeModule::begin_sync()
@ -76,7 +80,10 @@ void PlanarProbeModule::sync_object(Object *ob, ObjectHandle &ob_handle)
}
PlanarProbe &probe = find_or_insert(ob_handle);
probe.sync(float4x4(ob->object_to_world), light_probe->clipsta, light_probe->distinf);
probe.sync(float4x4(ob->object_to_world),
light_probe->clipsta,
light_probe->distinf,
light_probe->flag & LIGHTPROBE_FLAG_SHOW_DATA);
probe.is_probe_used = true;
}
@ -108,7 +115,10 @@ void PlanarProbeModule::set_view(const draw::View &main_view, int2 main_view_ext
radiance_tx_.ensure_2d_array(GPU_R11F_G11F_B10F, extent, layer_count, usage);
depth_tx_.ensure_2d_array(GPU_DEPTH_COMPONENT32F, extent, layer_count, usage);
do_display_draw_ = DRW_state_draw_support() && num_probes > 0;
int resource_index = 0;
int display_index = 0;
for (PlanarProbe &probe : probes_.values()) {
if (resource_index == PLANAR_PROBES_MAX) {
break;
@ -131,6 +141,10 @@ void PlanarProbeModule::set_view(const draw::View &main_view, int2 main_view_ext
instance_.pipelines.planar.render(res.view, res.combined_fb, resource_index, extent);
if (do_display_draw_ && probe.viewport_display) {
display_data_buf_.get_or_resize(display_index++) = {probe.plane_to_world, resource_index};
}
resource_index++;
}
@ -139,6 +153,12 @@ void PlanarProbeModule::set_view(const draw::View &main_view, int2 main_view_ext
probe_planar_buf_[resource_index].layer_id = -1;
}
probe_planar_buf_.push_update();
do_display_draw_ = display_index > 0;
if (do_display_draw_) {
display_data_buf_.resize(display_index);
display_data_buf_.push_update();
}
}
PlanarProbe &PlanarProbeModule::find_or_insert(ObjectHandle &ob_handle)
@ -147,6 +167,24 @@ PlanarProbe &PlanarProbeModule::find_or_insert(ObjectHandle &ob_handle)
return planar_probe;
}
void PlanarProbeModule::viewport_draw(View &view, GPUFrameBuffer *view_fb)
{
if (!do_display_draw_) {
return;
}
viewport_display_ps_.init();
viewport_display_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
viewport_display_ps_.framebuffer_set(&view_fb);
viewport_display_ps_.shader_set(instance_.shaders.static_shader_get(DISPLAY_PROBE_PLANAR));
bind_resources(viewport_display_ps_);
viewport_display_ps_.bind_ssbo("display_data_buf", display_data_buf_);
viewport_display_ps_.draw_procedural(GPU_PRIM_TRIS, 1, display_data_buf_.size() * 6);
instance_.manager->submit(viewport_display_ps_, view);
}
/** \} */
} // namespace blender::eevee

View File

@ -36,9 +36,14 @@ struct PlanarProbe : ProbePlanarData {
int resource_index;
/* Pruning flag. */
bool is_probe_used = false;
/** Display a debug plane in the viewport. */
bool viewport_display = false;
public:
void sync(const float4x4 &world_to_object, float clipping_offset, float influence_distance);
void sync(const float4x4 &world_to_object,
float clipping_offset,
float influence_distance,
bool viewport_display);
/**
* Update the ProbePlanarData part of the struct.
@ -90,6 +95,11 @@ class PlanarProbeModule {
bool update_probes_ = false;
/** Viewport data display drawing. */
bool do_display_draw_ = false;
ProbePlanarDisplayDataBuf display_data_buf_;
PassSimple viewport_display_ps_ = {"PlanarProbeModule.Viewport Display"};
public:
PlanarProbeModule(Instance &instance) : instance_(instance) {}
@ -100,6 +110,8 @@ class PlanarProbeModule {
void set_view(const draw::View &main_view, int2 main_view_extent);
void viewport_draw(View &view, GPUFrameBuffer *view_fb);
template<typename PassType> void bind_resources(PassType &pass)
{
/* Disable filter to avoid interpolation with missing background. */

View File

@ -122,6 +122,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
return "eevee_display_probe_grid";
case DISPLAY_PROBE_REFLECTION:
return "eevee_display_probe_reflection";
case DISPLAY_PROBE_PLANAR:
return "eevee_display_probe_planar";
case DOF_BOKEH_LUT:
return "eevee_depth_of_field_bokeh_lut";
case DOF_DOWNSAMPLE:

View File

@ -42,6 +42,7 @@ enum eShaderType {
DISPLAY_PROBE_GRID,
DISPLAY_PROBE_REFLECTION,
DISPLAY_PROBE_PLANAR,
DOF_BOKEH_LUT,
DOF_DOWNSAMPLE,

View File

@ -1376,6 +1376,16 @@ struct ClipPlaneData {
};
BLI_STATIC_ASSERT_ALIGN(ClipPlaneData, 16)
/** Viewport Display Pass. */
struct ProbePlanarDisplayData {
float4x4 plane_to_world;
int probe_index;
float _pad0;
float _pad1;
float _pad2;
};
BLI_STATIC_ASSERT_ALIGN(ProbePlanarDisplayData, 16)
/** \} */
/* -------------------------------------------------------------------- */
@ -1495,6 +1505,7 @@ using ReflectionProbeDataBuf =
draw::UniformArrayBuffer<ReflectionProbeData, REFLECTION_PROBES_MAX>;
using ReflectionProbeDisplayDataBuf = draw::StorageArrayBuffer<ReflectionProbeDisplayData>;
using ProbePlanarDataBuf = draw::UniformArrayBuffer<ProbePlanarData, PLANAR_PROBES_MAX>;
using ProbePlanarDisplayDataBuf = draw::StorageArrayBuffer<ProbePlanarDisplayData>;
using SamplingDataBuf = draw::StorageBuffer<SamplingData>;
using ShadowStatisticsBuf = draw::StorageBuffer<ShadowStatistics>;
using ShadowPagesInfoDataBuf = draw::StorageBuffer<ShadowPagesInfoData>;

View File

@ -151,6 +151,7 @@ void ShadingView::render()
inst_.shadows.debug_draw(render_view_new_, combined_fb_);
inst_.irradiance_cache.viewport_draw(render_view_new_, combined_fb_);
inst_.reflection_probes.viewport_draw(render_view_new_, combined_fb_);
inst_.planar_probes.viewport_draw(render_view_new_, combined_fb_);
inst_.ambient_occlusion.render_pass(render_view_new_);

View File

@ -0,0 +1,9 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
void main()
{
vec2 uv = gl_FragCoord.xy / textureSize(planar_radiance_tx, 0).xy;
out_color = texture(planar_radiance_tx, vec3(uv, probe_index));
}

View File

@ -0,0 +1,30 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl)
#pragma BLENDER_REQUIRE(draw_view_lib.glsl)
void main()
{
/* Constant array moved inside function scope.
* Minimizes local register allocation in MSL. */
const vec2 pos[6] = vec2[6](vec2(-1.0, -1.0),
vec2(1.0, -1.0),
vec2(-1.0, 1.0),
vec2(1.0, -1.0),
vec2(1.0, 1.0),
vec2(-1.0, 1.0));
vec2 lP = pos[gl_VertexID % 6];
int display_index = gl_VertexID / 6;
probe_index = display_data_buf[display_index].probe_index;
vec3 P = transform_point(display_data_buf[display_index].plane_to_world, vec3(lP, 0.0));
gl_Position = drw_point_world_to_homogenous(P);
/* Small bias to let the icon draw without Z-fighting. */
gl_Position.z += 0.0001;
}

View File

@ -63,4 +63,15 @@ GPU_SHADER_CREATE_INFO(eevee_display_probe_reflection)
.fragment_out(0, Type::VEC4, "out_color")
.do_static_compilation(true);
GPU_SHADER_INTERFACE_INFO(eevee_display_probe_planar_iface, "").flat(Type::INT, "probe_index");
GPU_SHADER_CREATE_INFO(eevee_display_probe_planar)
.additional_info("eevee_shared", "draw_view", "eevee_lightprobe_planar_data")
.storage_buf(0, Qualifier::READ, "ProbePlanarDisplayData", "display_data_buf[]")
.vertex_source("eevee_display_probe_planar_vert.glsl")
.vertex_out(eevee_display_probe_planar_iface)
.fragment_source("eevee_display_probe_planar_frag.glsl")
.fragment_out(0, Type::VEC4, "out_color")
.do_static_compilation(true);
/** \} */