VR Pickup objects and HLOD Optimization?

Greetings. I have a question about optimizing my level for VR using the UE4 HLOD system. Say I have a bookshelf with 100 individual objects on it that are all blueprint static meshes set to moveable and can be picked up by the VR player. But when the player teleports away from them, I would want to use the UE4 HLOD optimization, since the player can no longer reach them, and therefore they could just be static meshes. But HLOD doesn’t work with dynamic meshes, so I’d need to swap them out when the player moves away, or the hand isn’t overlapping them. Should I place the meshes in my scene as static meshes, and then use blueprints to swap out the moveable object using hide/show mesh? Would that be the best way to go about achieving better performance? I guess this would also mean that the static mesh would have baked lighting, and the dynamic mesh would use dynamic lighting, so there might be a “pop” in shading when the swap happens, right?

The root of my problem is having performance issues with so many objects (even using LODs for all of them), and so many textures for each, creating a lot of draw calls. If I have a room with many bookshelves, the cost adds up quickly. Thanks for any help!

Anyone have any thoughts on this, please?

The problem with swapping out dynamic for static objects is that obviously their position will no longer match - if a player tossed all the books on the floor and subsequently teleports away, the shelf will appear full again.

A better approach would be to use instanced static meshes, so that all books can be drawn in a single draw call. You will have to put your textures into atlasses and use other material parameters such as colors to diversify the books, rather than having unique textures for all of them. Normally, if your books use the same mesh (or you use a small amount of different meshes), and use the same material instance but with different parameters set (possibly through BP), the engine should instance them for you. You should see reduced draw calls in stat RHI.

Thank you for your reply, @Lhorkan I’m getting about 1200 draw calls now at the high end, and 4.5M triangles. Not sure what’s generally acceptable for VR, but that seems high. About 22ms per frame at peak, as tested on GeForce GTX 970. But 8-9ms tested on a GTX 1080ti.

The problem, though, is that my static meshes are not books. They are all unique objects.

Your first solution seems like it actually might work in my case. When a player picks something off the shelf, and drops it on the floor, I currently have it disappear from the floor, and respawn onto the shelf in its original position. Just not sure how to implement swapping out a dynamic with a static mesh. Right now, each object is a blueprint set to movable, containing a static mesh component, set to movable. Do I first place them all as static meshes, and then use blueprint triggers to swap out the moveable blueprint version of the mesh when the player’s hand touches it?

1200 draw calls is about the upper limit of draw calls on PC VR from what I’ve seen in the Robo Recall optimization talk. You should check stat RHI to see what you’re being bound by: draw calls or actual rendering on the GPU; the former is CPU work. You can reduce draw calls by enabling instanced stereo, if you haven’t already.

With what you describe above, I would consider having a Blueprint in charge of an entire shelf: when the player is far enough away, it shows a merged low poly mesh of the shelf contents. When the player comes within range, it swaps that merged mesh out for the individual Blueprint actors.

Yes, I have Instanced Stereo on. But not Forward Rendering yet. I am going to run some tests to see how much performance gain I will get with it on, and using MSAA.

That’s exactly what I’m trying to do, though… through HLODs. But HLODs don’t work with dynamic meshes. So I guess I will try to figure out how to code blueprint to swap out the meshes when the player gets close.