EEVEE-Next: Raytrace: Add Diffuse Ray

This implement the diffuse tracing as simple
screen-space ray trace. This is extremely inefficient
and should only be used for reference purpose.

The real screen space diffuse implementation will
be done in another PR.

Depends on #112507

![image](/attachments/a2c0a9d9-3206-4dc7-acf8-0c37851ad10b)

Pull Request: https://projects.blender.org/blender/blender/pulls/112539
This commit is contained in:
Clément Foucault 2023-09-20 18:36:59 +02:00 committed by Clément Foucault
parent 2638f30983
commit 89da0cf07d
12 changed files with 88 additions and 35 deletions

View File

@ -78,6 +78,8 @@
#define RAYTRACE_GROUP_SIZE 8
/* Keep this as a define to avoid shader variations. */
#define RAYTRACE_RADIANCE_FORMAT GPU_R11F_G11F_B10F
#define RAYTRACE_RAYTIME_FORMAT GPU_R32F
#define RAYTRACE_HORIZON_FORMAT GPU_R32UI
#define RAYTRACE_VARIANCE_FORMAT GPU_R16F
#define RAYTRACE_TILEMASK_FORMAT GPU_R8UI

View File

@ -593,10 +593,13 @@ void DeferredLayer::render(View &main_view,
inst_.subsurface.render(render_view, combined_fb, direct_diffuse_tx_);
}
TextureFromPool dummy_diffuse_indirect;
dummy_diffuse_indirect.acquire(int2(1), RAYTRACE_RADIANCE_FORMAT);
dummy_diffuse_indirect.clear(float4(0));
RayTraceResult diffuse_result = {dummy_diffuse_indirect};
RayTraceResult diffuse_result = inst_.raytracing.trace(rt_buffer,
radiance_feedback_tx_,
radiance_feedback_persmat_,
closure_bits_,
CLOSURE_DIFFUSE,
main_view,
render_view);
RayTraceResult reflect_result = inst_.raytracing.trace(rt_buffer,
radiance_feedback_tx_,

View File

@ -41,6 +41,16 @@ void RayTraceModule::sync()
{
Texture &depth_tx = inst_.render_buffers.depth_tx;
#define SHADER_VARIATION(_shader_name, _index) \
((_index == 0) ? _shader_name##REFLECT : \
(_index == 1) ? _shader_name##REFRACT : \
_shader_name##DIFFUSE)
#define PASS_VARIATION(_pass_name, _index, _suffix) \
((_index == 0) ? _pass_name##reflect##_suffix : \
(_index == 1) ? _pass_name##refract##_suffix : \
_pass_name##diffuse##_suffix)
/* Setup. */
{
PassSimple &pass = tile_classify_ps_;
@ -67,11 +77,10 @@ void RayTraceModule::sync()
pass.dispatch(&tile_compact_dispatch_size_);
pass.barrier(GPU_BARRIER_SHADER_STORAGE);
}
for (auto type : IndexRange(2)) {
PassSimple &pass = (type == 0) ? generate_reflect_ps_ : generate_refract_ps_;
for (auto type : IndexRange(3)) {
PassSimple &pass = PASS_VARIATION(generate_, type, _ps_);
pass.init();
pass.shader_set(inst_.shaders.static_shader_get((type == 0) ? RAY_GENERATE_REFLECT :
RAY_GENERATE_REFRACT));
pass.shader_set(inst_.shaders.static_shader_get(SHADER_VARIATION(RAY_GENERATE_, type)));
pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
pass.bind_image("out_ray_data_img", &ray_data_tx_);
pass.bind_ssbo("tiles_coord_buf", &ray_tiles_buf_);
@ -82,11 +91,10 @@ void RayTraceModule::sync()
GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
/* Tracing. */
for (auto type : IndexRange(2)) {
PassSimple &pass = (type == 0) ? trace_reflect_ps_ : trace_refract_ps_;
for (auto type : IndexRange(3)) {
PassSimple &pass = PASS_VARIATION(trace_, type, _ps_);
pass.init();
pass.shader_set(inst_.shaders.static_shader_get((type == 0) ? RAY_TRACE_SCREEN_REFLECT :
RAY_TRACE_SCREEN_REFRACT));
pass.shader_set(inst_.shaders.static_shader_get(SHADER_VARIATION(RAY_TRACE_SCREEN_, type)));
pass.bind_ssbo("tiles_coord_buf", &ray_tiles_buf_);
pass.bind_image("ray_data_img", &ray_data_tx_);
pass.bind_image("ray_time_img", &ray_time_tx_);
@ -115,11 +123,10 @@ void RayTraceModule::sync()
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
/* Denoise. */
for (auto type : IndexRange(2)) {
PassSimple &pass = (type == 0) ? denoise_spatial_reflect_ps_ : denoise_spatial_refract_ps_;
for (auto type : IndexRange(3)) {
PassSimple &pass = PASS_VARIATION(denoise_spatial_, type, _ps_);
pass.init();
pass.shader_set(inst_.shaders.static_shader_get((type == 0) ? RAY_DENOISE_SPATIAL_REFLECT :
RAY_DENOISE_SPATIAL_REFRACT));
pass.shader_set(inst_.shaders.static_shader_get(SHADER_VARIATION(RAY_DENOISE_SPATIAL_, type)));
pass.bind_ssbo("tiles_coord_buf", &denoise_tiles_buf_);
pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
pass.bind_texture("depth_tx", &depth_tx);
@ -155,11 +162,11 @@ void RayTraceModule::sync()
pass.dispatch(denoise_dispatch_buf_);
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
for (auto type : IndexRange(2)) {
PassSimple &pass = (type == 0) ? denoise_bilateral_reflect_ps_ : denoise_bilateral_refract_ps_;
for (auto type : IndexRange(3)) {
PassSimple &pass = PASS_VARIATION(denoise_bilateral_, type, _ps_);
pass.init();
pass.shader_set(inst_.shaders.static_shader_get((type == 0) ? RAY_DENOISE_BILATERAL_REFLECT :
RAY_DENOISE_BILATERAL_REFRACT));
pass.shader_set(
inst_.shaders.static_shader_get(SHADER_VARIATION(RAY_DENOISE_BILATERAL_, type)));
pass.bind_texture("depth_tx", &depth_tx);
pass.bind_image("in_radiance_img", &denoised_temporal_tx_);
pass.bind_image("out_radiance_img", &denoised_bilateral_tx_);
@ -172,6 +179,9 @@ void RayTraceModule::sync()
pass.dispatch(denoise_dispatch_buf_);
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
#undef SHADER_VARIATION
#undef PASS_VARIATION
}
void RayTraceModule::debug_pass_sync() {}
@ -190,8 +200,8 @@ RayTraceResult RayTraceModule::trace(RayTraceBuffer &rt_buffer,
{
BLI_assert_msg(count_bits_i(raytrace_closure) == 1,
"Only one closure type can be raytraced at a time.");
BLI_assert_msg(raytrace_closure ==
(raytrace_closure & (CLOSURE_REFLECTION | CLOSURE_REFRACTION)),
BLI_assert_msg(raytrace_closure == (raytrace_closure &
(CLOSURE_REFLECTION | CLOSURE_REFRACTION | CLOSURE_DIFFUSE)),
"Only reflection and refraction are implemented.");
if (tracing_method_ == RAYTRACE_EEVEE_METHOD_NONE) {
@ -207,7 +217,15 @@ RayTraceResult RayTraceModule::trace(RayTraceBuffer &rt_buffer,
PassSimple *denoise_bilateral_ps = nullptr;
RayTraceBuffer::DenoiseBuffer *denoise_buf = nullptr;
if (raytrace_closure == CLOSURE_REFLECTION) {
if (raytrace_closure == CLOSURE_DIFFUSE) {
options = reflection_options_;
generate_ray_ps = &generate_diffuse_ps_;
trace_ray_ps = force_no_tracing ? &trace_diffuse_ps_ : &trace_diffuse_ps_;
denoise_spatial_ps = &denoise_spatial_diffuse_ps_;
denoise_bilateral_ps = &denoise_bilateral_diffuse_ps_;
denoise_buf = &rt_buffer.diffuse;
}
else if (raytrace_closure == CLOSURE_REFLECTION) {
options = reflection_options_;
generate_ray_ps = &generate_reflect_ps_;
trace_ray_ps = force_no_tracing ? &trace_fallback_ps_ : &trace_reflect_ps_;
@ -286,7 +304,7 @@ RayTraceResult RayTraceModule::trace(RayTraceBuffer &rt_buffer,
{
/* Tracing rays. */
ray_data_tx_.acquire(tracing_res, GPU_RGBA16F);
ray_time_tx_.acquire(tracing_res, GPU_R32F);
ray_time_tx_.acquire(tracing_res, RAYTRACE_RAYTIME_FORMAT);
ray_radiance_tx_.acquire(tracing_res, RAYTRACE_RADIANCE_FORMAT);
inst_.manager->submit(*generate_ray_ps, render_view);

View File

@ -54,7 +54,7 @@ struct RayTraceBuffer {
* One for each closure type. Not to be mistaken with deferred layer type.
* For instance the opaque deferred layer will only used the reflection history buffer.
*/
DenoiseBuffer reflection, refraction;
DenoiseBuffer reflection, refraction, diffuse;
};
/**
@ -103,14 +103,18 @@ class RayTraceModule {
draw::PassSimple tile_classify_ps_ = {"TileClassify"};
draw::PassSimple tile_compact_ps_ = {"TileCompact"};
draw::PassSimple generate_diffuse_ps_ = {"RayGenerate.Diffuse"};
draw::PassSimple generate_reflect_ps_ = {"RayGenerate.Reflection"};
draw::PassSimple generate_refract_ps_ = {"RayGenerate.Refraction"};
draw::PassSimple trace_diffuse_ps_ = {"Trace.Diffuse"};
draw::PassSimple trace_reflect_ps_ = {"Trace.Reflection"};
draw::PassSimple trace_refract_ps_ = {"Trace.Refraction"};
draw::PassSimple trace_fallback_ps_ = {"Trace.Fallback"};
draw::PassSimple denoise_spatial_diffuse_ps_ = {"DenoiseSpatial.Diffuse"};
draw::PassSimple denoise_spatial_reflect_ps_ = {"DenoiseSpatial.Reflection"};
draw::PassSimple denoise_spatial_refract_ps_ = {"DenoiseSpatial.Refraction"};
draw::PassSimple denoise_temporal_ps_ = {"DenoiseTemporal"};
draw::PassSimple denoise_bilateral_diffuse_ps_ = {"DenoiseBilateral.Diffuse"};
draw::PassSimple denoise_bilateral_reflect_ps_ = {"DenoiseBilateral.Reflection"};
draw::PassSimple denoise_bilateral_refract_ps_ = {"DenoiseBilateral.Refraction"};

View File

@ -156,22 +156,30 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
return "eevee_light_culling_tile";
case LIGHT_CULLING_ZBIN:
return "eevee_light_culling_zbin";
case RAY_DENOISE_SPATIAL_DIFFUSE:
return "eevee_ray_denoise_spatial_diffuse";
case RAY_DENOISE_SPATIAL_REFLECT:
return "eevee_ray_denoise_spatial_reflect";
case RAY_DENOISE_SPATIAL_REFRACT:
return "eevee_ray_denoise_spatial_refract";
case RAY_DENOISE_TEMPORAL:
return "eevee_ray_denoise_temporal";
case RAY_DENOISE_BILATERAL_DIFFUSE:
return "eevee_ray_denoise_bilateral_diffuse";
case RAY_DENOISE_BILATERAL_REFLECT:
return "eevee_ray_denoise_bilateral_reflect";
case RAY_DENOISE_BILATERAL_REFRACT:
return "eevee_ray_denoise_bilateral_refract";
case RAY_GENERATE_DIFFUSE:
return "eevee_ray_generate_diffuse";
case RAY_GENERATE_REFLECT:
return "eevee_ray_generate_reflect";
case RAY_GENERATE_REFRACT:
return "eevee_ray_generate_refract";
case RAY_TRACE_FALLBACK:
return "eevee_ray_trace_fallback";
case RAY_TRACE_SCREEN_DIFFUSE:
return "eevee_ray_trace_screen_diffuse";
case RAY_TRACE_SCREEN_REFLECT:
return "eevee_ray_trace_screen_reflect";
case RAY_TRACE_SCREEN_REFRACT:

View File

@ -78,16 +78,20 @@ enum eShaderType {
MOTION_BLUR_TILE_FLATTEN_RGBA,
MOTION_BLUR_TILE_FLATTEN_RG,
RAY_DENOISE_BILATERAL_DIFFUSE,
RAY_DENOISE_BILATERAL_REFLECT,
RAY_DENOISE_BILATERAL_REFRACT,
RAY_DENOISE_SPATIAL_DIFFUSE,
RAY_DENOISE_SPATIAL_REFLECT,
RAY_DENOISE_SPATIAL_REFRACT,
RAY_DENOISE_TEMPORAL,
RAY_GENERATE_DIFFUSE,
RAY_GENERATE_REFLECT,
RAY_GENERATE_REFRACT,
RAY_TILE_CLASSIFY,
RAY_TILE_COMPACT,
RAY_TRACE_FALLBACK,
RAY_TRACE_SCREEN_DIFFUSE,
RAY_TRACE_SCREEN_REFLECT,
RAY_TRACE_SCREEN_REFRACT,

View File

@ -173,7 +173,7 @@ vec3 sample_uniform_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf)
{
vec3 tH = sample_uniform_hemisphere(rand);
pdf = sample_pdf_uniform_hemisphere();
return tH * mat3(N, T, B);
return mat3(T, B, N) * tH;
}
/** \} */
@ -200,7 +200,7 @@ vec3 sample_cosine_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf)
{
vec3 tH = sample_cosine_hemisphere(rand);
pdf = sample_pdf_cosine_hemisphere(tH.z);
return tH * mat3(N, T, B);
return mat3(T, B, N) * tH;
}
/** \} */

View File

@ -5,8 +5,7 @@
/**
* Compute light objects lighting contribution using Gbuffer data.
*
* Output light either directly to the radiance buffers or to temporary radiance accumulation
* buffer that will be processed by other deferred lighting passes.
* Output light .
*/
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
@ -42,6 +41,8 @@ void main()
gbuf.thickness,
diffuse_light,
reflection_light,
/* TODO(fclem): Implement refraction light. */
// refraction_light,
shadow);
output_renderpass_value(uniform_buf.render_pass.shadow_id, shadow);

View File

@ -118,7 +118,11 @@ void main()
#endif
gbuffer_load_closure_data(gbuf_closure_tx, texel_fullres, center_closure);
#if defined(RAYTRACE_DIFFUSE)
float roughness = 1.0;
#else
float roughness = center_closure.roughness;
#endif
float variance = imageLoad(in_variance_img, texel_fullres).r;
vec3 in_radiance = imageLoad(in_radiance_img, texel_fullres).rgb;

View File

@ -24,7 +24,9 @@ void main()
GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel_fullres);
#if defined(RAYTRACE_REFLECT)
#if defined(RAYTRACE_DIFFUSE)
bool valid_pixel = gbuf.has_diffuse;
#elif defined(RAYTRACE_REFLECT)
bool valid_pixel = gbuf.has_reflection;
#elif defined(RAYTRACE_REFRACT)
bool valid_pixel = gbuf.has_refraction;
@ -39,7 +41,9 @@ void main()
vec3 V = transform_direction(ViewMatrixInverse, get_view_vector_from_screen_uv(uv));
vec2 noise = utility_tx_fetch(utility_tx, vec2(texel), UTIL_BLUE_NOISE_LAYER).rg;
#if defined(RAYTRACE_REFLECT)
#if defined(RAYTRACE_DIFFUSE)
ClosureDiffuse closure = gbuf.diffuse;
#elif defined(RAYTRACE_REFLECT)
ClosureReflection closure = gbuf.reflection;
#elif defined(RAYTRACE_REFRACT)
ClosureRefraction closure = gbuf.refraction;

View File

@ -45,7 +45,7 @@ void main()
float noise_offset = sampling_rng_1D_get(SAMPLING_RAYTRACE_W);
float rand_trace = interlieved_gradient_noise(vec2(texel), 5.0, noise_offset);
#if defined(RAYTRACE_REFLECT)
#if defined(RAYTRACE_REFLECT) || defined(RAYTRACE_DIFFUSE)
const bool discard_backface = true;
const bool allow_self_intersection = false;
#elif defined(RAYTRACE_REFRACT)

View File

@ -6,6 +6,11 @@
#include "gpu_shader_create_info.hh"
#define EEVEE_RAYTRACE_CLOSURE_VARIATION(name, ...) \
GPU_SHADER_CREATE_INFO(name##_diffuse) \
.do_static_compilation(true) \
.define("RAYTRACE_DIFFUSE") \
.define("CLOSURE_ACTIVE", "eClosureBits(CLOSURE_DIFFUSE)") \
.additional_info(#name); \
GPU_SHADER_CREATE_INFO(name##_reflect) \
.do_static_compilation(true) \
.define("RAYTRACE_REFLECT") \
@ -65,7 +70,7 @@ GPU_SHADER_CREATE_INFO(eevee_ray_trace_fallback)
"draw_view",
"eevee_reflection_probe_data")
.image(0, GPU_RGBA16F, Qualifier::READ, ImageType::FLOAT_2D, "ray_data_img")
.image(1, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_time_img")
.image(1, RAYTRACE_RAYTIME_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_time_img")
.image(2, RAYTRACE_RADIANCE_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_radiance_img")
.sampler(1, ImageType::DEPTH_2D, "depth_tx")
.storage_buf(4, Qualifier::READ, "uint", "tiles_coord_buf[]")
@ -80,7 +85,7 @@ GPU_SHADER_CREATE_INFO(eevee_ray_trace_screen)
"eevee_hiz_data",
"eevee_reflection_probe_data")
.image(0, GPU_RGBA16F, Qualifier::READ, ImageType::FLOAT_2D, "ray_data_img")
.image(1, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_time_img")
.image(1, RAYTRACE_RAYTIME_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_time_img")
.image(2, RAYTRACE_RADIANCE_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_radiance_img")
.sampler(0, ImageType::FLOAT_2D, "screen_radiance_tx")
.sampler(1, ImageType::DEPTH_2D, "depth_tx")
@ -99,7 +104,7 @@ GPU_SHADER_CREATE_INFO(eevee_ray_denoise_spatial)
"eevee_utility_texture")
.sampler(3, ImageType::DEPTH_2D, "depth_tx")
.image(0, GPU_RGBA16F, Qualifier::READ, ImageType::FLOAT_2D, "ray_data_img")
.image(1, GPU_RGBA16F, Qualifier::READ, ImageType::FLOAT_2D, "ray_time_img")
.image(1, RAYTRACE_RAYTIME_FORMAT, Qualifier::READ, ImageType::FLOAT_2D, "ray_time_img")
.image(2, RAYTRACE_RADIANCE_FORMAT, Qualifier::READ, ImageType::FLOAT_2D, "ray_radiance_img")
.image(3, RAYTRACE_RADIANCE_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "out_radiance_img")
.image(4, RAYTRACE_VARIANCE_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "out_variance_img")