Procedural Mesh Component Rendering Performance Concerns

As a quick background on what I’m doing… I’m working on a dual contouring based voxel engine which currently runs with up to ~1500 chunks. Each chunk uses a heavily customized version of the ProceduralMeshComponent, or PMC, to render and provide collision. Also each chunk, and it’s associated PMC, has on average 2 mesh sections. This is also roughly the same chunk setup John Alcatraz is using in his project.

What we’re seeing is anywhere from ~0.2ms to ~1.2ms used each frame in the function GetDynamicMeshElements. Upon investigating further, it appears that 80+% of the time is used on this line

BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest());

I’m not super familiar with how the internals of UE4 work but creating this every frame for each mesh section doesn’t seem like the best way to do this. After looking into several other components including the StaticMesh, Landscape, and also the BrickGame plugin it appears that 2 different things should change here.

  1. That line should be changed to use a stored version of the uniform buffer and then the function OnTransformChanged should be implemented to updated it when necessary.
  2. DrawStaticElements should be implemented to keep from having to re-register every section of every chunk with the rendering system each frame. The ProceduralMeshComponent only implements dynamic relevance currently.

Am I correct in this thought process? Is there anything else that can be done to further improve this? What is the actual difference between DrawStaticElements and GetDynamicMeshElements, and the associated StaticRelevance and DynamicRelevance?

I have done both of the above changes and it appears to function correctly and I don’t get the excessive time updating uniform buffers every frame. I have based my changes to the GetDynamicMeshElements, DrawStaticElements, and OnTransformChanged functions on BrickGame found here starting at line 241:

The next part of this question is also based on BrickGames rendering component. I see where the vertex factory implemented the functions GetStaticBatchElementVisibility and GetStaticBatchElementShadowVisibility (Around line 148 in the above link) . Is this meant to be able to effectively show/hide individual meshes within the component instead of just the component as a whole? If that is right, is this called every frame, and if so does it preempt the usual culling based on the return value?

Thanks in advance for any help!

There are lots of different use cases for drawing geometry, and PMC is currently set up to be entirely dynamic and not optimized for the static case, which sounds like what you are looking for. Your changes to improve static geometry performance do sound interesting, it may be something we want to add options for supporting in the future. In general though when you have more specific rendering needs, it is often best to create your own component/proxy types rather than using the ‘general purpose’ ProceduralMeshComponent!