-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Added option to enable high precision float in GLES2 #33646
Conversation
We recommend always defining the option and prefixing its name with Lines 962 to 963 in 98caeb6
|
I agree with making this optional, however assuming it is turned on, If we consider 3 possibilities:
This PR will help in situation (1) however it can potentially make situation (2) worse, and leaves situation (3) unfixed. As is this would be a case to authors of 'beware, use at your own risk', but it would be nice to have some kind of scalable solution, to what is admittedly a difficult problem. It would be nice to be able to detect situations (2) and (3), and apply a different shader (or a different path within the shader). Could it be possible to detect situation (3) outside the shader itself? Perhaps by attempting to compile a test fragment shader containing highp, or using the define itself to cause compilation failure and testing for this compilation failure (assuming OpenGL doesn't just crash!)? This could potentially be used to swap to a different shader. For situation (2) it might be possible to have an in game settings to swap between 2 alternative shaders? A real life example shader is a fancy water shader - you might use a highp fragment shader on hardware that supports it well, but fallback to a simpler shader on hardware that doesn't, so those people can still play the game. In addition there is the performance question of whether highp should be used throughout a fragment shader (I don't know whether this PR applies it throughout or just to varyings / variables that have been marked as highp in the godot shader source). The problem of scalable shaders is also generally applicable, to enable users to scale their game experience according to their hardware, I don't know if we have any in built solution for this as yet but it may be worth thinking about within this framework. Having the option of 2 (or more) tiers of shaders to choose from would make the games far more scalable, if this isn't already available, and could be used to address this problem without making the games unplayable for a large number of players. |
@lawnjelly Detecting the support can be done outside via Regarding the question of where the change introduces highp computation in the fragment shader: as far as I understand it this will apply to all variables/uniforms/varyings that have no precision qualifier applied (and as you said: this should only be used on high-end devices). Regarding a scalable shader pipeline: this sounds like a monumental task with a lot of trade-offs depending on how you define the capabilities of the low-end hardware vs. mid-range and high-end. Especially since a user would then have to be very aware of how the system behaves on different hardware in a very detailed way to author the content properly and not rely on sth. that might disappear for some players of the game (but arguably this is already the case at the moment). There are already some options in the existing shader that go into this direction (phong vs. ggx, lit vs. unlit) so maybe providing some query functions for the hardware capabilities to GDScript would allow (advanced) users to build system to manually select the right shader; also supporting the opengl precision keywords in the godot shader language could help there if someone wants to go deep into performance optimization. |
3f24a67
to
b8cdcea
Compare
I updated the PR with |
doc/classes/ProjectSettings.xml
Outdated
@@ -821,6 +821,9 @@ | |||
</member> | |||
<member name="rendering/quality/shading/force_lambert_over_burley.mobile" type="bool" setter="" getter="" default="true"> | |||
</member> | |||
<member name="rendering/quality/shading/gles2_high_float_precision.mobile" type="bool" setter="" getter="" default="false"> | |||
If [code]true[/code] and available on the target device high floating point precision for all shader computations in GLES2 is enabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to ->
"If [code]true[/code] and available on the target device, enables high floating point precision for all shader computations in GLES2.
[b]Warning:[/b] High floating point precision can be extremely slow on older devices and is often not available at all. Use with caution."
main/main.cpp
Outdated
@@ -961,6 +961,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph | |||
|
|||
// Assigning here even though it's GLES2-specific, to be sure that it appears in docs | |||
GLOBAL_DEF("rendering/quality/2d/gles2_use_nvidia_rect_flicker_workaround", false); | |||
GLOBAL_DEF("rendering/quality/shading/gles2_high_float_precision.mobile", false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be in VisualServer.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, you can add it after:
servers/visual_server.cpp
2446: GLOBAL_DEF("rendering/gles2/compatibility/disable_half_float", false);
It could be renamed to "rendering/gles2/compatibility/enable_high_float"
I guess to match the other gles2/compatibility
setting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually this one should be removed now that it has been put in VisualServer. It should only be defined once.
servers/visual_server.cpp
Outdated
@@ -2401,6 +2401,7 @@ VisualServer::VisualServer() { | |||
GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley.mobile", true); | |||
GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false); | |||
GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true); | |||
GLOBAL_DEF("rendering/quality/shading/gles2_high_float_precision.mobile", false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should have both the normal and the .mobile
variant here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit of a weird situation though as the non-.mobile
variant (or .Android
if we go this route) wouldn't do anything currently.
@clayjohn @NeoSpark314 Any updates on this PR? |
@m4gr3d I'm good with it. It just needs reduz's approval to get merged. Would be a good candidate for a PR review meeting. |
@NeoSpark314 When you get a chance, this PR needs to be rebased on the latest master branch. |
@aaronfranke @NeoSpark314 Actually I think this PR should be rebased against the 3.2 branch since gles2 is removed from the master branch. |
Also note that since the PR was originally made there is now a project setting group |
@NeoSpark314 Could you rebase this on |
@akien-mga done; rebased this PR on top of 3.2 and changed the target branch to 3.2 |
Here's an example of a user that needed this feature for an Oculus Quest project too: https://twitter.com/acegiak/status/1285535845806510080 (she compiled Godot with this PR to solve it). @reduz is OK with the changes 👍 There are some outstanding nitpicks from @clayjohn though which would be good to address. Should there also be some additional documentation about the caveats mentioned by @lawnjelly? |
drivers/gles2/shader_gles2.cpp
Outdated
@@ -180,6 +181,14 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() { | |||
strings.push_back("#define USE_HIGHP_PRECISION\n"); | |||
#endif | |||
|
|||
#ifdef ANDROID_ENABLED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it really be Android-specific? If so, instead of exposing it as a .mobile
override, it could be an .Android
override (see platform/android/export/export.cpp::get_platform_features
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have experience with iOS and don't know if the shader compiler would support it. I made it android specific now by moving it to .Android
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The #ifdef
can be removed.
@akien-mga I updated the documentation as suggested by @clayjohn, moved the setting to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good to me.
Just double check with @akien that the #ifdef ANDROID_ENABLED
is still needed now that you are using .Android
An additional project setting under rendering/gles2/compatibility with the name enable_high_float.Android is introduced that enables #define USE_HIGHP_PRECISION in GLES2 shader on Android when it is supported by the shader compiler. This fixes godotengine#33633 and godotengine#32813 and also GodotVR/godot_oculus_mobile#60 and GodotVR/godot_oculus_mobile#68 on devices that support the highp (high precision) modifier.
@akien-mga the |
Thanks! |
An additional project setting under rendering/shading with the name
gles2_high_float_precision.mobile is introduced that enables #define USE_HIGHP_PRECISION
in GLES2 shader on Android when it is supported by the shader compiler.
This fixes #33633 and #32813 and also GodotVR/godot_oculus_mobile#60
and GodotVR/godot_oculus_mobile#68 on devices that support the highp (high precision) modifier.
@clayjohn suggested on discord to introduce a project setting to solve this problem.
Two open questions from my side are