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"); + /** \} */ /* -------------------------------------------------------------------- */