Provide GlobalsUniform in UiMaterial shaders (#10739)
# Objective `GlobalsUniform` provides the current time to shaders, which is useful for animations. `UiMaterial` is an abstraction that makes it easier to write custom shaders for UI elements. This PR makes it possible to use the `GlobalsUniform` in `UiMaterial` shaders. ## Solution The `GlobalsUniform` is bound to `@group(0) @binding(1)`. It is accessible in shaders with: ```wgsl #import bevy_render::globals::Globals @group(0) @binding(1) var<uniform> globals: Globals; ``` --- ## Changelog Added `GlobalsUniform` in `UiMaterial` shaders ## Discussion Should I modify the existing ui_material example to showcase this?
This commit is contained in:
parent
0e9f6e92ea
commit
e44b74fb6a
@ -1,8 +1,13 @@
|
|||||||
#import bevy_render::view::View
|
#import bevy_render::{
|
||||||
|
view::View,
|
||||||
|
globals::Globals,
|
||||||
|
}
|
||||||
#import bevy_ui::ui_vertex_output::UiVertexOutput
|
#import bevy_ui::ui_vertex_output::UiVertexOutput
|
||||||
|
|
||||||
@group(0) @binding(0)
|
@group(0) @binding(0)
|
||||||
var<uniform> view: View;
|
var<uniform> view: View;
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var<uniform> globals: Globals;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vertex(
|
fn vertex(
|
||||||
|
|||||||
@ -15,6 +15,7 @@ use bevy_ecs::{
|
|||||||
use bevy_math::{Mat4, Rect, Vec2, Vec4Swizzles};
|
use bevy_math::{Mat4, Rect, Vec2, Vec4Swizzles};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
extract_component::ExtractComponentPlugin,
|
extract_component::ExtractComponentPlugin,
|
||||||
|
globals::{GlobalsBuffer, GlobalsUniform},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_phase::*,
|
render_phase::*,
|
||||||
render_resource::{binding_types::uniform_buffer, *},
|
render_resource::{binding_types::uniform_buffer, *},
|
||||||
@ -225,11 +226,15 @@ impl<M: UiMaterial> FromWorld for UiMaterialPipeline<M> {
|
|||||||
|
|
||||||
let view_layout = render_device.create_bind_group_layout(
|
let view_layout = render_device.create_bind_group_layout(
|
||||||
"ui_view_layout",
|
"ui_view_layout",
|
||||||
&BindGroupLayoutEntries::single(
|
&BindGroupLayoutEntries::sequential(
|
||||||
ShaderStages::VERTEX_FRAGMENT,
|
ShaderStages::VERTEX_FRAGMENT,
|
||||||
|
(
|
||||||
uniform_buffer::<ViewUniform>(true),
|
uniform_buffer::<ViewUniform>(true),
|
||||||
|
uniform_buffer::<GlobalsUniform>(false),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
UiMaterialPipeline {
|
UiMaterialPipeline {
|
||||||
ui_layout,
|
ui_layout,
|
||||||
view_layout,
|
view_layout,
|
||||||
@ -430,18 +435,22 @@ pub fn prepare_uimaterial_nodes<M: UiMaterial>(
|
|||||||
mut ui_meta: ResMut<UiMaterialMeta<M>>,
|
mut ui_meta: ResMut<UiMaterialMeta<M>>,
|
||||||
mut extracted_uinodes: ResMut<ExtractedUiMaterialNodes<M>>,
|
mut extracted_uinodes: ResMut<ExtractedUiMaterialNodes<M>>,
|
||||||
view_uniforms: Res<ViewUniforms>,
|
view_uniforms: Res<ViewUniforms>,
|
||||||
|
globals_buffer: Res<GlobalsBuffer>,
|
||||||
ui_material_pipeline: Res<UiMaterialPipeline<M>>,
|
ui_material_pipeline: Res<UiMaterialPipeline<M>>,
|
||||||
mut phases: Query<&mut RenderPhase<TransparentUi>>,
|
mut phases: Query<&mut RenderPhase<TransparentUi>>,
|
||||||
mut previous_len: Local<usize>,
|
mut previous_len: Local<usize>,
|
||||||
) {
|
) {
|
||||||
if let Some(view_binding) = view_uniforms.uniforms.binding() {
|
if let (Some(view_binding), Some(globals_binding)) = (
|
||||||
|
view_uniforms.uniforms.binding(),
|
||||||
|
globals_buffer.buffer.binding(),
|
||||||
|
) {
|
||||||
let mut batches: Vec<(Entity, UiMaterialBatch<M>)> = Vec::with_capacity(*previous_len);
|
let mut batches: Vec<(Entity, UiMaterialBatch<M>)> = Vec::with_capacity(*previous_len);
|
||||||
|
|
||||||
ui_meta.vertices.clear();
|
ui_meta.vertices.clear();
|
||||||
ui_meta.view_bind_group = Some(render_device.create_bind_group(
|
ui_meta.view_bind_group = Some(render_device.create_bind_group(
|
||||||
"ui_material_view_bind_group",
|
"ui_material_view_bind_group",
|
||||||
&ui_material_pipeline.view_layout,
|
&ui_material_pipeline.view_layout,
|
||||||
&BindGroupEntries::single(view_binding),
|
&BindGroupEntries::sequential((view_binding, globals_binding)),
|
||||||
));
|
));
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
|
|||||||
@ -67,7 +67,8 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader
|
|||||||
///
|
///
|
||||||
/// If you only use the fragment shader make sure to import `UiVertexOutput` from
|
/// If you only use the fragment shader make sure to import `UiVertexOutput` from
|
||||||
/// `bevy_ui::ui_vertex_output` in your wgsl shader.
|
/// `bevy_ui::ui_vertex_output` in your wgsl shader.
|
||||||
/// Also note that bind group 0 is always bound to the [`View Uniform`](bevy_render::view::ViewUniform).
|
/// Also note that bind group 0 is always bound to the [`View Uniform`](bevy_render::view::ViewUniform)
|
||||||
|
/// and the [`Globals Uniform`](bevy_render::globals::GlobalsUniform).
|
||||||
///
|
///
|
||||||
/// ```wgsl
|
/// ```wgsl
|
||||||
/// #import bevy_ui::ui_vertex_output UiVertexOutput
|
/// #import bevy_ui::ui_vertex_output UiVertexOutput
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user