Android OpenGL ES3.1 performance


I’m doing some mobile VR (nexus 6P, cartboard-like-device), and I’m strugling to archieve best performance for this particular device (It’s fixed VR experience ONLY for nexus 6P at this moment)
My rendertarget is 2048x1024 (1024x1024 per eye) without any postprocessing (the HMD plugin is similar in overal design to the GearVR one) so basically it boils to:
Bind 2048x1024 RT (RGBA8), set viewport, and do forward rendering of left eye, then switch viewport, do rendering of right eye, then in one single step push this texture into backbuffer & do flip
I wanted to experiment with little higher bit-resolution of the 2048x1024 RT (create it as 11_11_10_RGB) but this needs ES 3.1, so I’v switched to 3.1 (i’m using 4.11.2 from github)
and the performance went waaaaay down … from around 40 - 60 fps, to 5 - 7 fps ?
I didn’t profiled it yet, but I’m suspecting that UE switched back to deferred (I’m right, I do not want this as I do not have any dynamic lights, just static lighting (& some self illuminations for blinking stuff hardcoded in shaders)
So why I switched to ES 3.1 ?
Mainly because the lighting does not look right :confused: I want PROPER linear lighting, and as far as I see this could be done only in ES 3.1.
Now the lightmaps in darker areas looks just bad (banding)
Any other ways to archeve linear lighting on this specific phone and maintain desired performance (scene has ~200 batches, ~100k triangles per whole frame)


ES 3.1 in UE4 is deferred rendering and will be a big performance hit. It is intended for Nvidia K-1 and X-1 GPUs.

After grabbing frame I see it.
But I’m mainly tried ES 3.1 to gamma correctnes, since ES 3.1 is not a way to go, then I’v investigated why there is no gamma corectnes on my adreno 430 while the GL_EXT_sRGB is supported.
Looking at OpenGLES2.cpp the bSupportSRGB is correcly set to true, but then it is immediatelly forced to be false with a comment // @Todo ios7: SRGB support does not work …
but why this is also disabled for android devices ? any reason ?
I’m recompiling engine now, so I’ll be able to ansfer this for myself probably, but I’m curious about this little ‘hack’ :wink:

This has been in the engine for some time; I’ll do some investigating, but I suspect it predates Android support in UE4 :slight_smile:

Seems that commenting this hack (and also uncommenting -srgb switch in ASTC texture format compressor, and also fixing ASTC SRGB vs. RGB formats in GLDevice ;)) did the trick and I have gamma correct forward renderer for android.
(it will work only for ATC / ASTC as for example ETC1 / PVR compressed formats do not have SRGB versions of their enums (well, they have, but they do not work on real android devices) but for my use-case it works (at least with VR, where I’m manually create final framebuffer & FBO (I don’t know if they will be gamma - correct when automatically created by engine - would be nice to sort this out in 4.12 or 4.13 if it’s to late ? :>)

  • and I forgot to mention that changes in /shaders directory are also needed couse unreal assumes no sRGB sampling on textures (on mobiles) :confused: (see OUTPUT_GAMMA_SPACE definition and ProcessMaterialColorTextureLookup in MaterialTemplate.usf (sadly without OUTPUT_GAMMA_SPACE definition !!!)

Yes, I checked and the shader support is the primary reason it is disabled. There is a task to support this in our system.

after sorting all out and profiling it turns out that on adreno 430 (nexus 6P) the ‘not so correct’ shaders version (doing tex.rgb^2 on sampling and sqrt on output) is about ~2 ms faster than (18.3ms vs 20.1ms in test frame according to adreno gpu profiler)
correct one (sampling GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR and writing to GL_SRGB8_ALPHA8_EXT, without any magic in shader)
but the ‘not so correct’ version have issues in the dark areas (obvious banding)

the third attempt was to sample texture(s) and then max((1.0/12.92)tex.rgb, tex.rgbtex.rgb), then cancel this out by outputing min(12.92 * final.rgb, sqrt(max(0.006, final.rgb))) - this added some ALU, but it’s still faster (!!!) than hardware sRGB (have 19.4ms in profiler) and there is no banding … so sRGB is not entirelly free on mobiles.
(the main cost is not to sample sRGB ASTC with seems to be free, but to write GL_SRGB8_ALPHA8_EXT (with I suspect is rather something like R11G11B10F with additional 8Bit alpha attachment), but if I use GL_R11F_G11F_B10F with SRGB modifier (I don’t need alpha) then some weird things happend and phone eventually restarts :/) (GL_R11F_G11F_B10F without SRGB modifier works just fine, but still could not hold enough precision to do ‘degamma’ in postprocess step).

Hope that helps to sort all sRGB things out in future unreal versions. :wink:

We have a task UEMOB-117 to add a full ES 3.1 mode to the forward renderer where we can assume things like sRGB and 16 texture samplers. That’s going to be worked on in June.

  • Jack