State change sorting on draw calls

Hey guys,
I have a question regarding batching state changes in UE. I have hundred meshes in my level, which share a total of 7 materials/ texture atlases. (mesh 1-15 material 1, 15-30 material 2 …). My project is on Forward renderer on Mobile (platform is Oculus Quest/ Android). The meshes are Unlit Opaque and early Z pass is turned off.

At the moment Unreal renders these meshes in an order which I assume is front to back, although looking at the draw calls in Render doc, it seriously looks like the meshes are being drawn in a random order. I am aware that the order in forward rendering without an early z-pass is front to back to avoid fragment overdraw, but since my meshes are unlit photogrammetry meshes, I dont care about the overdraw as much and would like to try to avoid unnecessarily state changes.

So what I want to do is to **draw the meshes that share the same material/ texture **together (each still its own draw call, just mesh 1-15 first, then 15-30, like this I would avoid a glBindTexture() call). At the moment there are around 70 glBindTexture calls. The reason why it is not 100 is because sometimes it just happens that two meshes that share the same texture are drawn on after another and no glBindTexture is required. I would like to reduce this number to 7 glBindTextures calls. Btw I get all these info by looking at the render loop in RenderDoc.

Looking at Epics documentationit is stated that “there is no state sorting” for the dynamic rendering path. But even when my meshes are marked as static, they are still not sorted! Although it says that based on the "Compare and Matches " functions the draw polices are sorted.

Anyone has any ideas how to achieve a dynamic batching like this? Or at least where in the code base I can go to read more on it/ modify it?

Any suggestions would be a bliss.


Hi, are all your materials and meshes the same?

Hi @chrudimer , thanks for answering. No the meshes are not the same. I am also not trying to merge the draw calls themselves. I just want to get rid of the redundant glTextureBind calls.

Ah ok, then I don’t have the knowledge to help you there, only thing I can think of would be trying this (not sure if you already tried this):

Make a very simple material, so only one texture (that is not a parameter) as base color (or emissive color in unlit) and directly use this material without any instancing (so this material and not an instance of it) and check if this reduces the glBindTexture calls.