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.
This commit is contained in:
Clément Foucault
2023-10-03 16:05:20 +02:00
parent 23e4cbc86a
commit 1b1b1a19bf
8 changed files with 42 additions and 0 deletions

View File

@@ -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

View File

@@ -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<float4, 16, true>;
using VelocityIndexBuf = draw::StorageArrayBuffer<VelocityIndex, 16>;
using VelocityObjectBuf = draw::StorageArrayBuffer<float4x4, 16>;
using CryptomatteObjectBuf = draw::StorageArrayBuffer<float2, 16>;
using ClipPlaneBuf = draw::UniformBuffer<ClipPlaneData>;
} // namespace blender::eevee
#endif

View File

@@ -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);
}

View File

@@ -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
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

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