bevy_ui_render/
pipeline.rs1use bevy_asset::{load_embedded_asset, AssetServer, Handle};
2use bevy_ecs::prelude::*;
3use bevy_image::BevyDefault as _;
4use bevy_mesh::VertexBufferLayout;
5use bevy_render::{
6 render_resource::{
7 binding_types::{sampler, texture_2d, uniform_buffer},
8 *,
9 },
10 renderer::RenderDevice,
11 view::{ViewTarget, ViewUniform},
12};
13use bevy_shader::Shader;
14use bevy_utils::default;
15
16#[derive(Resource)]
17pub struct UiPipeline {
18 pub view_layout: BindGroupLayout,
19 pub image_layout: BindGroupLayout,
20 pub shader: Handle<Shader>,
21}
22
23pub fn init_ui_pipeline(
24 mut commands: Commands,
25 render_device: Res<RenderDevice>,
26 asset_server: Res<AssetServer>,
27) {
28 let view_layout = render_device.create_bind_group_layout(
29 "ui_view_layout",
30 &BindGroupLayoutEntries::single(
31 ShaderStages::VERTEX_FRAGMENT,
32 uniform_buffer::<ViewUniform>(true),
33 ),
34 );
35
36 let image_layout = render_device.create_bind_group_layout(
37 "ui_image_layout",
38 &BindGroupLayoutEntries::sequential(
39 ShaderStages::FRAGMENT,
40 (
41 texture_2d(TextureSampleType::Float { filterable: true }),
42 sampler(SamplerBindingType::Filtering),
43 ),
44 ),
45 );
46
47 commands.insert_resource(UiPipeline {
48 view_layout,
49 image_layout,
50 shader: load_embedded_asset!(asset_server.as_ref(), "ui.wgsl"),
51 });
52}
53
54#[derive(Clone, Copy, Hash, PartialEq, Eq)]
55pub struct UiPipelineKey {
56 pub hdr: bool,
57 pub anti_alias: bool,
58}
59
60impl SpecializedRenderPipeline for UiPipeline {
61 type Key = UiPipelineKey;
62
63 fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
64 let vertex_layout = VertexBufferLayout::from_vertex_formats(
65 VertexStepMode::Vertex,
66 vec![
67 VertexFormat::Float32x3,
69 VertexFormat::Float32x2,
71 VertexFormat::Float32x4,
73 VertexFormat::Uint32,
75 VertexFormat::Float32x4,
77 VertexFormat::Float32x4,
79 VertexFormat::Float32x2,
81 VertexFormat::Float32x2,
83 ],
84 );
85 let shader_defs = if key.anti_alias {
86 vec!["ANTI_ALIAS".into()]
87 } else {
88 Vec::new()
89 };
90
91 RenderPipelineDescriptor {
92 vertex: VertexState {
93 shader: self.shader.clone(),
94 shader_defs: shader_defs.clone(),
95 buffers: vec![vertex_layout],
96 ..default()
97 },
98 fragment: Some(FragmentState {
99 shader: self.shader.clone(),
100 shader_defs,
101 targets: vec![Some(ColorTargetState {
102 format: if key.hdr {
103 ViewTarget::TEXTURE_FORMAT_HDR
104 } else {
105 TextureFormat::bevy_default()
106 },
107 blend: Some(BlendState::ALPHA_BLENDING),
108 write_mask: ColorWrites::ALL,
109 })],
110 ..default()
111 }),
112 layout: vec![self.view_layout.clone(), self.image_layout.clone()],
113 label: Some("ui_pipeline".into()),
114 ..default()
115 }
116 }
117}