After reviewing the relevant source code, I suspect that the issue may be caused by the current strategy used for selecting the contact plane during convex-convex collision manifold construction.
The convex-convex contact points are generated in the following function:
Function:
template <typename ConvexImplicitType1, typename ConvexImplicitType2> void ConstructConvexConvexOneShotManifold
Location:
Engine\Source\Runtime\Experimental\Chaos\Private\Chaos\CollisionOneShotManifolds.cpp
This function is responsible for building the collision manifold between two convex shapes in a “one-shot” manner. It internally calls:
Function:
template <typename ConvexImplicitType> int32 SelectContactPlane(…)
to determine the “best” contact plane based on the separating axis identified by
GJKContactPointMargin.
However, the current implementation of SelectContactPlane selects the plane that has the closest normal alignment with the separating axis, without considering whether the selected plane actually overlaps with the other convex shape.
This can be problematic when a convex shape has multiple planes (faces) with similar or nearly parallel normals. In such cases, the current selection strategy may incorrectly pick a plane that is not truly involved in the contact, simply because its normal is closest to the separating axis.
As a result, if the selected contact plane does not actually overlap with the other convex, no clipped vertices will be generated during the clipping phase, and thus no valid contact points will be produced for that pair — even though a real collision or proximity might exist.
To illustrate the issue more clearly, I have recorded a video:
Video:
StepWithModifiedEngine_DrawSAT_DrawContactPlane.mp4
which shows, frame by frame, the selected separating axis and the corresponding contact planes that were chosen by the algorithm. The footage demonstrates that the selected plane may not align with the actual overlapping region between the two convexes.