With the help of engine source FSplineComponentVisualizer::DrawVisualization and some forum posts, this is what I end up with:
Basically what I did was extending UPrimitiveComponent class and override these two functions:
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override;
Define your own component bounds to deal with frustum culling with CalcBounds.
Then create another class inheriting from FPrimitiveSceneProxy to get hold of a FPrimitiveDrawInterface pointer ([refer to this forum post][2]) and draw with
PDI->DrawLine(LineStart, LineEnd, Color, SceneDepthPriorityGroup, Thickness);
If you want your line occluded by other objects, the SceneDepthPriorityGroup has to be SDPG_World.
With a thickness of 0.0f the line is constantly 1 pixel wide; however any value above 0.0f results in the line thickness becoming depth dependent. If you need a constant thickness and want to be able to control the thickness as well, check out FSceneView::WorldToScreen, which returns a FVector4, then use the W component of that vector to scale the line thickness.
