From 1b1b1a19bffcade8cd367bac8a3b242dee2bc3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 3 Oct 2023 16:05:20 +0200 Subject: [PATCH] EEVEE-Next: Add world clip plane support This add a way to use a software clip plane in the prepass shader (surf_depth_frag.glsl). The benefit of using this instead of gl_ClipDistance is that the rasterization pattern is given to match. Which means that only the prepass shader have to use this. This is slow and should only be enabled when needed. --- .../blender/draw/engines/eevee_next/eevee_defines.hh | 1 + .../draw/engines/eevee_next/eevee_shader_shared.hh | 7 +++++++ .../eevee_next/shaders/eevee_geom_curves_vert.glsl | 4 ++++ .../eevee_next/shaders/eevee_geom_gpencil_vert.glsl | 4 ++++ .../eevee_next/shaders/eevee_geom_mesh_vert.glsl | 4 ++++ .../shaders/eevee_geom_point_cloud_vert.glsl | 4 ++++ .../eevee_next/shaders/eevee_surf_depth_frag.glsl | 10 ++++++++++ .../eevee_next/shaders/infos/eevee_material_info.hh | 8 ++++++++ 8 files changed, 42 insertions(+) diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index eaa19b8d8e2..7027987c088 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -173,6 +173,7 @@ #define VELOCITY_CAMERA_PREV_BUF 2 #define VELOCITY_CAMERA_CURR_BUF 3 #define VELOCITY_CAMERA_NEXT_BUF 4 +#define CLIP_PLANE_BUF 5 /* Storage Buffers. */ #define LIGHT_CULL_BUF_SLOT 0 diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh index a993abcc272..14cb8fc5d40 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh @@ -1309,6 +1309,12 @@ struct ReflectionProbeData { }; BLI_STATIC_ASSERT_ALIGN(ReflectionProbeData, 16) +struct ClipPlaneData { + /** World space clip plane equation. Used to render planar lightprobes. */ + float4 plane; +}; +BLI_STATIC_ASSERT_ALIGN(ClipPlaneData, 16) + /** \} */ /* -------------------------------------------------------------------- */ @@ -1442,6 +1448,7 @@ using VelocityGeometryBuf = draw::StorageArrayBuffer; using VelocityIndexBuf = draw::StorageArrayBuffer; using VelocityObjectBuf = draw::StorageArrayBuffer; using CryptomatteObjectBuf = draw::StorageArrayBuffer; +using ClipPlaneBuf = draw::UniformBuffer; } // namespace blender::eevee #endif diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl index 7ac5c412896..35078f0e8a7 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl @@ -54,5 +54,9 @@ void main() interp.P += nodetree_displacement(); +#ifdef MAT_CLIP_PLANE + clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0)); +#endif + gl_Position = point_world_to_ndc(interp.P); } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl index 3ecb6d8d730..a316796e4f9 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl @@ -51,4 +51,8 @@ void main() attrib_load(); interp.P += nodetree_displacement(); + +#ifdef MAT_CLIP_PLANE + clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0)); +#endif } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl index 09875e3ba5b..afaacf5b9c7 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl @@ -35,5 +35,9 @@ void main() interp.P += nodetree_displacement(); +#ifdef MAT_CLIP_PLANE + clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0)); +#endif + gl_Position = point_world_to_ndc(interp.P); } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_point_cloud_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_point_cloud_vert.glsl index f80d19c7de5..7452ba44d08 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_point_cloud_vert.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_point_cloud_vert.glsl @@ -47,5 +47,9 @@ void main() interp.P += nodetree_displacement(); +#ifdef MAT_CLIP_PLANE + clip_interp.clip_distance = dot(clip_plane.plane, vec4(interp.P, 1.0)); +#endif + gl_Position = point_world_to_ndc(interp.P); } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl index f262eb72ba4..dbd2ff4227f 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl @@ -44,6 +44,16 @@ void main() } #endif +#ifdef MAT_CLIP_PLANE + /* Do not use hardware clip planes as they modify the rasterization (some GPUs add vertices). + * This would in turn create a discrepency between the prepass depth and the gbuffer depth which + * exhibits missing pixels data. */ + if (clip_interp.clip_distance > 0.0) { + discard; + return; + } +#endif + #ifdef MAT_VELOCITY out_velocity = velocity_surface(interp.P + motion.prev, interp.P, interp.P + motion.next); out_velocity = velocity_pack(out_velocity); 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 a47eddd85d4..7ba6a4d1965 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 @@ -26,6 +26,14 @@ GPU_SHADER_CREATE_INFO(eevee_utility_texture) .define("EEVEE_UTILITY_TX") .sampler(RBUFS_UTILITY_TEX_SLOT, ImageType::FLOAT_2D_ARRAY, "utility_tx"); +GPU_SHADER_INTERFACE_INFO(eevee_clip_plane_iface, "clip_interp") + .smooth(Type::FLOAT, "clip_distance"); + +GPU_SHADER_CREATE_INFO(eevee_clip_plane) + .vertex_out(eevee_clip_plane_iface) + .uniform_buf(CLIP_PLANE_BUF, "ClipPlaneData", "clip_plane") + .define("MAT_CLIP_PLANE"); + /** \} */ /* -------------------------------------------------------------------- */