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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user