FAQ: Mobile Rendering

Mar 24, 2021.Knowledge

Is there a reference for the things like z-depth that are inconsistent in the viewport ES2 Preview and the device renderer?

  • Q2, 2020: Z-depth is different, with differences between Android and IOS
  • The framebuffer is used to help with this
  • We also use GL extensions, and iOS can’t fetch depth
  • We render a 16 bit depth into the alpha value
  • In 4.26, we changed how we calculate depth to provide more precision. Might have strange effects at far off objects

What limitations should we be aware of for instancing on Android/iOS?

  • When instancing using components like HISM, there are no limitations on iOS.
  • On Android, there are a few things to be aware of with Mali GPU based devices: firstly devices based on the Midgard architecture (Mali-T8xx series and earlier), there are limitations when about the range of adjacent vertex indices when using 16-bit index buffers, as some data is repurposed for instancing purposes. Rendering such meshes with instancing will result in corrupted triangles. 4.25 added a workaround r.Android.MaliT8Bug=1 which will detect content with this issue and expand them to 32-bit index buffers at load time.
  • Secondly, Mali GPUs run the vertex shader once and store the results in a parameter buffer. Then each screen tile is processed in turn running the fragment shader. The parameter buffer has limited size and the full render pipeline needs to be flushed and restarted when it fills up. In normal rendering this can be dealt with, but in the case of instancing, it’s possible to overflow this buffer when you are rendering millions of triangles in a single draw call. When that happens, some of your instanced meshes will fail to render. There is no mechanism to detect this situation and not much that can be done to mitigate it except breaking up your draw calls. We don’t see it in practice with Fortnite foliage but we have seen it with synthetic test scenes.
  • For auto-instancing we have the GPU Scene feature which is supported on mobile in UE 4.24 and UE 4.25, but mobile GPUs are not well optimized for the random buffer access patterns we use to look up vertex data and so this is slower than no instancing for regular geometry, and use of HISM for special cases like foliage in typical game scenes.
  • We have also seen rendering corruption with this feature on some old Mali T8xx based mobile devices which we believe are due to driver bugs.

Best practices with Layered Materials? Mobile limitations?

  • No limitation we know of with layered materials on mobile. They are just too expensive to use on mobile, so we never use them internally.
  • The mobile hardware sampler limit is 16 samplers.
  • Several textures are used by the landscape system for blending layers together (1 texture for the first two layers plus the normal map, and 1 extra texture for each 4 layers you apply).
  • The mobile renderer also makes use of a couple of textures: the CSM shadowmap if using dynamic shadows, or otherwise 2 textures for the precomputed light/shadowmaps, plus the reflection environment or skylight.
  • With all of that, 5 or 6 layers sounds about right. Limiting the number of layers per component is key here as that’s the important number. There’s a landscape visualization mode that shows that.

Is there a way to disable features which are known to be unrealistic to use on mobile?

  • UE4 has the mobile renderer which is tuned to specifically ship mobile titles for lower end markets. The mobile renderer in UE4 currently defaults to the minimum specs used in Fortnite, but those can be modified by dozens (if not hundreds) of console variables or using the device profiles.