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

Add is_equal_approx/is_zero_approx for floats to shading language #77239

Closed

Conversation

Chaosus
Copy link
Member

@Chaosus Chaosus commented May 19, 2023

Adds the support for these two functions to Godot Shading Language. If the user does not use them - they will not be added to the code and thus will not be compiled by the internal system compiler (main @reduz claim about adding custom functions).

image

This should fix (partly, only for floats): godotengine/godot-proposals#6870

@Chaosus Chaosus requested a review from a team as a code owner May 19, 2023 12:36
@Chaosus Chaosus added this to the 4.1 milestone May 19, 2023
@Chaosus Chaosus force-pushed the shader_is_equal/zero_approx branch from 9d59426 to cdebff2 Compare May 19, 2023 12:48
@clayjohn clayjohn modified the milestones: 4.1, 4.2 Jun 9, 2023
@Calinou
Copy link
Member

Calinou commented Jun 26, 2023

If the user does not use them - they will not be added to the code and thus will not be compiled by the internal system compiler (main @reduz claim about adding custom functions).

@paddy-exe may be interested in this system, since it could allow adding helper functions to the text-based shader language similar to the ones we already have in VisualShader.

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally (rebased on top of master 6758a7f), it works as expected.

Code looks good to me at a glance.

@Calinou
Copy link
Member

Calinou commented Aug 24, 2023

(partly, only for floats)

This likely depends on godotengine/godot-proposals#2808, unless we're OK with using methods that have different names instead (which is inconsistent with how GDScript does it).

@Chaosus Chaosus force-pushed the shader_is_equal/zero_approx branch from cdebff2 to 337a096 Compare August 24, 2023 15:44
@Chaosus Chaosus force-pushed the shader_is_equal/zero_approx branch from 337a096 to 7478c51 Compare August 24, 2023 15:49
@akien-mga akien-mga requested a review from a team August 28, 2023 10:24
Copy link
Contributor

@paddy-exe paddy-exe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good to me 👍🏻

@bitsawer
Copy link
Member

I think this can be pretty useful, although as Calinou noted type overloading (for float, vec2, vec3 and vec4) would be great to add at some point as many similar GLSL functions understand overloading and these will be kind of special cases that don't. I usually use custom epsilon comparison values tuned for each purpose, but I think rough comparisons can be useful in many cases.

Another minor issue is this kind of "GDScriptification" of the shader language, as is_equal_approx() name and behavior is from GDScript. I don't personally mind at all, but for example with #71919 I discussed with @clayjohn and he mentioned that as main worry (if I remember right, feel free to correct me). I think asking reduz about it was the previous conclusion about it.

But generally, I don't mind adding this. Especially if we want to add function overlading at some point. Plus the system used for generating code only if used can be pretty useful for other things, too.

@Chaosus
Copy link
Member Author

Chaosus commented Aug 29, 2023

Another minor issue is this kind of "GDScriptification" of the shader language, as is_equal_approx() name and behavior is from GDScript.

Yeah, so either we assign a name from https://docs.godotengine.org/en/stable/tutorials/shaders/shaders_style_guide.html#naming-conventions (is_equal_approx) or make them like GLSL built-ins (isEqualApprox).

@bitsawer
Copy link
Member

I personally like is_equal_approx() more in this case instead of isEqualApprox(), the snake-case naming hints it's a Godot specific addition and it's also more familiar to GDScript users. But some people might think it's inconsistent with other GLSL built-in fuctions and the Godot / GLSL function divide might not matter to most people (if they will even be aware of it), they will just see a conflicting naming conventions. Kind of a bikeshedding here, I can understand both arguments.

@QbieShay
Copy link
Contributor

QbieShay commented Aug 30, 2023

Hey 👋 I have commented under the original proposal, but I was wondering if we can put our brain together to try and make a bit of golfing and find code that can be inlined perhaps? Shouldn't it be better than using a function and binary operators? I proposed this for vectors length(abs(curr_color - oldColor)) > 0.01)

@Calinou
Copy link
Member

Calinou commented Aug 30, 2023

Hey 👋 I have commented under the original proposal, but I was wondering if we can put our brain together to try and make a bit of golfing and find code that can be inlined perhaps? Shouldn't it be better than using a function and binary operators? I proposed this for vectors length(abs(curr_color - oldColor)) > 0.01)

This is likely significantly slower, as length() needs to perform sqrt() operations and can't early-abort if one of the components is not equal. I'd check the generated shader assembly from equivalent GLSL code to make sure.

@QbieShay
Copy link
Contributor

But the GPU has dedicated hardware for that i think ..? not sure :D

@Calinou
Copy link
Member

Calinou commented Aug 31, 2023

But the GPU has dedicated hardware for that i think ..? not sure :D

No matter how fast the GPU is, more instructions still take more time to run than fewer instructions 🙂

@QbieShay
Copy link
Contributor

QbieShay commented Sep 1, 2023

Hah, I wouldn't bet on that because GPUs are freaky. At the same time, I don't have enough hard evidence to support that and I don't think it's enough of an issue to be worthy more discussion ^^ no more opposition from my side

@clayjohn
Copy link
Member

clayjohn commented Sep 2, 2023

To add to Bitsawer's comment. I do feel weird about adding GDScript functionality into GDShaders, I think for two reasons:

  1. It will increase demand for other GDScript functionality
  2. It adds significant complexity to our shader pre-compiler which is already turning into an expensive and difficult to maintain area of the engine.

That being said this particular change is rather simple and does not add much complexity. So I think it is worth evaluating on its own. In any case, I think it would be beneficial to discuss this at the next rendering meeting so we can start to put together a clear idea about the future of GDShaders in respect to adding GDScript functionality.

@clayjohn
Copy link
Member

We discussed this in the Rendering meeting on September 6. Those present in the meeting felt that adding this function into GDShaders is problematic as it mixed GLSL and GDScript paradigms, and doesn't actually solve the issue of users not understanding floating point precision.

In the meeting we agreed that a better solution would be to detect usages of equal and not-equal operators with floats on either side and present the user with a clear warning in the editor

@clayjohn clayjohn removed this from the 4.2 milestone Sep 19, 2023
@Chaosus Chaosus closed this Sep 20, 2023
@Chaosus
Copy link
Member Author

Chaosus commented Sep 20, 2023

Alright, then this should be closed. A warning is already been present for the users.

@Chaosus Chaosus deleted the shader_is_equal/zero_approx branch September 20, 2023 10:29
@Calinou
Copy link
Member

Calinou commented Sep 20, 2023

We discussed this in the Rendering meeting on September 6. Those present in the meeting felt that adding this function into GDShaders is problematic as it mixed GLSL and GDScript paradigms, and doesn't actually solve the issue of users not understanding floating point precision.

Could we have a built-in EPSILON constant to make approximate comparisons easier, so you don't have to define it manually every time you need it?

@QbieShay
Copy link
Contributor

I think writing < EPSILON or < 0.001 is free enough

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

Successfully merging this pull request may close these issues.

7 participants