Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TRACKER] iOS rendering bugs related to half_float precision issues #38441

Closed
5 tasks done
clayjohn opened this issue May 3, 2020 · 4 comments
Closed
5 tasks done

[TRACKER] iOS rendering bugs related to half_float precision issues #38441

clayjohn opened this issue May 3, 2020 · 4 comments

Comments

@clayjohn
Copy link
Member

clayjohn commented May 3, 2020

Recently, while investigating a potential batching bug, @lawnjelly traced back rendering issues on an iOS device to the use of half float UVs. When an ArrayMesh is set to use compression, it will use half float (16 bit) formats instead of full float (32 bit). This cuts the size of the mesh in half, but can result in precision issues. The use of half floats is enabled by the extension GL_HALF_FLOAT_OES which is "available" on all GLES2 devices. I say "available" because iOS register the extension and present it as available, but silently fail when half floats are used in a vertex format. This comment #38318 (comment) presents a partial fix to the problem, but a more robust fix is needed.

I see two avenues to approach this problem:

  1. The issues are most obvious when rendering a mesh after having rendered certain GUI primitives. This seems to suggest that mixing half_floats and floats is a problem (e.g. the vertex buffer doesn't like switching between the two formats. This may require us to allocate more buffers to keep things clearly separated.

  2. The issue clearly stems from the use of GL_HALF_FLOAT_OES, so an obvious (but not necessarily optimal) fix would be to force iOS devices to never use half floats here:

    #ifdef JAVASCRIPT_ENABLED
    config.support_half_float_vertices = false;
    #else
    //every other platform, be it mobile or desktop, supports this (even if not in the GLES2 spec).
    config.support_half_float_vertices = true;
    #endif

config.support_half_float_vertices = true;
//every platform should support this except web, iOS has issues with their support, so disable
#ifdef JAVASCRIPT_ENABLED
	config.support_half_float_vertices = false;
#endif 
#ifdef IPHONE_ENABLED
	config.support_half_float_vertices = false;
#endif

This solution, while easy, would result in iOS devices never compressing vertex data, which will unnecessarily increase the amount of VRAM used.

The following issues appear to stem from this particular issue and will likely be solved by the fixes above:

The following issues may come from this particular issue and may be solved by the fixes above:

@clayjohn clayjohn added this to the 3.2 milestone May 3, 2020
@Calinou Calinou added the tracker label May 3, 2020
@Calinou Calinou changed the title iOS half_float issue tracker [TRACKER] iOS rendering bugs related to half_float precision issues May 3, 2020
@lawnjelly
Copy link
Member

3.2.2 beta 2

Good news is, we got this in 3.2.2 beta 2.

Bad news is, I made a boo-boo 😊 , and although there is a disable_half_float project setting in rendering/gles2/debug/disable_half_float, it is actually trying to read it from a mistyped version (batching instead of debug) in the code. So changing this project setting currently won't have any effect.

Instructions

However, you can still get it to work, but you have to work around my mistake by editing your project.godot, which is a text file, that contains lots of info about your project.

You just need to add the setting manually in your project.godot:

[rendering]

gles2/batching/disable_half_float=true

(if the [rendering] section already exists, then only gles2/batching/disable_half_float=true should be added under it)

Feedback

Please let us know how you get on, whether this fixes any issues on iOS for you. Again, apologies for making such silly mistake!

@oeleo1
Copy link

oeleo1 commented May 13, 2020

Feedback: after some quick testing on iOS: Yes, it does fix the CPUParticles on iOS for GLES2 and that's great news. Regarding performance, no perceivable difference on my project of batching vs non-batching on iOS but I have to spend some more time on that. It looks like the batching prevents some of the stutter I see with GLES2 (GLES3 is far better on iOS). Haven't tried Android yet.

@lawnjelly
Copy link
Member

Feedback: after some quick testing on iOS: Yes, it does fix the CPUParticles on iOS for GLES2 and that's great news. Regarding performance, no perceivable difference on my project of batching vs non-batching on iOS but I have to spend some more time on that. It looks like the batching prevents some of the stutter I see with GLES2 (GLES3 is far better on iOS). Haven't tried Android yet.

That's good, the half float change seems to be successful. We'll have to see about the most sensible way to roll it out long term (in terms of detection, or just platform specific defaults), and test whether it is a case of half float not being supported in GLES2, or just the wrong constant.

In terms of performance, it could be that you are not drawcall limited, it depends on the game. I'm happy to help with specific performance issues in games, although probably github isn't the best place. Maybe https://godotforums.org/ ?

@akien-mga akien-mga modified the milestones: 3.2, 3.3 Mar 17, 2021
@akien-mga akien-mga modified the milestones: 3.3, 3.5, 3.4 Oct 25, 2021
@akien-mga
Copy link
Member

All fixed as of 3.4 with #54229 which disables half float on iOS by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants