EEVEE Next: GI surfels debug display #105802

Merged
Miguel Pozo merged 6 commits from pragma37/blender:pull-eevee-next-surfels into main 2023-03-16 14:14:44 +01:00
13 changed files with 210 additions and 1 deletions

View File

@ -144,6 +144,7 @@ set(SRC
engines/eevee_next/eevee_film.cc
engines/eevee_next/eevee_hizbuffer.cc
pragma37 marked this conversation as resolved Outdated

Rename to eevee_irradiance_cache.cc.

Rename to `eevee_irradiance_cache.cc`.
engines/eevee_next/eevee_instance.cc
engines/eevee_next/eevee_irradiance_cache.cc
engines/eevee_next/eevee_light.cc
engines/eevee_next/eevee_material.cc
engines/eevee_next/eevee_motion_blur.cc
@ -275,6 +276,7 @@ set(SRC
engines/eevee_next/eevee_film.hh
engines/eevee_next/eevee_hizbuffer.hh
engines/eevee_next/eevee_instance.hh
engines/eevee_next/eevee_irradiance_cache.hh
engines/eevee_next/eevee_light.hh
engines/eevee_next/eevee_material.hh
engines/eevee_next/eevee_motion_blur.hh
@ -425,6 +427,8 @@ set(GLSL_SRC
engines/eevee_next/shaders/eevee_colorspace_lib.glsl
engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
engines/eevee_next/shaders/eevee_transparency_lib.glsl
engines/eevee_next/shaders/eevee_debug_surfels_vert.glsl
engines/eevee_next/shaders/eevee_debug_surfels_frag.glsl
engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
engines/eevee_next/shaders/eevee_depth_of_field_bokeh_lut_comp.glsl
engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl

View File

@ -70,6 +70,7 @@ void Instance::init(const int2 &output_res,
shadows.init();
motion_blur.init();
main_view.init();
irradiance_cache.init();
}
void Instance::set_time(float time)
@ -117,6 +118,7 @@ void Instance::begin_sync()
main_view.sync();
world.sync();
film.sync();
irradiance_cache.sync();
}
void Instance::scene_sync()

View File

@ -20,6 +20,7 @@
#include "eevee_depth_of_field.hh"
#include "eevee_film.hh"
#include "eevee_hizbuffer.hh"
#include "eevee_irradiance_cache.hh"
#include "eevee_light.hh"
#include "eevee_material.hh"
#include "eevee_motion_blur.hh"
@ -60,6 +61,7 @@ class Instance {
RenderBuffers render_buffers;
MainView main_view;
World world;
IrradianceCache irradiance_cache;
/** Input data. */
Depsgraph *depsgraph;
@ -103,7 +105,8 @@ class Instance {
film(*this),
render_buffers(*this),
main_view(*this),
world(*this){};
world(*this),
irradiance_cache(*this){};
~Instance(){};
void init(const int2 &output_res,

View File

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_rand.hh"
#include "eevee_instance.hh"
#include "eevee_irradiance_cache.hh"
namespace blender::eevee {
void IrradianceCache::generate_random_surfels()
{
const int surfels_len = 256;
debug_surfels.resize(surfels_len);
RandomNumberGenerator rng;
rng.seed(0);
for (DebugSurfel &surfel : debug_surfels) {
float3 random = rng.get_unit_float3();
surfel.position = random * 3.0f;
surfel.normal = random;
surfel.color = float4(rng.get_float(), rng.get_float(), rng.get_float(), 1.0f);
}
debug_surfels.push_update();
}
void IrradianceCache::init()
{
if (debug_surfels_sh_ == nullptr) {
debug_surfels_sh_ = inst_.shaders.static_shader_get(DEBUG_SURFELS);
}
/* TODO: Remove this. */
generate_random_surfels();
}
void IrradianceCache::sync()
{
debug_pass_sync();
}
void IrradianceCache::debug_pass_sync()
{
if (inst_.debug_mode == eDebugMode::DEBUG_IRRADIANCE_CACHE_SURFELS) {
debug_surfels_ps_.init();
debug_surfels_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
DRW_STATE_DEPTH_LESS_EQUAL);
debug_surfels_ps_.shader_set(debug_surfels_sh_);
debug_surfels_ps_.bind_ssbo("surfels_buf", debug_surfels);
debug_surfels_ps_.push_constant("surfel_radius", 0.25f);
debug_surfels_ps_.draw_procedural(GPU_PRIM_TRI_STRIP, debug_surfels.size(), 4);
}
}
void IrradianceCache::debug_draw(View &view, GPUFrameBuffer *view_fb)
{
if (inst_.debug_mode == eDebugMode::DEBUG_IRRADIANCE_CACHE_SURFELS) {
inst_.info = "Debug Mode: Irradiance Cache Surfels";
GPU_framebuffer_bind(view_fb);
inst_.manager->submit(debug_surfels_ps_, view);
}
}
} // namespace blender::eevee

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "eevee_shader_shared.hh"
namespace blender::eevee {
class Instance;
class IrradianceCache {
private:
Instance &inst_;
DebugSurfelBuf debug_surfels;
PassSimple debug_surfels_ps_ = {"IrradianceCache.Debug"};
GPUShader *debug_surfels_sh_ = nullptr;
/* TODO: Remove this. */
void generate_random_surfels();
public:
IrradianceCache(Instance &inst) : inst_(inst){};
~IrradianceCache(){};
void init();
void sync();
void debug_pass_sync();
void debug_draw(View &view, GPUFrameBuffer *view_fb);
};
} // namespace blender::eevee

View File

@ -98,6 +98,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
return "eevee_motion_blur_tiles_flatten_render";
case MOTION_BLUR_TILE_FLATTEN_VIEWPORT:
return "eevee_motion_blur_tiles_flatten_viewport";
case DEBUG_SURFELS:
return "eevee_debug_surfels";
case DOF_BOKEH_LUT:
return "eevee_depth_of_field_bokeh_lut";
case DOF_DOWNSAMPLE:

View File

@ -30,6 +30,8 @@ enum eShaderType {
FILM_COMP,
FILM_CRYPTOMATTE_POST,
DEBUG_SURFELS,
DOF_BOKEH_LUT,
DOF_DOWNSAMPLE,
DOF_FILTER,

View File

@ -48,6 +48,10 @@ enum eDebugMode : uint32_t {
* Show incorrectly downsample tiles in red.
*/
DEBUG_HIZ_VALIDATION = 2u,
/**
* Display IrradianceCache surfels.
*/
DEBUG_IRRADIANCE_CACHE_SURFELS = 3u,
/**
* Show tiles depending on their status.
*/
@ -821,6 +825,21 @@ static inline ShadowTileDataPacked shadow_tile_pack(ShadowTileData tile)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Debug
* \{ */
pragma37 marked this conversation as resolved

\name Debug

`\name Debug`
struct DebugSurfel {
packed_float3 position;
pragma37 marked this conversation as resolved Outdated

Rename to DebugSurfel

Rename to `DebugSurfel`

So the idea would be to eventually have a Surfel and a DebugSurfel and make the copy/conversion before rendering the debug visualization?

So the idea would be to eventually have a Surfel and a DebugSurfel and make the copy/conversion before rendering the debug visualization?

Yes. I'm thinking we could reuse it for raytracing debugging.

Yes. I'm thinking we could reuse it for raytracing debugging.
int _pad0;
pragma37 marked this conversation as resolved

Use packed_float3 if you do that.

Use `packed_float3` if you do that.
packed_float3 normal;
int _pad1;
float4 color;
};
BLI_STATIC_ASSERT_ALIGN(DebugSurfel, 16)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Hierarchical-Z Buffer
* \{ */
@ -928,6 +947,7 @@ using DepthOfFieldDataBuf = draw::UniformBuffer<DepthOfFieldData>;
using DepthOfFieldScatterListBuf = draw::StorageArrayBuffer<ScatterRect, 16, true>;
using DrawIndirectBuf = draw::StorageBuffer<DrawCommand, true>;
using FilmDataBuf = draw::UniformBuffer<FilmData>;
using DebugSurfelBuf = draw::StorageArrayBuffer<DebugSurfel, 64>;
using HiZDataBuf = draw::UniformBuffer<HiZData>;
using LightCullingDataBuf = draw::StorageBuffer<LightCullingData>;
using LightCullingKeyBuf = draw::StorageArrayBuffer<uint, LIGHT_CHUNK, true>;

View File

@ -136,6 +136,8 @@ void ShadingView::render()
inst_.hiz_buffer.debug_draw(render_view_new_, combined_fb_);
inst_.shadows.debug_draw(render_view_new_, combined_fb_);
inst_.irradiance_cache.debug_draw(render_view_new_, combined_fb_);
GPUTexture *combined_final_tx = render_postfx(rbufs.combined_tx);
inst_.film.accumulate(sub_view_, combined_final_tx);

View File

@ -0,0 +1,21 @@
void main()
{
DebugSurfel surfel = surfels_buf[surfel_index];
out_color = surfel.color;
/* Display surfels as circles. */
if (distance(P, surfel.position) > surfel_radius) {
discard;
return;
}
/* Display backfacing surfels with a transparent checkerboard grid. */
if (!gl_FrontFacing) {
ivec2 grid_uv = ivec2(gl_FragCoord) / 5;
if ((grid_uv.x + grid_uv.y) % 2 == 0) {
discard;
return;
}
}
}

View File

@ -0,0 +1,38 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
void main()
{
surfel_index = gl_InstanceID;
DebugSurfel surfel = surfels_buf[surfel_index];
vec3 lP;
switch (gl_VertexID) {
case 0:
lP = vec3(-1, 1, 0);
break;
case 1:
lP = vec3(-1, -1, 0);
break;
case 2:
lP = vec3(1, 1, 0);
break;
case 3:
lP = vec3(1, -1, 0);
break;
}
vec3 N = surfel.normal;
vec3 T, B;
make_orthonormal_basis(N, T, B);
mat4 model_matrix = mat4(vec4(T * surfel_radius, 0),
vec4(B * surfel_radius, 0),
vec4(N * surfel_radius, 0),
vec4(surfel.position, 1));
P = (model_matrix * vec4(lP, 1)).xyz;
gl_Position = point_world_to_ndc(P);
}

View File

@ -0,0 +1,16 @@
#include "eevee_defines.hh"
#include "gpu_shader_create_info.hh"
GPU_SHADER_INTERFACE_INFO(eeve_debug_surfel_iface, "")
.smooth(Type::VEC3, "P")
.flat(Type::INT, "surfel_index");
GPU_SHADER_CREATE_INFO(eevee_debug_surfels)
.additional_info("eevee_shared", "draw_view")
.vertex_source("eevee_debug_surfels_vert.glsl")
.vertex_out(eeve_debug_surfel_iface)
.fragment_source("eevee_debug_surfels_frag.glsl")
.fragment_out(0, Type::VEC4, "out_color")
.storage_buf(0, Qualifier::READ, "DebugSurfel", "surfels_buf[]")
.push_constant(Type::FLOAT, "surfel_radius")
.do_static_compilation(true);

View File

@ -606,6 +606,7 @@ set(SRC_SHADER_CREATE_INFOS
../draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_film_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_irradiance_cache_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
../draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh