godot: Broken GLES2 render in Godot 3.4 and later on iOS due to Octahedral Compression

Godot version

3.4.2 and 3.5 beta 1

System information

iOS 15.2.1 / iPhone SE / OpenGL ES 2.0 Renderer: Apple A9 GPU

Issue description

When running the game on iOS, GLES2 rendering does not work correctly. I tried a variety of render settings, re-imported everything several times, but nothing helped. I have tried all versions of Godot since 3.4 to check at what point the rendering started to work incorrectly, however, in all versions the situation is the same.

On the video you can track the process of how it looks.

https://user-images.githubusercontent.com/13809475/151420521-a01c91e0-bb55-4235-9335-593ddb72cc9f.mp4

Also here are some screenshots. Sorry for the quality, I didn’t make it. Shotcut_00_00_16_533

Shotcut_00_00_03_467

Shotcut_00_00_36_067

Runs from Xcode

xcode

This project works great on Android, Windows, Linux, MacOS but is completely broken on iOS. Switching to GLES3 solves this problem, but the game starts to work very slowly (FPS drops a lot).

When starting the project, the console outputs this

*********** main.m
running app main
Path: /var/containers/Bundle/Application/141C6F1F-C05D-41A4-BAFE-8B9F9C1B4C81/Bunker.app
godot_iphone /var/containers/Bundle/Application/141C6F1F-C05D-41A4-BAFE-8B9F9C1B4C81/Bunker.app/Bunker
cwd /private/var/containers/Bundle/Application/141C6F1F-C05D-41A4-BAFE-8B9F9C1B4C81/Bunker.app
os created
setting data dir to /var/mobile/Containers/Data/Application/E8A36F7A-E7D7-49B6-AA65-3296D3C7DC04/Documents from /var/mobile/Containers/Data/Application/E8A36F7A-E7D7-49B6-AA65-3296D3C7DC04/Documents
setup 0
2022-01-27 19:12:00.839936+0300 Bunker[1369:282913] Metal API Validation Enabled
2022-01-27 19:12:00.977090+0300 Bunker[1369:282913] Setting up an OpenGL ES 2.0 context.
2022-01-27 19:12:00.977381+0300 Bunker[1369:282913] failed to make complete framebuffer object 8cd6
2022-01-27 19:12:00.977430+0300 Bunker[1369:282913] Failed to create frame buffer!
******** setting up keyboard input view
******** adding observer for keyboard show/hide

start animation!
2022-01-27 19:12:01.018063+0300 Bunker[1369:282913] ERROR: AudioOutputUnitStart failed, code: -50
2022-01-27 19:12:01.018145+0300 Bunker[1369:282913]    at: start (drivers/coreaudio/audio_driver_coreaudio.cpp:249) - AudioOutputUnitStart failed, code: -50
ERROR: AudioOutputUnitStart failed, code: -50
   at: start (drivers/coreaudio/audio_driver_coreaudio.cpp:249) - AudioOutputUnitStart failed, code: -50
2022-01-27 19:12:01.025181+0300 Bunker[1369:282913] Godot Engine v3.5.beta1.official.b9b23d222 - https://godotengine.org
Godot Engine v3.5.beta1.official.b9b23d222 - https://godotengine.org
2022-01-27 19:12:01.030797+0300 Bunker[1369:282913] OpenGL ES 2.0 Renderer: Apple A9 GPU
OpenGL ES 2.0 Renderer: Apple A9 GPU
2022-01-27 19:12:01.202877+0300 Bunker[1369:282913] 

When switching to a game scene with a loaded 3D level

(servers/visual/visual_server_scene.cpp:731) - Index p_surface = 0 is out of bounds (instance->materials.size() = 0).
ERROR: Index p_surface = 0 is out of bounds (instance->materials.size() = 0).
   at: instance_set_surface_material (servers/visual/visual_server_scene.cpp:731) - Index p_surface = 0 is out of bounds (instance->materials.size() = 0).
2022-01-27 19:12:39.319028+0300 Bunker[1369:282913] ERROR: Index p_surface = 0 is out of bounds (instance->materials.size() = 0).
2022-01-27 19:12:39.319089+0300 Bunker[1369:282913]    at: instance_set_surface_material (servers/visual/visual_server_scene.cpp:731) - Index p_surface = 0 is out of bounds (instance->materials.size() = 0).
ERROR: Index p_surface = 0 is out of bounds (instance->materials.size() = 0).
   at: instance_set_surface_material (servers/visual/visual_server_scene.cpp:731) - Index p_surface = 0 is out of bounds (instance->materials.size() = 0).

Endless spamming of bugs to the console (shown in the video video) throughout the game.

2022-01-27 19:16:12.030526+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.047285+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.065636+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.080681+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.097296+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.114506+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.130409+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.146974+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.164081+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.181806+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.197300+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.213994+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.230584+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.247444+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.264062+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.281690+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.298460+0300 Bunker[1369:282913] DrawView: 500 error
2022-01-27 19:16:12.314070+0300 Bunker[1369:282913] DrawView: 500 error

