From 7c1cb4bd8bfca052de8805a23f324f9eba290d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Wed, 20 Sep 2023 17:52:55 +0200 Subject: [PATCH] EEVEE-Next: Deferred: Add combine pass This allow to move the light evaluation up in the deferred pipeline and avoid coupling two different steps into one. This add more flexibility in the implementation of deferred lighting and indirect lighting algorithms. This splits the reflection probe evaluation to its own shader since it is quite different now. Pull Request: https://projects.blender.org/blender/blender/pulls/112507 --- .../draw/engines/eevee_next/eevee_defines.hh | 1 + .../draw/engines/eevee_next/eevee_gbuffer.hh | 12 +- .../draw/engines/eevee_next/eevee_pipeline.cc | 127 +++++++++--------- .../draw/engines/eevee_next/eevee_raytrace.cc | 12 +- .../engines/eevee_next/eevee_subsurface.cc | 3 +- .../shaders/eevee_deferred_capture_frag.glsl | 48 +------ .../shaders/eevee_deferred_combine_frag.glsl | 28 ++-- .../shaders/eevee_deferred_light_frag.glsl | 42 +----- .../eevee_next/shaders/eevee_gbuffer_lib.glsl | 84 ++++++++++++ .../shaders/eevee_nodetree_lib.glsl | 54 -------- .../eevee_ray_denoise_bilateral_comp.glsl | 16 +-- .../eevee_ray_denoise_spatial_comp.glsl | 54 +++----- .../shaders/eevee_ray_generate_comp.glsl | 40 +----- .../shaders/eevee_ray_tile_classify_comp.glsl | 12 +- .../shaders/eevee_renderpass_lib.glsl | 52 ++++++- .../shaders/eevee_subsurface_eval_frag.glsl | 23 ++-- .../shaders/eevee_surf_deferred_frag.glsl | 87 ++++++------ .../shaders/eevee_surf_forward_frag.glsl | 1 + .../shaders/eevee_surf_world_frag.glsl | 1 + .../shaders/infos/eevee_deferred_info.hh | 18 ++- .../shaders/infos/eevee_material_info.hh | 5 +- .../shaders/infos/eevee_subsurface_info.hh | 7 +- .../shaders/infos/eevee_tracing_info.hh | 19 +-- 23 files changed, 360 insertions(+), 386 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index f8c5a36c0cf..baf2cb390b6 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -144,6 +144,7 @@ #define RBUFS_CRYPTOMATTE_SLOT 2 #define GBUF_CLOSURE_SLOT 3 #define GBUF_COLOR_SLOT 4 +#define GBUF_HEADER_SLOT 5 /* Volume properties pass do not write to `rbufs`. Reuse the same bind points. */ #define VOLUME_PROP_SCATTERING_IMG_SLOT 0 #define VOLUME_PROP_EXTINCTION_IMG_SLOT 1 diff --git a/source/blender/draw/engines/eevee_next/eevee_gbuffer.hh b/source/blender/draw/engines/eevee_next/eevee_gbuffer.hh index df8ecde7296..b89c1e71060 100644 --- a/source/blender/draw/engines/eevee_next/eevee_gbuffer.hh +++ b/source/blender/draw/engines/eevee_next/eevee_gbuffer.hh @@ -68,7 +68,8 @@ class Instance; * Color degradation is expected to happen in this case. */ struct GBuffer { - /* TODO(fclem): Use texture from pool once they support texture array. */ + /* TODO(fclem): Use texture from pool once they support texture array and layer views. */ + Texture header_tx = {"GbufferHeader"}; Texture closure_tx = {"GbufferClosure"}; Texture color_tx = {"GbufferColor"}; @@ -76,6 +77,7 @@ struct GBuffer { { const bool use_sss = (closure_bits_ & CLOSURE_SSS) != 0; eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_SHADER_WRITE; + header_tx.ensure_2d(GPU_R8UI, extent, usage); closure_tx.ensure_2d_array(GPU_RGBA16, extent, use_sss ? 3 : 2, usage); color_tx.ensure_2d_array(GPU_RGB10_A2, extent, 2, usage); } @@ -83,9 +85,17 @@ struct GBuffer { void release() { /* TODO(fclem): Use texture from pool once they support texture array. */ + // header_tx.release(); // closure_tx.release(); // color_tx.release(); } + + template void bind_resources(draw::detail::PassBase *pass) + { + pass->bind_texture("gbuf_header_tx", &header_tx); + pass->bind_texture("gbuf_closure_tx", &closure_tx); + pass->bind_texture("gbuf_color_tx", &color_tx); + } }; } // namespace blender::eevee diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc index 0e20979b4f4..aae894e6eae 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc @@ -392,6 +392,7 @@ void DeferredLayer::begin_sync() /* G-buffer. */ gbuffer_ps_.bind_image(GBUF_CLOSURE_SLOT, &inst_.gbuffer.closure_tx); gbuffer_ps_.bind_image(GBUF_COLOR_SLOT, &inst_.gbuffer.color_tx); + gbuffer_ps_.bind_image(GBUF_HEADER_SLOT, &inst_.gbuffer.header_tx); /* RenderPasses & AOVs. */ gbuffer_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); gbuffer_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); @@ -424,44 +425,48 @@ void DeferredLayer::end_sync() { eClosureBits evaluated_closures = CLOSURE_DIFFUSE | CLOSURE_REFLECTION | CLOSURE_REFRACTION; if (closure_bits_ & evaluated_closures) { - eval_light_ps_.init(); - /* Use stencil test to reject pixel not written by this layer. */ - eval_light_ps_.state_set(DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); - eval_light_ps_.state_stencil(0x00u, 0x00u, evaluated_closures); - eval_light_ps_.shader_set(inst_.shaders.static_shader_get(DEFERRED_LIGHT)); - eval_light_ps_.bind_image("direct_diffuse_img", &direct_diffuse_tx_); - eval_light_ps_.bind_image("direct_reflect_img", &direct_reflect_tx_); - eval_light_ps_.bind_image("direct_refract_img", &direct_refract_tx_); - eval_light_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - eval_light_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); - eval_light_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); - inst_.bind_uniform_data(&eval_light_ps_); - inst_.lights.bind_resources(&eval_light_ps_); - inst_.shadows.bind_resources(&eval_light_ps_); - inst_.sampling.bind_resources(&eval_light_ps_); - inst_.hiz_buffer.bind_resources(&eval_light_ps_); - eval_light_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); - eval_light_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); - - combine_ps_.init(); - /* Use stencil test to reject pixel not written by this layer. */ - combine_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL | DRW_STATE_BLEND_ADD); - combine_ps_.state_stencil(0x00u, 0x00u, evaluated_closures); - combine_ps_.shader_set(inst_.shaders.static_shader_get(DEFERRED_COMBINE)); - combine_ps_.bind_image("direct_diffuse_img", &direct_diffuse_tx_); - combine_ps_.bind_image("direct_reflect_img", &direct_reflect_tx_); - combine_ps_.bind_image("direct_refract_img", &direct_refract_tx_); - combine_ps_.bind_image("indirect_diffuse_img", &indirect_diffuse_tx_); - combine_ps_.bind_image("indirect_reflect_img", &indirect_reflect_tx_); - combine_ps_.bind_image("indirect_refract_img", &indirect_refract_tx_); - combine_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - combine_ps_.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx); - combine_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); - combine_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); - inst_.bind_uniform_data(&combine_ps_); - combine_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); - combine_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + { + PassSimple &pass = eval_light_ps_; + pass.init(); + /* Use stencil test to reject pixel not written by this layer. */ + pass.state_set(DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); + pass.state_stencil(0x00u, 0x00u, evaluated_closures); + pass.shader_set(inst_.shaders.static_shader_get(DEFERRED_LIGHT)); + pass.bind_image("direct_diffuse_img", &direct_diffuse_tx_); + pass.bind_image("direct_reflect_img", &direct_reflect_tx_); + pass.bind_image("direct_refract_img", &direct_refract_tx_); + pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); + pass.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); + pass.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); + inst_.bind_uniform_data(&pass); + inst_.gbuffer.bind_resources(&pass); + inst_.lights.bind_resources(&pass); + inst_.shadows.bind_resources(&pass); + inst_.sampling.bind_resources(&pass); + inst_.hiz_buffer.bind_resources(&pass); + pass.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); + pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); + } + { + PassSimple &pass = combine_ps_; + pass.init(); + /* Use stencil test to reject pixel not written by this layer. */ + pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL | DRW_STATE_BLEND_ADD_FULL); + pass.state_stencil(0x00u, 0x00u, evaluated_closures); + pass.shader_set(inst_.shaders.static_shader_get(DEFERRED_COMBINE)); + pass.bind_image("direct_diffuse_img", &direct_diffuse_tx_); + pass.bind_image("direct_reflect_img", &direct_reflect_tx_); + pass.bind_image("direct_refract_img", &direct_refract_tx_); + pass.bind_image("indirect_diffuse_img", &indirect_diffuse_tx_); + pass.bind_image("indirect_reflect_img", &indirect_reflect_tx_); + pass.bind_image("indirect_refract_img", &indirect_refract_tx_); + pass.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); + pass.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); + inst_.gbuffer.bind_resources(&pass); + inst_.bind_uniform_data(&pass); + pass.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); + pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); + } } } @@ -550,6 +555,9 @@ void DeferredLayer::render(View &main_view, } } + /* TODO(fclem): Clear in pass when Gbuffer will render with framebuffer. */ + inst_.gbuffer.header_tx.clear(uint4(0)); + GPU_framebuffer_bind(combined_fb); inst_.manager->submit(gbuffer_ps_, render_view); @@ -748,6 +756,7 @@ void DeferredProbeLayer::begin_sync() /* G-buffer. */ gbuffer_ps_.bind_image(GBUF_CLOSURE_SLOT, &inst_.gbuffer.closure_tx); gbuffer_ps_.bind_image(GBUF_COLOR_SLOT, &inst_.gbuffer.color_tx); + gbuffer_ps_.bind_image(GBUF_HEADER_SLOT, &inst_.gbuffer.header_tx); /* RenderPasses & AOVs. */ gbuffer_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); gbuffer_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); @@ -783,31 +792,25 @@ void DeferredProbeLayer::begin_sync() void DeferredProbeLayer::end_sync() { if (closure_bits_ & (CLOSURE_DIFFUSE | CLOSURE_REFLECTION)) { - const bool is_last_eval_pass = !(closure_bits_ & CLOSURE_SSS); - - eval_light_ps_.init(); + PassSimple &pass = eval_light_ps_; + pass.init(); /* Use stencil test to reject pixel not written by this layer. */ - eval_light_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL | - DRW_STATE_BLEND_CUSTOM); - eval_light_ps_.state_stencil(0x00u, 0x00u, (CLOSURE_DIFFUSE | CLOSURE_REFLECTION)); - eval_light_ps_.shader_set(inst_.shaders.static_shader_get(DEFERRED_CAPTURE_EVAL)); - eval_light_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - eval_light_ps_.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx); - eval_light_ps_.push_constant("is_last_eval_pass", is_last_eval_pass); - eval_light_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); - eval_light_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); - eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - - inst_.bind_uniform_data(&eval_light_ps_); - inst_.lights.bind_resources(&eval_light_ps_); - inst_.shadows.bind_resources(&eval_light_ps_); - inst_.sampling.bind_resources(&eval_light_ps_); - inst_.hiz_buffer.bind_resources(&eval_light_ps_); - inst_.reflection_probes.bind_resources(&eval_light_ps_); - inst_.irradiance_cache.bind_resources(&eval_light_ps_); - - eval_light_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); - eval_light_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL); + pass.state_stencil(0x00u, 0x00u, (CLOSURE_DIFFUSE | CLOSURE_REFLECTION)); + pass.shader_set(inst_.shaders.static_shader_get(DEFERRED_CAPTURE_EVAL)); + pass.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); + pass.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); + pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); + inst_.bind_uniform_data(&pass); + inst_.gbuffer.bind_resources(&pass); + inst_.lights.bind_resources(&pass); + inst_.shadows.bind_resources(&pass); + inst_.sampling.bind_resources(&pass); + inst_.hiz_buffer.bind_resources(&pass); + inst_.reflection_probes.bind_resources(&pass); + inst_.irradiance_cache.bind_resources(&pass); + pass.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); + pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); } } diff --git a/source/blender/draw/engines/eevee_next/eevee_raytrace.cc b/source/blender/draw/engines/eevee_next/eevee_raytrace.cc index 291fabbd8c4..c3230442b1a 100644 --- a/source/blender/draw/engines/eevee_next/eevee_raytrace.cc +++ b/source/blender/draw/engines/eevee_next/eevee_raytrace.cc @@ -46,12 +46,11 @@ void RayTraceModule::sync() PassSimple &pass = tile_classify_ps_; pass.init(); pass.shader_set(inst_.shaders.static_shader_get(RAY_TILE_CLASSIFY)); - pass.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - pass.bind_texture("stencil_tx", &renderbuf_stencil_view_); pass.bind_image("tile_mask_img", &tile_mask_tx_); pass.bind_ssbo("ray_dispatch_buf", &ray_dispatch_buf_); pass.bind_ssbo("denoise_dispatch_buf", &denoise_dispatch_buf_); inst_.bind_uniform_data(&pass); + inst_.gbuffer.bind_resources(&pass); pass.dispatch(&tile_classify_dispatch_size_); pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS | GPU_BARRIER_SHADER_STORAGE); } @@ -74,12 +73,10 @@ void RayTraceModule::sync() pass.shader_set(inst_.shaders.static_shader_get((type == 0) ? RAY_GENERATE_REFLECT : RAY_GENERATE_REFRACT)); pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - pass.bind_texture("stencil_tx", &renderbuf_stencil_view_); - pass.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - pass.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx); pass.bind_image("out_ray_data_img", &ray_data_tx_); pass.bind_ssbo("tiles_coord_buf", &ray_tiles_buf_); inst_.sampling.bind_resources(&pass); + inst_.gbuffer.bind_resources(&pass); pass.dispatch(ray_dispatch_buf_); pass.barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); @@ -125,8 +122,6 @@ void RayTraceModule::sync() RAY_DENOISE_SPATIAL_REFRACT)); pass.bind_ssbo("tiles_coord_buf", &denoise_tiles_buf_); pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - pass.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - pass.bind_texture("stencil_tx", &renderbuf_stencil_view_); pass.bind_texture("depth_tx", &depth_tx); pass.bind_image("ray_data_img", &ray_data_tx_); pass.bind_image("ray_time_img", &ray_time_tx_); @@ -137,6 +132,7 @@ void RayTraceModule::sync() pass.bind_image("tile_mask_img", &tile_mask_tx_); inst_.bind_uniform_data(&pass); inst_.sampling.bind_resources(&pass); + inst_.gbuffer.bind_resources(&pass); pass.dispatch(denoise_dispatch_buf_); pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS); } @@ -164,7 +160,6 @@ void RayTraceModule::sync() pass.init(); pass.shader_set(inst_.shaders.static_shader_get((type == 0) ? RAY_DENOISE_BILATERAL_REFLECT : RAY_DENOISE_BILATERAL_REFRACT)); - pass.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); 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_); @@ -173,6 +168,7 @@ void RayTraceModule::sync() pass.bind_ssbo("tiles_coord_buf", &denoise_tiles_buf_); inst_.bind_uniform_data(&pass); inst_.sampling.bind_resources(&pass); + inst_.gbuffer.bind_resources(&pass); pass.dispatch(denoise_dispatch_buf_); pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS); } diff --git a/source/blender/draw/engines/eevee_next/eevee_subsurface.cc b/source/blender/draw/engines/eevee_next/eevee_subsurface.cc index 619459f9e91..28a92d85f73 100644 --- a/source/blender/draw/engines/eevee_next/eevee_subsurface.cc +++ b/source/blender/draw/engines/eevee_next/eevee_subsurface.cc @@ -36,9 +36,8 @@ void SubsurfaceModule::end_sync() subsurface_ps_.shader_set(inst_.shaders.static_shader_get(SUBSURFACE_EVAL)); inst_.bind_uniform_data(&subsurface_ps_); inst_.hiz_buffer.bind_resources(&subsurface_ps_); + inst_.gbuffer.bind_resources(&subsurface_ps_); subsurface_ps_.bind_texture("radiance_tx", &diffuse_light_tx_); - subsurface_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); - subsurface_ps_.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx); subsurface_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); /** NOTE: Not used in the shader, but we bind it to avoid debug warnings. */ subsurface_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_capture_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_capture_frag.glsl index 91168753891..813d2f13dcc 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_capture_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_capture_frag.glsl @@ -21,61 +21,27 @@ void main() vec3 V = cameraVec(P); float vP_z = dot(cameraForward, P) - dot(cameraForward, cameraPos); - vec4 gbuffer_0_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 0), 0); - vec4 gbuffer_1_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel); - ClosureReflection reflection_data; - reflection_data.N = gbuffer_normal_unpack(gbuffer_0_packed.xy); - reflection_data.roughness = gbuffer_0_packed.z; - - ClosureDiffuse diffuse_data; - diffuse_data.N = gbuffer_normal_unpack(gbuffer_1_packed.xy); - /* These are only set for SSS case. */ - diffuse_data.sss_radius = vec3(0.0); - diffuse_data.sss_id = 0u; - float thickness = 0.0; - - ClosureRefraction refraction_data; - refraction_data.N = diffuse_data.N; - refraction_data.roughness = gbuffer_1_packed.z; - refraction_data.ior = 0.0; /* Not needed. */ - - bool is_refraction = gbuffer_is_refraction(gbuffer_1_packed); - if (is_refraction) { - /* Still evaluate the diffuse light so that dithered SSS / Refraction combination still - * produces a complete diffuse light buffer that will be correctly convolved by the SSSS. - * The refraction pixels will just set the diffuse radiance to 0. */ - } - else if (textureSize(gbuffer_closure_tx, 0).z >= 3) { - vec4 gbuffer_2_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 2), 0); - diffuse_data.sss_radius = gbuffer_sss_radii_unpack(gbuffer_2_packed.xyz); - diffuse_data.sss_id = gbuffer_object_id_unorm16_unpack(gbuffer_2_packed.w); - thickness = gbuffer_thickness_unpack(gbuffer_1_packed.z); - } - - vec3 Ng = diffuse_data.N; + vec3 Ng = gbuf.diffuse.N; vec3 diffuse_light = vec3(0.0); vec3 unused_reflection_light = vec3(0.0); vec3 unused_refraction_light = vec3(0.0); float unused_shadow = 1.0; - light_eval(diffuse_data, - reflection_data, + light_eval(gbuf.diffuse, + gbuf.reflection, P, Ng, V, vP_z, - thickness, + gbuf.thickness, diffuse_light, unused_reflection_light, unused_shadow); - /* Apply color and output lighting to render-passes. */ - vec4 color_0_packed = texelFetch(gbuffer_color_tx, ivec3(texel, 0), 0); - vec4 color_1_packed = texelFetch(gbuffer_color_tx, ivec3(texel, 1), 0); + vec3 albedo = gbuf.diffuse.color + gbuf.reflection.color + gbuf.refraction.color; - vec3 albedo_color = gbuffer_color_unpack(color_0_packed) + gbuffer_color_unpack(color_1_packed); - - out_radiance = vec4(diffuse_light * albedo_color, 0.0); + out_radiance = vec4(diffuse_light * albedo, 0.0); } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_combine_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_combine_frag.glsl index 65b43cd7324..24be6ede092 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_combine_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_combine_frag.glsl @@ -21,24 +21,18 @@ void main() vec3 refract_light = imageLoad(direct_refract_img, texel).rgb + imageLoad(indirect_refract_img, texel).rgb; - /* Apply color and output lighting to render-passes. */ - vec4 gbuffer_1_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); - bool is_refraction = gbuffer_is_refraction(gbuffer_1_packed); - - vec4 color_0_packed = texelFetch(gbuffer_color_tx, ivec3(texel, 0), 0); - vec4 color_1_packed = texelFetch(gbuffer_color_tx, ivec3(texel, 1), 0); - - vec3 reflection_color = gbuffer_color_unpack(color_0_packed); - vec3 refraction_color = is_refraction ? gbuffer_color_unpack(color_1_packed) : vec3(0.0); - vec3 diffuse_color = is_refraction ? vec3(0.0) : gbuffer_color_unpack(color_1_packed); - + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel); + /* Mask invalid radiance. */ + diffuse_light = gbuf.has_diffuse ? diffuse_light : vec3(0.0); + reflect_light = gbuf.has_reflection ? reflect_light : vec3(0.0); + refract_light = gbuf.has_refraction ? refract_light : vec3(0.0); /* Light passes. */ vec3 specular_light = reflect_light + refract_light; - render_pass_color_out(uniform_buf.render_pass.diffuse_light_id, diffuse_light); - render_pass_color_out(uniform_buf.render_pass.specular_light_id, specular_light); - + output_renderpass_color(uniform_buf.render_pass.diffuse_light_id, vec4(diffuse_light, 1.0)); + output_renderpass_color(uniform_buf.render_pass.specular_light_id, vec4(specular_light, 1.0)); + /* Combine. */ out_combined = vec4(0.0); - out_combined.xyz += diffuse_light * diffuse_color; - out_combined.xyz += reflect_light * reflection_color; - out_combined.xyz += refract_light * refraction_color; + out_combined.xyz += diffuse_light * gbuf.diffuse.color; + out_combined.xyz += reflect_light * gbuf.reflection.color; + out_combined.xyz += refract_light * gbuf.refraction.color; } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl index 5594f12e192..06dc34280a2 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl @@ -26,59 +26,29 @@ void main() vec3 V = cameraVec(P); float vP_z = dot(cameraForward, P) - dot(cameraForward, cameraPos); - vec4 gbuffer_0_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 0), 0); - vec4 gbuffer_1_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); - - ClosureReflection reflection_data; - reflection_data.N = gbuffer_normal_unpack(gbuffer_0_packed.xy); - reflection_data.roughness = gbuffer_0_packed.z; - - ClosureDiffuse diffuse_data; - diffuse_data.N = gbuffer_normal_unpack(gbuffer_1_packed.xy); - /* These are only set for SSS case. */ - diffuse_data.sss_radius = vec3(0.0); - diffuse_data.sss_id = 0u; - float thickness = 0.0; - - ClosureRefraction refraction_data; - refraction_data.N = diffuse_data.N; - refraction_data.roughness = gbuffer_1_packed.z; - refraction_data.ior = 0.0; /* Not needed. */ - - bool is_refraction = gbuffer_is_refraction(gbuffer_1_packed); - if (is_refraction) { - /* Still evaluate the diffuse light so that dithered SSS / Refraction combination still - * produces a complete diffuse light buffer that will be correctly convolved by the SSSS. - * The refraction pixels will just set the diffuse radiance to 0. */ - } - else if (textureSize(gbuffer_closure_tx, 0).z >= 3) { - vec4 gbuffer_2_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 2), 0); - diffuse_data.sss_radius = gbuffer_sss_radii_unpack(gbuffer_2_packed.xyz); - diffuse_data.sss_id = gbuffer_object_id_unorm16_unpack(gbuffer_2_packed.w); - thickness = gbuffer_thickness_unpack(gbuffer_1_packed.z); - } + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel); vec3 diffuse_light = vec3(0.0); vec3 reflection_light = vec3(0.0); vec3 refraction_light = vec3(0.0); float shadow = 1.0; - light_eval(diffuse_data, - reflection_data, + light_eval(gbuf.diffuse, + gbuf.reflection, P, Ng, V, vP_z, - thickness, + gbuf.thickness, diffuse_light, reflection_light, shadow); - render_pass_value_out(uniform_buf.render_pass.shadow_id, shadow); + output_renderpass_value(uniform_buf.render_pass.shadow_id, shadow); /* Store lighting for next deferred pass. */ /* Output object ID for sub-surface screen space processing. */ - float f_sss_id = gbuffer_object_id_f16_pack(diffuse_data.sss_id); + float f_sss_id = gbuffer_object_id_f16_pack(gbuf.diffuse.sss_id); imageStore(direct_diffuse_img, texel, vec4(diffuse_light, f_sss_id)); imageStore(direct_reflect_img, texel, vec4(reflection_light, 1.0)); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_gbuffer_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_gbuffer_lib.glsl index e4f45b6bbcf..f5546da7338 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_gbuffer_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_gbuffer_lib.glsl @@ -9,6 +9,8 @@ */ #pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl) vec2 gbuffer_normal_pack(vec3 N) { @@ -110,3 +112,85 @@ bool gbuffer_is_refraction(vec4 gbuffer) { return gbuffer.w < 1.0; } + +struct GBufferData { + ClosureDiffuse diffuse; + ClosureReflection reflection; + ClosureRefraction refraction; + float thickness; + bool has_diffuse; + bool has_reflection; + bool has_refraction; +}; + +GBufferData gbuffer_read(usampler2D header_tx, + sampler2DArray closure_tx, + sampler2DArray color_tx, + ivec2 texel) +{ + GBufferData gbuf; + + uint header = texelFetch(header_tx, texel, 0).r; + + gbuf.thickness = 0.0; + gbuf.has_diffuse = flag_test(header, CLOSURE_DIFFUSE); + gbuf.has_reflection = flag_test(header, CLOSURE_REFLECTION); + gbuf.has_refraction = flag_test(header, CLOSURE_REFRACTION); + + if (gbuf.has_reflection) { + int layer = 0; + vec4 closure_packed = texelFetch(closure_tx, ivec3(texel, layer), 0); + gbuf.reflection.N = gbuffer_normal_unpack(closure_packed.xy); + gbuf.reflection.roughness = closure_packed.z; + + vec4 color_packed = texelFetch(color_tx, ivec3(texel, layer), 0); + gbuf.reflection.color = gbuffer_color_unpack(color_packed); + } + else { + gbuf.reflection.N = vec3(0.0, 0.0, 1.0); + gbuf.reflection.roughness = 0.0; + gbuf.reflection.color = vec3(0.0); + } + + if (gbuf.has_diffuse) { + int layer = 1; + vec4 closure_packed = texelFetch(closure_tx, ivec3(texel, layer), 0); + gbuf.diffuse.N = gbuffer_normal_unpack(closure_packed.xy); + gbuf.diffuse.sss_id = 0u; + gbuf.thickness = gbuffer_thickness_unpack(closure_packed.z); + + vec4 color_packed = texelFetch(color_tx, ivec3(texel, layer), 0); + gbuf.diffuse.color = gbuffer_color_unpack(color_packed); + + if (flag_test(header, CLOSURE_SSS)) { + int layer = 2; + vec4 closure_packed = texelFetch(closure_tx, ivec3(texel, layer), 0); + gbuf.diffuse.sss_radius = gbuffer_sss_radii_unpack(closure_packed.xyz); + gbuf.diffuse.sss_id = gbuffer_object_id_unorm16_unpack(closure_packed.w); + } + } + else { + gbuf.diffuse.N = vec3(0.0, 0.0, 1.0); + gbuf.diffuse.sss_id = 0u; + gbuf.diffuse.color = vec3(0.0); + } + + if (gbuf.has_refraction) { + int layer = 1; + vec4 closure_packed = texelFetch(closure_tx, ivec3(texel, layer), 0); + gbuf.refraction.N = gbuffer_normal_unpack(closure_packed.xy); + gbuf.refraction.roughness = closure_packed.z; + gbuf.refraction.ior = gbuffer_ior_unpack(closure_packed.w); + + vec4 color_packed = texelFetch(color_tx, ivec3(texel, layer), 0); + gbuf.refraction.color = gbuffer_color_unpack(color_packed); + } + else { + gbuf.refraction.N = vec3(0.0, 0.0, 1.0); + gbuf.refraction.ior = 1.1; + gbuf.refraction.roughness = 0.0; + gbuf.refraction.color = vec3(0.0); + } + + return gbuf; +} diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl index 99c882990ff..36607db1b51 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl @@ -367,60 +367,6 @@ vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter #endif } -void output_renderpass_color(int id, vec4 color) -{ -#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) - if (id >= 0) { - ivec2 texel = ivec2(gl_FragCoord.xy); - imageStore(rp_color_img, ivec3(texel, id), color); - } -#endif -} - -void output_renderpass_value(int id, float value) -{ -#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) - if (id >= 0) { - ivec2 texel = ivec2(gl_FragCoord.xy); - imageStore(rp_value_img, ivec3(texel, id), vec4(value)); - } -#endif -} - -void clear_aovs() -{ -#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) - for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.color_len; i++) { - output_renderpass_color(uniform_buf.render_pass.color_len + i, vec4(0)); - } - for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.value_len; i++) { - output_renderpass_value(uniform_buf.render_pass.value_len + i, 0.0); - } -#endif -} - -void output_aov(vec4 color, float value, uint hash) -{ -#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) - for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.color_len; i++) { - if (uniform_buf.render_pass.aovs.hash_color[i].x == hash) { - imageStore(rp_color_img, - ivec3(ivec2(gl_FragCoord.xy), uniform_buf.render_pass.color_len + i), - color); - return; - } - } - for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.value_len; i++) { - if (uniform_buf.render_pass.aovs.hash_value[i].x == hash) { - imageStore(rp_value_img, - ivec3(ivec2(gl_FragCoord.xy), uniform_buf.render_pass.value_len + i), - vec4(value)); - return; - } - } -#endif -} - #ifdef EEVEE_MATERIAL_STUBS # define attrib_load() # define nodetree_displacement() vec3(0.0) diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_bilateral_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_bilateral_comp.glsl index 3b376bf0af6..6c556f60697 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_bilateral_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_bilateral_comp.glsl @@ -61,20 +61,20 @@ vec3 from_accumulation_space(vec3 color) return color / (1.0 - dot(color, vec3(1.0))); } -void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, +void gbuffer_load_closure_data(sampler2DArray gbuf_closure_tx, ivec2 texel, out ClosureDiffuse closure) { - vec4 data_in = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); + vec4 data_in = texelFetch(gbuf_closure_tx, ivec3(texel, 1), 0); closure.N = gbuffer_normal_unpack(data_in.xy); } -void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, +void gbuffer_load_closure_data(sampler2DArray gbuf_closure_tx, ivec2 texel, out ClosureRefraction closure) { - vec4 data_in = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); + vec4 data_in = texelFetch(gbuf_closure_tx, ivec3(texel, 1), 0); closure.N = gbuffer_normal_unpack(data_in.xy); if (gbuffer_is_refraction(data_in)) { @@ -87,11 +87,11 @@ void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, } } -void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, +void gbuffer_load_closure_data(sampler2DArray gbuf_closure_tx, ivec2 texel, out ClosureReflection closure) { - vec4 data_in = texelFetch(gbuffer_closure_tx, ivec3(texel, 0), 0); + vec4 data_in = texelFetch(gbuf_closure_tx, ivec3(texel, 0), 0); closure.N = gbuffer_normal_unpack(data_in.xy); closure.roughness = data_in.z; @@ -116,7 +116,7 @@ void main() #else # error #endif - gbuffer_load_closure_data(gbuffer_closure_tx, texel_fullres, center_closure); + gbuffer_load_closure_data(gbuf_closure_tx, texel_fullres, center_closure); float roughness = center_closure.roughness; @@ -168,7 +168,7 @@ void main() continue; } - gbuffer_load_closure_data(gbuffer_closure_tx, sample_texel, sample_closure); + gbuffer_load_closure_data(gbuf_closure_tx, sample_texel, sample_closure); float depth_weight = bilateral_depth_weight(center_closure.N, center_P, sample_P); float spatial_weight = bilateral_spatial_weight(filter_size, vec2(offset)); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_spatial_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_spatial_comp.glsl index f3a6e4f02e5..4417ec9a3ca 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_spatial_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_denoise_spatial_comp.glsl @@ -22,40 +22,22 @@ #pragma BLENDER_REQUIRE(eevee_bxdf_lib.glsl) #pragma BLENDER_REQUIRE(common_view_lib.glsl) -void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, +void gbuffer_load_closure_data(sampler2DArray gbuf_closure_tx, ivec2 texel, out ClosureDiffuse closure) { - vec4 data_in = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); - - closure.N = gbuffer_normal_unpack(data_in.xy); } -void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, +void gbuffer_load_closure_data(sampler2DArray gbuf_closure_tx, ivec2 texel, out ClosureRefraction closure) { - vec4 data_in = texelFetch(gbuffer_closure_tx, ivec3(texel, 1), 0); - - closure.N = gbuffer_normal_unpack(data_in.xy); - if (gbuffer_is_refraction(data_in)) { - closure.roughness = data_in.z; - closure.ior = gbuffer_ior_unpack(data_in.w); - } - else { - closure.roughness = 1.0; - closure.ior = 1.1; - } } -void gbuffer_load_closure_data(sampler2DArray gbuffer_closure_tx, +void gbuffer_load_closure_data(sampler2DArray gbuf_closure_tx, ivec2 texel, out ClosureReflection closure) { - vec4 data_in = texelFetch(gbuffer_closure_tx, ivec3(texel, 0), 0); - - closure.N = gbuffer_normal_unpack(data_in.xy); - closure.roughness = data_in.z; } float bxdf_eval(ClosureDiffuse closure, vec3 L, vec3 V) @@ -88,19 +70,6 @@ bool neighbor_tile_mask_bit_get(uint tile_mask, ivec2 offset) return flag_test(tile_mask, 1u << shift); } -#if defined(RAYTRACE_DIFFUSE) -# define ClosureT ClosureDiffuse -# define CLOSURE_ACTIVE eClosureBits(CLOSURE_DIFFUSE) -#elif defined(RAYTRACE_REFRACT) -# define ClosureT ClosureRefraction -# define CLOSURE_ACTIVE eClosureBits(CLOSURE_REFRACTION) -#elif defined(RAYTRACE_REFLECT) -# define ClosureT ClosureReflection -# define CLOSURE_ACTIVE eClosureBits(CLOSURE_REFLECTION) -#else -# error -#endif - void main() { const uint tile_size = RAYTRACE_GROUP_SIZE; @@ -143,8 +112,8 @@ void main() } } - bool valid_texel = in_texture_range(texel_fullres, stencil_tx); - uint closure_bits = (!valid_texel) ? 0u : texelFetch(stencil_tx, texel_fullres, 0).r; + bool valid_texel = in_texture_range(texel_fullres, gbuf_header_tx); + uint closure_bits = (!valid_texel) ? 0u : texelFetch(gbuf_header_tx, texel_fullres, 0).r; if (!flag_test(closure_bits, CLOSURE_ACTIVE)) { imageStore(out_radiance_img, texel_fullres, vec4(FLT_11_11_10_MAX, 0.0)); imageStore(out_variance_img, texel_fullres, vec4(0.0)); @@ -155,8 +124,17 @@ void main() vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv; vec3 V = transform_direction(ViewMatrixInverse, get_view_vector_from_screen_uv(uv)); - ClosureT closure; - gbuffer_load_closure_data(gbuffer_closure_tx, texel_fullres, closure); + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel_fullres); + +#if defined(RAYTRACE_DIFFUSE) + ClosureDiffuse closure = gbuf.diffuse; +#elif defined(RAYTRACE_REFRACT) + ClosureRefraction closure = gbuf.refraction; +#elif defined(RAYTRACE_REFLECT) + ClosureReflection closure = gbuf.reflection; +#else +# error +#endif uint sample_count = 16u; float filter_size = 9.0; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_generate_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_generate_comp.glsl index 03b2ebeef5c..c0b28e5de5d 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_generate_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_generate_comp.glsl @@ -22,58 +22,32 @@ void main() ivec2 texel_fullres = texel * uniform_buf.raytrace.resolution_scale + uniform_buf.raytrace.resolution_bias; - bool valid_texel = in_texture_range(texel_fullres, stencil_tx); - uint closure_bits = (!valid_texel) ? 0u : texelFetch(stencil_tx, texel_fullres, 0).r; + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel_fullres); #if defined(RAYTRACE_REFLECT) - ClosureReflection closure; - eClosureBits closure_active = CLOSURE_REFLECTION; - const int gbuf_layer = 0; + bool valid_pixel = gbuf.has_reflection; #elif defined(RAYTRACE_REFRACT) - ClosureRefraction closure; - eClosureBits closure_active = CLOSURE_REFRACTION; - const int gbuf_layer = 1; + bool valid_pixel = gbuf.has_refraction; #endif - if (!flag_test(closure_bits, closure_active)) { + if (!valid_pixel) { imageStore(out_ray_data_img, texel, vec4(0.0)); return; } - vec2 uv = (vec2(texel_fullres) + 0.5) / vec2(textureSize(stencil_tx, 0).xy); + vec2 uv = (vec2(texel_fullres) + 0.5) / vec2(textureSize(gbuf_header_tx, 0).xy); 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; - /* Load GBuffer data. */ - vec4 gbuffer_packed = texelFetch(gbuffer_closure_tx, ivec3(texel_fullres, gbuf_layer), 0); - - closure.N = gbuffer_normal_unpack(gbuffer_packed.xy); - #if defined(RAYTRACE_REFLECT) - closure.roughness = gbuffer_packed.z; - + ClosureReflection closure = gbuf.reflection; #elif defined(RAYTRACE_REFRACT) - if (gbuffer_is_refraction(gbuffer_packed)) { - closure.roughness = gbuffer_packed.z; - closure.ior = gbuffer_ior_unpack(gbuffer_packed.w); - } - else { - /* Avoid producing incorrect ray directions. */ - closure.ior = 1.1; - closure.roughness = 0.0; - } + ClosureRefraction closure = gbuf.refraction; #endif float pdf; vec3 ray_direction = ray_generate_direction(noise.xy, closure, V, pdf); -#if defined(RAYTRACE_REFRACT) - if (gbuffer_is_refraction(gbuffer_packed) && closure_active != CLOSURE_REFRACTION) { - /* Discard incorrect rays. */ - pdf = 0.0; - } -#endif - /* Store inverse pdf to speedup denoising. * Limit to the smallest non-0 value that the format can encode. * Strangely it does not correspond to the IEEE spec. */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_tile_classify_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_tile_classify_comp.glsl index 4e90cf032dd..b8523b010e1 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_ray_tile_classify_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_ray_tile_classify_comp.glsl @@ -40,15 +40,17 @@ void main() barrier(); - ivec2 texel = min(ivec2(gl_GlobalInvocationID.xy), textureSize(stencil_tx, 0) - 1); + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); - eClosureBits closure_bits = eClosureBits(texelFetch(stencil_tx, texel, 0).r); + bool valid_texel = in_texture_range(texel, gbuf_header_tx); + uint closure_bits = (!valid_texel) ? 0u : texelFetch(gbuf_header_tx, texel, 0).r; if (flag_test(closure_bits, uniform_buf.raytrace.closure_active)) { - int gbuffer_layer = uniform_buf.raytrace.closure_active == CLOSURE_REFRACTION ? 1 : 0; + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel); - vec4 gbuffer_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, gbuffer_layer), 0); - float roughness = gbuffer_packed.z; + float roughness = (uniform_buf.raytrace.closure_active == CLOSURE_REFRACTION) ? + gbuf.refraction.roughness : + gbuf.reflection.roughness; if (ray_glossy_factor(roughness) > 0.0) { /* We don't care about race condition here. */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_renderpass_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_renderpass_lib.glsl index 078154bfbce..9495c7172c9 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_renderpass_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_renderpass_lib.glsl @@ -2,16 +2,56 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -void render_pass_color_out(int pass_index, vec3 color) +void output_renderpass_color(int id, vec4 color) { - if (pass_index >= 0) { - imageStore(rp_color_img, ivec3(ivec2(gl_FragCoord.xy), pass_index), vec4(color, 0.0)); +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + if (id >= 0) { + ivec2 texel = ivec2(gl_FragCoord.xy); + imageStore(rp_color_img, ivec3(texel, id), color); } +#endif } -void render_pass_value_out(int pass_index, float value) +void output_renderpass_value(int id, float value) { - if (pass_index >= 0) { - imageStore(rp_value_img, ivec3(ivec2(gl_FragCoord.xy), pass_index), vec4(value)); +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + if (id >= 0) { + ivec2 texel = ivec2(gl_FragCoord.xy); + imageStore(rp_value_img, ivec3(texel, id), vec4(value)); } +#endif +} + +void clear_aovs() +{ +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.color_len; i++) { + output_renderpass_color(uniform_buf.render_pass.color_len + i, vec4(0)); + } + for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.value_len; i++) { + output_renderpass_value(uniform_buf.render_pass.value_len + i, 0.0); + } +#endif +} + +void output_aov(vec4 color, float value, uint hash) +{ +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.color_len; i++) { + if (uniform_buf.render_pass.aovs.hash_color[i].x == hash) { + imageStore(rp_color_img, + ivec3(ivec2(gl_FragCoord.xy), uniform_buf.render_pass.color_len + i), + color); + return; + } + } + for (int i = 0; i < AOV_MAX && i < uniform_buf.render_pass.aovs.value_len; i++) { + if (uniform_buf.render_pass.aovs.hash_value[i].x == hash) { + imageStore(rp_value_img, + ivec3(ivec2(gl_FragCoord.xy), uniform_buf.render_pass.value_len + i), + vec4(value)); + return; + } + } +#endif } \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_subsurface_eval_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_subsurface_eval_frag.glsl index c0833c8733d..4609678dff3 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_subsurface_eval_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_subsurface_eval_frag.glsl @@ -28,22 +28,16 @@ void main(void) float gbuffer_depth = texelFetch(hiz_tx, texel, 0).r; vec3 vP = get_view_space_from_depth(center_uv, gbuffer_depth); - vec4 color_1_packed = texelFetch(gbuffer_color_tx, ivec3(texel, 1), 0); - vec4 gbuffer_2_packed = texelFetch(gbuffer_closure_tx, ivec3(texel, 2), 0); + GBufferData gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_color_tx, texel); - ClosureDiffuse diffuse; - diffuse.sss_radius = gbuffer_sss_radii_unpack(gbuffer_2_packed.xyz); - diffuse.sss_id = gbuffer_object_id_unorm16_unpack(gbuffer_2_packed.w); - diffuse.color = gbuffer_color_unpack(color_1_packed); - - if (diffuse.sss_id == 0u) { + if (gbuf.diffuse.sss_id == 0u) { /* Normal diffuse is already in combined pass. */ /* Refraction also go into this case. */ out_combined = vec4(0.0); return; } - float max_radius = max_v3(diffuse.sss_radius); + float max_radius = max_v3(gbuf.diffuse.sss_radius); float homcoord = ProjectionMatrix[2][3] * vP.z + ProjectionMatrix[3][3]; vec2 sample_scale = vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * @@ -56,10 +50,11 @@ void main(void) return; } - diffuse.sss_radius = max(vec3(1e-4), diffuse.sss_radius / max_radius) * max_radius; + /* Avoid too small radii that have float imprecision. */ + vec3 clamped_sss_radius = max(vec3(1e-4), gbuf.diffuse.sss_radius / max_radius) * max_radius; /* Scale albedo because we can have HDR value caused by BSDF sampling. */ - vec3 albedo = diffuse.color / max(1e-6, max_v3(diffuse.color)); - vec3 d = burley_setup(diffuse.sss_radius, albedo); + vec3 albedo = gbuf.diffuse.color / max(1e-6, max_v3(gbuf.diffuse.color)); + vec3 d = burley_setup(clamped_sss_radius, albedo); /* Do not rotate too much to avoid too much cache misses. */ float golden_angle = M_PI * (3.0 - sqrt(5.0)); @@ -87,7 +82,7 @@ void main(void) vec3 sample_radiance = sample_data.rgb; uint sample_sss_id = uint(sample_data.a); - if (sample_sss_id != diffuse.sss_id) { + if (sample_sss_id != gbuf.diffuse.sss_id) { continue; } @@ -116,7 +111,7 @@ void main(void) accum -= texelFetch(radiance_tx, texel, 0).rgb; /* Apply surface color on final radiance. */ - accum *= diffuse.color; + accum *= gbuf.diffuse.color; /* Debug, detect NaNs. */ if (any(isnan(accum))) { diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl index 24e77fd55f6..15c9b413523 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl @@ -16,6 +16,7 @@ #pragma BLENDER_REQUIRE(eevee_ambient_occlusion_lib.glsl) #pragma BLENDER_REQUIRE(eevee_surf_lib.glsl) #pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_renderpass_lib.glsl) #pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl) vec4 closure_to_rgba(Closure cl) @@ -86,56 +87,62 @@ void main() /* ----- GBuffer output ----- */ - if (true) { + uint header = 0u; + + if (g_reflection_data.weight > 0.0) { /* Reflection. */ - vec4 out_reflect = vec4(gbuffer_normal_pack(g_reflection_data.N), - g_reflection_data.roughness, - g_reflection_data.roughness); - imageStore(out_gbuff_closure_img, ivec3(out_texel, 0), out_reflect); + vec4 closure; + closure.xy = gbuffer_normal_pack(g_reflection_data.N); + closure.z = g_reflection_data.roughness; + closure.w = 0.0; + imageStore(out_gbuf_closure_img, ivec3(out_texel, 0), closure); vec4 color = gbuffer_color_pack(g_reflection_data.color); - imageStore(out_gbuff_color_img, ivec3(out_texel, 0), color); + imageStore(out_gbuf_color_img, ivec3(out_texel, 0), color); + header |= CLOSURE_REFLECTION; } - /* TODO(fclem) other RNG. */ - float refract_rand = fract(g_closure_rand * 6.1803398875); float combined_weight = g_refraction_data.weight + g_diffuse_data.weight; - bool output_refraction = combined_weight > 0.0 && - (refract_rand * combined_weight) < g_refraction_data.weight; - if (output_refraction) { - /* Refraction. */ - vec4 closure; - closure.xy = gbuffer_normal_pack(g_refraction_data.N); - closure.z = g_refraction_data.roughness; - closure.w = gbuffer_ior_pack(g_refraction_data.ior); - /* Clamp to just bellow 1 to be able to distinguish between refraction and diffuse. - * Ceiling value is chosen by the storage format (16bit UNORM). */ - closure.w = min(closure.w, float(0xFFFFu - 1u) / float(0xFFFFu)); - imageStore(out_gbuff_closure_img, ivec3(out_texel, 1), closure); + if (combined_weight > 0.0) { + /* TODO(fclem) other RNG. */ + float refract_rand = fract(g_closure_rand * 6.1803398875); + bool output_refraction = (refract_rand * combined_weight) < g_refraction_data.weight; + if (output_refraction) { + /* Refraction. */ + vec4 closure; + closure.xy = gbuffer_normal_pack(g_refraction_data.N); + closure.z = g_refraction_data.roughness; + closure.w = gbuffer_ior_pack(g_refraction_data.ior); + imageStore(out_gbuf_closure_img, ivec3(out_texel, 1), closure); - vec4 color = gbuffer_color_pack(g_refraction_data.color); - imageStore(out_gbuff_color_img, ivec3(out_texel, 1), color); - } - else { - /* Diffuse. */ - vec4 closure; - closure.xy = gbuffer_normal_pack(g_diffuse_data.N); - closure.z = gbuffer_thickness_pack(thickness); - /* Used to detect the refraction case. Could be used for roughness. */ - closure.w = 1.0; - imageStore(out_gbuff_closure_img, ivec3(out_texel, 1), closure); + vec4 color = gbuffer_color_pack(g_refraction_data.color); + imageStore(out_gbuf_color_img, ivec3(out_texel, 1), color); + header |= CLOSURE_REFRACTION; + } + else { + /* Diffuse. */ + vec4 closure; + closure.xy = gbuffer_normal_pack(g_diffuse_data.N); + closure.z = gbuffer_thickness_pack(thickness); + closure.w = 0.0; /* Unused. */ + imageStore(out_gbuf_closure_img, ivec3(out_texel, 1), closure); - vec4 color = gbuffer_color_pack(g_diffuse_data.color); - imageStore(out_gbuff_color_img, ivec3(out_texel, 1), color); + vec4 color = gbuffer_color_pack(g_diffuse_data.color); + imageStore(out_gbuf_color_img, ivec3(out_texel, 1), color); + header |= CLOSURE_DIFFUSE; + } + + if (g_diffuse_data.sss_id > 0) { + /* SubSurface Scattering. */ + vec4 closure; + closure.xyz = gbuffer_sss_radii_pack(g_diffuse_data.sss_radius); + closure.w = gbuffer_object_id_unorm16_pack(uint(resource_id)); + imageStore(out_gbuf_closure_img, ivec3(out_texel, 2), closure); + header |= CLOSURE_SSS; + } } - if (true) { - /* SubSurface Scattering. */ - vec4 closure; - closure.xyz = gbuffer_sss_radii_pack(g_diffuse_data.sss_radius); - closure.w = gbuffer_object_id_unorm16_pack(g_diffuse_data.sss_id > 0 ? uint(resource_id) : 0); - imageStore(out_gbuff_closure_img, ivec3(out_texel, 2), closure); - } + imageStore(out_gbuf_header_img, out_texel, uvec4(header)); /* ----- Radiance output ----- */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl index 153963976bd..893aec25ac4 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl @@ -16,6 +16,7 @@ #pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl) #pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl) #pragma BLENDER_REQUIRE(eevee_surf_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_renderpass_lib.glsl) #pragma BLENDER_REQUIRE(eevee_volume_lib.glsl) vec4 closure_to_rgba(Closure cl) diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl index 35a97c3eb8c..2a889aef48b 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl @@ -13,6 +13,7 @@ #pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl) #pragma BLENDER_REQUIRE(eevee_surf_lib.glsl) #pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl) +#pragma BLENDER_REQUIRE(eevee_renderpass_lib.glsl) void main() { diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh index a419d94a8d9..0056a7515ff 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh @@ -10,12 +10,15 @@ #define image_in(slot, format, name) \ image(slot, format, Qualifier::READ, ImageType::FLOAT_2D, name, Frequency::PASS) +GPU_SHADER_CREATE_INFO(eevee_gbuffer_data) + .sampler(7, ImageType::UINT_2D, "gbuf_header_tx") + .sampler(8, ImageType::FLOAT_2D_ARRAY, "gbuf_closure_tx") + .sampler(9, ImageType::FLOAT_2D_ARRAY, "gbuf_color_tx"); + GPU_SHADER_CREATE_INFO(eevee_deferred_light) .fragment_source("eevee_deferred_light_frag.glsl") /* Early fragment test is needed to avoid processing fragments without correct GBuffer data. */ .early_fragment_test(true) - /* Inputs. */ - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") /* Chaining to next pass. */ /* TODO(@fclem): These could use the sub-pass feature. */ .image_out(2, GPU_RGBA16F, "direct_diffuse_img") @@ -23,6 +26,7 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_light) .image_out(4, GPU_RGBA16F, "direct_refract_img") .define("SSS_TRANSMITTANCE") .additional_info("eevee_shared", + "eevee_gbuffer_data", "eevee_utility_texture", "eevee_sampling_data", "eevee_light_data", @@ -43,10 +47,11 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_combine) .image_in(5, RAYTRACE_RADIANCE_FORMAT, "indirect_diffuse_img") .image_in(6, RAYTRACE_RADIANCE_FORMAT, "indirect_reflect_img") .image_in(7, RAYTRACE_RADIANCE_FORMAT, "indirect_refract_img") - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") - .sampler(1, ImageType::FLOAT_2D_ARRAY, "gbuffer_color_tx") .fragment_out(0, Type::VEC4, "out_combined") - .additional_info("eevee_shared", "eevee_render_pass_out", "draw_fullscreen") + .additional_info("eevee_shared", + "eevee_gbuffer_data", + "eevee_render_pass_out", + "draw_fullscreen") .fragment_source("eevee_deferred_combine_frag.glsl") .do_static_compilation(true); @@ -54,11 +59,10 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_capture_eval) /* Early fragment test is needed to avoid processing fragments without correct GBuffer data. */ .early_fragment_test(true) /* Inputs. */ - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") - .sampler(1, ImageType::FLOAT_2D_ARRAY, "gbuffer_color_tx") .fragment_out(0, Type::VEC4, "out_radiance") .define("SSS_TRANSMITTANCE") .additional_info("eevee_shared", + "eevee_gbuffer_data", "eevee_utility_texture", "eevee_sampling_data", "eevee_light_data", diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh index 82fe048a237..57b14ba47e1 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh @@ -127,8 +127,9 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred) .fragment_out(0, Type::VEC4, "out_transmittance", DualBlend::SRC_1) /* Everything is stored inside a two layered target, one for each format. This is to fit the * limitation of the number of images we can bind on a single shader. */ - .image_array_out(GBUF_CLOSURE_SLOT, Qualifier::WRITE, GPU_RGBA16, "out_gbuff_closure_img") - .image_array_out(GBUF_COLOR_SLOT, Qualifier::WRITE, GPU_RGB10_A2, "out_gbuff_color_img") + .image_array_out(GBUF_CLOSURE_SLOT, Qualifier::WRITE, GPU_RGBA16, "out_gbuf_closure_img") + .image_array_out(GBUF_COLOR_SLOT, Qualifier::WRITE, GPU_RGB10_A2, "out_gbuf_color_img") + .image(GBUF_HEADER_SLOT, GPU_R8UI, Qualifier::WRITE, ImageType::UINT_2D, "out_gbuf_header_img") .fragment_source("eevee_surf_deferred_frag.glsl") .additional_info("eevee_global_ubo", "eevee_utility_texture", diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_subsurface_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_subsurface_info.hh index 5130711fc63..fafdb3791b7 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_subsurface_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_subsurface_info.hh @@ -7,9 +7,10 @@ GPU_SHADER_CREATE_INFO(eevee_subsurface_eval) .do_static_compilation(true) - .additional_info("eevee_shared", "eevee_global_ubo", "eevee_render_pass_out") - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") - .sampler(1, ImageType::FLOAT_2D_ARRAY, "gbuffer_color_tx") + .additional_info("eevee_shared", + "eevee_gbuffer_data", + "eevee_global_ubo", + "eevee_render_pass_out") .sampler(2, ImageType::FLOAT_2D, "radiance_tx") .early_fragment_test(true) .fragment_out(0, Type::VEC4, "out_combined") diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh index f358c3d9681..10c089d9c71 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh @@ -9,10 +9,12 @@ GPU_SHADER_CREATE_INFO(name##_reflect) \ .do_static_compilation(true) \ .define("RAYTRACE_REFLECT") \ + .define("CLOSURE_ACTIVE", "eClosureBits(CLOSURE_REFLECTION)") \ .additional_info(#name); \ GPU_SHADER_CREATE_INFO(name##_refract) \ .do_static_compilation(true) \ .define("RAYTRACE_REFRACT") \ + .define("CLOSURE_ACTIVE", "eClosureBits(CLOSURE_REFRACTION)") \ .additional_info(#name); /* -------------------------------------------------------------------- */ @@ -22,10 +24,8 @@ GPU_SHADER_CREATE_INFO(eevee_ray_tile_classify) .do_static_compilation(true) .local_group_size(RAYTRACE_GROUP_SIZE, RAYTRACE_GROUP_SIZE) - .additional_info("eevee_shared", "eevee_global_ubo") + .additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo") .typedef_source("draw_shader_shared.h") - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") - .sampler(1, ImageType::UINT_2D, "stencil_tx") .image(0, RAYTRACE_TILEMASK_FORMAT, Qualifier::WRITE, ImageType::UINT_2D, "tile_mask_img") .storage_buf(0, Qualifier::WRITE, "DispatchCommand", "ray_dispatch_buf") .storage_buf(1, Qualifier::WRITE, "DispatchCommand", "denoise_dispatch_buf") @@ -46,12 +46,11 @@ GPU_SHADER_CREATE_INFO(eevee_ray_tile_compact) GPU_SHADER_CREATE_INFO(eevee_ray_generate) .local_group_size(RAYTRACE_GROUP_SIZE, RAYTRACE_GROUP_SIZE) .additional_info("eevee_shared", + "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "draw_view", "eevee_utility_texture") - .sampler(0, ImageType::UINT_2D, "stencil_tx") - .sampler(1, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_ray_data_img") .storage_buf(4, Qualifier::READ, "uint", "tiles_coord_buf[]") .compute_source("eevee_ray_generate_comp.glsl"); @@ -93,12 +92,11 @@ EEVEE_RAYTRACE_CLOSURE_VARIATION(eevee_ray_trace_screen) GPU_SHADER_CREATE_INFO(eevee_ray_denoise_spatial) .local_group_size(RAYTRACE_GROUP_SIZE, RAYTRACE_GROUP_SIZE) .additional_info("eevee_shared", + "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "draw_view", "eevee_utility_texture") - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") - .sampler(1, ImageType::UINT_2D, "stencil_tx") .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") @@ -130,8 +128,11 @@ GPU_SHADER_CREATE_INFO(eevee_ray_denoise_temporal) GPU_SHADER_CREATE_INFO(eevee_ray_denoise_bilateral) .local_group_size(RAYTRACE_GROUP_SIZE, RAYTRACE_GROUP_SIZE) - .additional_info("eevee_shared", "eevee_global_ubo", "eevee_sampling_data", "draw_view") - .sampler(0, ImageType::FLOAT_2D_ARRAY, "gbuffer_closure_tx") + .additional_info("eevee_shared", + "eevee_gbuffer_data", + "eevee_global_ubo", + "eevee_sampling_data", + "draw_view") .sampler(1, ImageType::DEPTH_2D, "depth_tx") .image(1, RAYTRACE_RADIANCE_FORMAT, Qualifier::READ, ImageType::FLOAT_2D, "in_radiance_img") .image(2, RAYTRACE_RADIANCE_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "out_radiance_img")