-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Merged by Bors] - add globals to mesh view bind group #5409
Conversation
I used this PR for my animated shader: https://youtu.be/BanMIX3_GiU |
6719d22
to
5ec6a7b
Compare
I'm very much in favour of this, i know at least Unity offers this out of the box, I would imagine other engines do too, but I haven't checked. I think the percentage of users that would need this in a shader is higher than the percentage of users that can easily understand how to implement it themselves, since it requires getting to work at a lower level than deriving On thing I would consider: Maybe the solution is to have a different example that shows setting the bing group for a different functionality, and adapt |
I'll update the animate_shader example soon to reflect the changes and after some quick discussion with @superdump we agreed that we indeed need lower level examples instead of relying on examples showcasing multiple things. These will be added in a separate PR. See #5843 |
5ec6a7b
to
ab821cb
Compare
5217250
to
648075a
Compare
I added the frame count as a wrapping u32. Unfotunately, I can't rely on the |
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'm not sure what I think of the name Globals
. I wanted to say GlobalUniforms
but then we'd need GlobalUniformsUniform
. :)
Yeah, I was hoping somebody would have proposed a better name. I guess since this is only for time stuff this could just be a |
something around frame metadata rather than globals? |
The time since startup value isn't really related to the frame though, since it's just the time since startup (or at least, the time since the last wrap period). Godot, unreal and unity all seem to put this under Time. |
Oh you mean the frame start time 😄 |
# Objective - Sometimes, like when using shaders, you can only use a time value in `f32`. Unfortunately this suffers from floating precision issues pretty quickly. The standard approach to this problem is to wrap the time after a given period - This is necessary for #5409 ## Solution - Add a `seconds_since_last_wrapping_period` method on `Time` that returns a `f32` that is the `seconds_since_startup` modulo the `max_wrapping_period` --- ## Changelog Added `seconds_since_last_wrapping_period` to `Time` ## Additional info I'm very opened to hearing better names. I don't really like the current naming, I just went with something descriptive. Co-authored-by: Charles <IceSentry@users.noreply.github.com>
b0020e5
to
3e1f0ab
Compare
I rebased and used the now merged wrapping time api. This should be ready for a final review pass I think. |
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.
Thanks a lot for this! This is going to be a huge time saver for users, imo. It's also great to see the animate_shader
example be way more accessible.
I have a comment about 2d, that I don't necessarily think has to be addressed in this PR, but maybe it's worth tracking with an issue afterwards..? Not sure what you people think.
// The time since startup data is in the globals binding which is part of the mesh_view_bindings import | ||
#import bevy_pbr::mesh_view_bindings |
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.
What about 2d users? They may not depend on bevy_pbr
, but it's possible they still want to access the globals binding.
Possible solutions (imo):
- make the globals binding available also in
bevy_sprite::mesh2d_view_bindings
- have an example with sprites that shows importing
mesh_view_bindings
frombevy_pbr
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.
Good point, I'll address this in a follow up PR. I honestly didn't think of that. I'll probably add the bindings to mesh2d_view_bindings
. Although, I wonder if we could have some sort of "core" bindings that are shared between both.
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.
LGTM. Just one small nit. :)
Co-authored-by: Robert Swain <robert.swain@gmail.com>
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.
bors r+
# Objective - It's often really useful to have access to the time when writing shaders. ## Solution - Add a UnifformBuffer in the mesh view bind group - This buffer contains the time, delta time and a wrapping frame count https://user-images.githubusercontent.com/8348954/180130314-97948c2a-2d11-423d-a9c4-fb5c9d1892c7.mp4 --- ## Changelog - Added a `GlobalsUniform` at position 9 of the mesh view bind group ## Notes The implementation is currently split between bevy_render and bevy_pbr because I was basing my implementation on the `ViewPlugin`. I'm not sure if that's the right way to structure it. I named this `globals` instead of just time because we could potentially add more things to it. ## References in other engines - Godot: <https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/canvas_item_shader.html#global-built-ins> - Global time since startup, in seconds, by default resets to 0 after 3600 seconds - Doesn't seem to have anything else - Unreal: <https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Materials/ExpressionReference/Constant/> - Generic time value that updates every frame. Can be paused or scaled. - Frame count node, doesn't seem to be an equivalent for shaders: <https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Utilities/GetFrameCount/> - Unity: <https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html> - time since startup in seconds. No mention of time wrapping. Stored as a `vec4(t/20, t, t*2, t*3)` where `t` is the value in seconds - Also has delta time, sin time and cos time - ShaderToy: <https://www.shadertoy.com/howto> - iTime is the time since startup in seconds. - iFrameRate - iTimeDelta - iFrame frame counter Co-authored-by: Charles <IceSentry@users.noreply.github.com>
Pull request successfully merged into main. Build succeeded: |
# Objective - Sometimes, like when using shaders, you can only use a time value in `f32`. Unfortunately this suffers from floating precision issues pretty quickly. The standard approach to this problem is to wrap the time after a given period - This is necessary for bevyengine#5409 ## Solution - Add a `seconds_since_last_wrapping_period` method on `Time` that returns a `f32` that is the `seconds_since_startup` modulo the `max_wrapping_period` --- ## Changelog Added `seconds_since_last_wrapping_period` to `Time` ## Additional info I'm very opened to hearing better names. I don't really like the current naming, I just went with something descriptive. Co-authored-by: Charles <IceSentry@users.noreply.github.com>
# Objective - It's often really useful to have access to the time when writing shaders. ## Solution - Add a UnifformBuffer in the mesh view bind group - This buffer contains the time, delta time and a wrapping frame count https://user-images.githubusercontent.com/8348954/180130314-97948c2a-2d11-423d-a9c4-fb5c9d1892c7.mp4 --- ## Changelog - Added a `GlobalsUniform` at position 9 of the mesh view bind group ## Notes The implementation is currently split between bevy_render and bevy_pbr because I was basing my implementation on the `ViewPlugin`. I'm not sure if that's the right way to structure it. I named this `globals` instead of just time because we could potentially add more things to it. ## References in other engines - Godot: <https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/canvas_item_shader.html#global-built-ins> - Global time since startup, in seconds, by default resets to 0 after 3600 seconds - Doesn't seem to have anything else - Unreal: <https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Materials/ExpressionReference/Constant/> - Generic time value that updates every frame. Can be paused or scaled. - Frame count node, doesn't seem to be an equivalent for shaders: <https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Utilities/GetFrameCount/> - Unity: <https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html> - time since startup in seconds. No mention of time wrapping. Stored as a `vec4(t/20, t, t*2, t*3)` where `t` is the value in seconds - Also has delta time, sin time and cos time - ShaderToy: <https://www.shadertoy.com/howto> - iTime is the time since startup in seconds. - iFrameRate - iTimeDelta - iFrame frame counter Co-authored-by: Charles <IceSentry@users.noreply.github.com>
# Objective - Sometimes, like when using shaders, you can only use a time value in `f32`. Unfortunately this suffers from floating precision issues pretty quickly. The standard approach to this problem is to wrap the time after a given period - This is necessary for bevyengine#5409 ## Solution - Add a `seconds_since_last_wrapping_period` method on `Time` that returns a `f32` that is the `seconds_since_startup` modulo the `max_wrapping_period` --- ## Changelog Added `seconds_since_last_wrapping_period` to `Time` ## Additional info I'm very opened to hearing better names. I don't really like the current naming, I just went with something descriptive. Co-authored-by: Charles <IceSentry@users.noreply.github.com>
# Objective - It's often really useful to have access to the time when writing shaders. ## Solution - Add a UnifformBuffer in the mesh view bind group - This buffer contains the time, delta time and a wrapping frame count https://user-images.githubusercontent.com/8348954/180130314-97948c2a-2d11-423d-a9c4-fb5c9d1892c7.mp4 --- ## Changelog - Added a `GlobalsUniform` at position 9 of the mesh view bind group ## Notes The implementation is currently split between bevy_render and bevy_pbr because I was basing my implementation on the `ViewPlugin`. I'm not sure if that's the right way to structure it. I named this `globals` instead of just time because we could potentially add more things to it. ## References in other engines - Godot: <https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/canvas_item_shader.html#global-built-ins> - Global time since startup, in seconds, by default resets to 0 after 3600 seconds - Doesn't seem to have anything else - Unreal: <https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Materials/ExpressionReference/Constant/> - Generic time value that updates every frame. Can be paused or scaled. - Frame count node, doesn't seem to be an equivalent for shaders: <https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Utilities/GetFrameCount/> - Unity: <https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html> - time since startup in seconds. No mention of time wrapping. Stored as a `vec4(t/20, t, t*2, t*3)` where `t` is the value in seconds - Also has delta time, sin time and cos time - ShaderToy: <https://www.shadertoy.com/howto> - iTime is the time since startup in seconds. - iFrameRate - iTimeDelta - iFrame frame counter Co-authored-by: Charles <IceSentry@users.noreply.github.com>
# Objective - Sometimes, like when using shaders, you can only use a time value in `f32`. Unfortunately this suffers from floating precision issues pretty quickly. The standard approach to this problem is to wrap the time after a given period - This is necessary for bevyengine#5409 ## Solution - Add a `seconds_since_last_wrapping_period` method on `Time` that returns a `f32` that is the `seconds_since_startup` modulo the `max_wrapping_period` --- ## Changelog Added `seconds_since_last_wrapping_period` to `Time` ## Additional info I'm very opened to hearing better names. I don't really like the current naming, I just went with something descriptive. Co-authored-by: Charles <IceSentry@users.noreply.github.com>
# Objective - It's often really useful to have access to the time when writing shaders. ## Solution - Add a UnifformBuffer in the mesh view bind group - This buffer contains the time, delta time and a wrapping frame count https://user-images.githubusercontent.com/8348954/180130314-97948c2a-2d11-423d-a9c4-fb5c9d1892c7.mp4 --- ## Changelog - Added a `GlobalsUniform` at position 9 of the mesh view bind group ## Notes The implementation is currently split between bevy_render and bevy_pbr because I was basing my implementation on the `ViewPlugin`. I'm not sure if that's the right way to structure it. I named this `globals` instead of just time because we could potentially add more things to it. ## References in other engines - Godot: <https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/canvas_item_shader.html#global-built-ins> - Global time since startup, in seconds, by default resets to 0 after 3600 seconds - Doesn't seem to have anything else - Unreal: <https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Materials/ExpressionReference/Constant/> - Generic time value that updates every frame. Can be paused or scaled. - Frame count node, doesn't seem to be an equivalent for shaders: <https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Utilities/GetFrameCount/> - Unity: <https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html> - time since startup in seconds. No mention of time wrapping. Stored as a `vec4(t/20, t, t*2, t*3)` where `t` is the value in seconds - Also has delta time, sin time and cos time - ShaderToy: <https://www.shadertoy.com/howto> - iTime is the time since startup in seconds. - iFrameRate - iTimeDelta - iFrame frame counter Co-authored-by: Charles <IceSentry@users.noreply.github.com>
Objective
Solution
shader_material_SH7SH4AvgA.mp4
Changelog
GlobalsUniform
at position 9 of the mesh view bind groupNotes
The implementation is currently split between bevy_render and bevy_pbr because I was basing my implementation on the
ViewPlugin
. I'm not sure if that's the right way to structure it.I named this
globals
instead of just time because we could potentially add more things to it.References in other engines
vec4(t/20, t, t*2, t*3)
wheret
is the value in seconds