Steps to reproduce

Download and open the project from the archive.

The minimum project contains the most complete script for building the game.

Main level in res://levels/level_0.tscn

Rendering takes place on the scene res://scenes/game.tscn

Minimal reproduction project

Bunker_21.zip

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 54 (26 by maintainers)

Most upvoted comments

Good afternoon! The problem has now been fixed!

Apologies for the delay, I have been learning how to use xcode/develop on mac/ios for the past day or so haha (thanks to my friend for letting me use their apple devices to dig into this!)

Ok so some progress - I think I found the issue causing all of those DrawView: 500 errors - it’s actually not the octahedral compression (surprise!); in my implementation of split stream vertex buffers, I seem to have missed setting the uses_half_float flag in rasterizer_storage_gles2.cpp when checking the format for compressed vertex positions - this is causing an invalid enum and resulting in the messed up rendering seen in the first

As for the rendering artifacts seen on the character models in the minimal scene, those may be caused by octahedral, but I have not been able to reproduce that on the iphone that I have access to (iPhone 13 pro) - I am curious though if anything changes in the rendering after the half_float fix is merged in - I’ll see if I can dig into this aspect of it though and see if I can reproduce

and just as a quick response to the usefulness of octahedral compression - while I recognize the performance and battery life claims have not necessarily actualized in real world projects (just the benchmarks I’ve made), I would like to also point out that there is also a large visual quality improvement in using octahedral compression (almost ground truth level quality for the same cost as the old compression technique) so there is value there too; I’m a bit confused how loading octahedral compressed meshes could work if you couldn’t import your meshes as octahedral compressed in godot to create them in the first place (there are no 3D modelling packages I’m aware of that export octahedral compressed meshes)

Ok, I spent a whole day testing and yes, it is 100% “Octahedral Compression”, after re-creating the assets and re-importing into the game with “Octahedral Compression” disabled, the whole game began to display correctly on all devices. Apparently, there are many weeks ahead of recreating gaming assets… well, the reason has become clear. Hope this bug gets fixed. As a recommendation, you can turn it off by default, since many people have no idea about such subtleties and the technical side of the issue.

So, I tried to re-import new models that were created in the same way as the previous ones. This time I imported the same model with different parameters and the result showed up immediately.

The screenshot shows the two models and the differences in settings (yes, just one tick). 1643452117

And now how it looks on the phone.

https://user-images.githubusercontent.com/13809475/151659005-12554eaa-0b41-4e04-bb22-e1ee457b8c7d.mp4

In that case, octahedral compression should default to OFF (with a big warning that it is destructive!)

It is only destructive if you remove your source resources, which you should never do since Godot 3.0 – it’s not a supported workflow anymore. To clarify, Godot’s import system does not overwrite your source resources. However, if you remove your scene resources (and still have the imported resource lingering in .import/), you can’t get the source resource back without filesystem recovery tools.

Ok one thing I can bring up right now at least is that there’s another issue open on Android devices with Mali GPUs which causes issues with rendering of animated meshes, and the Samsung M12 has one of these gpus 😕 - although I have not found a way to resolve it or truly confirm the driver bug yet (see this issue https://github.com/godotengine/godot/issues/54763)

UPD: This makes the project cleaner, there are no heaps of extra files. Plus less redundant information.

It’s tangential to this issue (octahedral compression needs to be fixed not to produce these bugs), but be aware that with this practice you are saving 3D mesh data as text in tscn files, when you could be using it from binary data in .glb, with a lot more flexibility to reimport everything on the fly if you need to change anything (like import settings here, or modify your mesh data, animations, etc.).

I don’t have the original glb to compare, but see here the extra size that you get in a .tscn file from encoding mesh data as a byte array (the .tscn file has lines with 1 million characters). I converted it to .scn for comparison (the size of .tscn + .glb should be similar to that .scn):

-rw-r--r-- 1 akien akien 168K Feb  1 14:39 kosmonavt_1.scn
-rw-r--r-- 1 akien akien 1,2M Feb  1  2022 kosmonavt_1.tscn

@akien-mga The trouble is that my assets do not lie in the form of separate files. They are literally inside tscn files… It was my mistake when I originally designed the game’s architecture)

I don’t know if this works as I didn’t know it existed, but if you look in project_settings/import_defaults tab, and select importer Scene, there is a checkbox for octahedral compression. Sounds worth a try at least, maybe this will re-import meshes in the tscn files?

If not, then presumably we should have some mechanism for re-importing meshes in tscn files, or at least a warning. 🤔

The smallest project.

Bunker_21.zip

And don’t panic

I understand. Thanks. It’s just that the game has a huge audience (millions of people) on Android, and many players have asked for iPhone support, which I can’t provide because of this… I would like to use the 3.5+ features to provide the best experience for the players. As soon as I download 3.4 beta 3, I will share the results of testing. For 3.4 beta 2, everything is bad.