render: add MSAA support
This commit is contained in:
		
							parent
							
								
									a2c1a90695
								
							
						
					
					
						commit
						ca87359c6e
					
				@ -63,6 +63,10 @@ path = "examples/2d/texture_atlas.rs"
 | 
			
		||||
name = "load_model"
 | 
			
		||||
path = "examples/3d/load_model.rs"
 | 
			
		||||
 | 
			
		||||
[[example]]
 | 
			
		||||
name = "msaa"
 | 
			
		||||
path = "examples/3d/msaa.rs"
 | 
			
		||||
 | 
			
		||||
[[example]]
 | 
			
		||||
name = "parenting"
 | 
			
		||||
path = "examples/3d/parenting.rs"
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ pub use once_cell;
 | 
			
		||||
 | 
			
		||||
pub mod prelude {
 | 
			
		||||
    pub use crate::{
 | 
			
		||||
        base::Msaa,
 | 
			
		||||
        color::Color,
 | 
			
		||||
        draw::Draw,
 | 
			
		||||
        entity::*,
 | 
			
		||||
@ -26,6 +27,7 @@ pub mod prelude {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use crate::prelude::*;
 | 
			
		||||
use base::Msaa;
 | 
			
		||||
use bevy_app::prelude::*;
 | 
			
		||||
use bevy_asset::AddAsset;
 | 
			
		||||
use bevy_ecs::{IntoQuerySystem, IntoThreadLocalSystem};
 | 
			
		||||
@ -131,10 +133,15 @@ impl AppPlugin for RenderPlugin {
 | 
			
		||||
                shader::clear_shader_defs_system.system(),
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        if app.resources().get::<Msaa>().is_none() {
 | 
			
		||||
            app.init_resource::<Msaa>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let Some(ref config) = self.base_render_graph_config {
 | 
			
		||||
            let resources = app.resources();
 | 
			
		||||
            let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
 | 
			
		||||
            render_graph.add_base_graph(config);
 | 
			
		||||
            let msaa = resources.get::<Msaa>().unwrap();
 | 
			
		||||
            render_graph.add_base_graph(config, &msaa);
 | 
			
		||||
            let mut active_cameras = resources.get_mut::<ActiveCameras>().unwrap();
 | 
			
		||||
            if config.add_3d_camera {
 | 
			
		||||
                active_cameras.add(base::camera::CAMERA3D);
 | 
			
		||||
 | 
			
		||||
@ -7,11 +7,23 @@ use bevy_asset::{Assets, Handle};
 | 
			
		||||
use once_cell::sync::Lazy;
 | 
			
		||||
use std::collections::{HashMap, HashSet};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Eq, PartialEq, Debug, Default)]
 | 
			
		||||
#[derive(Clone, Eq, PartialEq, Debug)]
 | 
			
		||||
pub struct PipelineSpecialization {
 | 
			
		||||
    pub shader_specialization: ShaderSpecialization,
 | 
			
		||||
    pub primitive_topology: PrimitiveTopology,
 | 
			
		||||
    pub dynamic_bindings: Vec<DynamicBinding>,
 | 
			
		||||
    pub sample_count: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for PipelineSpecialization {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            sample_count: 1,
 | 
			
		||||
            shader_specialization: Default::default(),
 | 
			
		||||
            primitive_topology: Default::default(),
 | 
			
		||||
            dynamic_bindings: Default::default(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PipelineSpecialization {
 | 
			
		||||
@ -145,6 +157,8 @@ impl PipelineCompiler {
 | 
			
		||||
            Some(vertex_buffer_descriptors),
 | 
			
		||||
            &pipeline_specialization.dynamic_bindings,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        specialized_descriptor.sample_count = pipeline_specialization.sample_count;
 | 
			
		||||
        specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
 | 
			
		||||
 | 
			
		||||
        let specialized_pipeline_handle = pipelines.add(specialized_descriptor);
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
use super::{PipelineDescriptor, PipelineSpecialization};
 | 
			
		||||
use crate::{
 | 
			
		||||
    draw::{Draw, DrawContext, DrawError, Drawable},
 | 
			
		||||
    renderer::RenderResourceBindings,
 | 
			
		||||
    renderer::RenderResourceBindings, prelude::Msaa,
 | 
			
		||||
};
 | 
			
		||||
use bevy_asset::Handle;
 | 
			
		||||
use bevy_ecs::{Query, ResMut};
 | 
			
		||||
use bevy_ecs::{Query, ResMut, Res};
 | 
			
		||||
use bevy_property::Properties;
 | 
			
		||||
#[derive(Properties, Default, Clone)]
 | 
			
		||||
pub struct RenderPipeline {
 | 
			
		||||
@ -104,9 +104,14 @@ impl<'a> Drawable for DrawableRenderPipelines<'a> {
 | 
			
		||||
pub fn draw_render_pipelines_system(
 | 
			
		||||
    mut draw_context: DrawContext,
 | 
			
		||||
    mut render_resource_bindings: ResMut<RenderResourceBindings>,
 | 
			
		||||
    msaa: Res<Msaa>,
 | 
			
		||||
    mut query: Query<(&mut Draw, &mut RenderPipelines)>,
 | 
			
		||||
) {
 | 
			
		||||
    for (mut draw, mut render_pipelines) in &mut query.iter() {
 | 
			
		||||
        for pipeline in render_pipelines.pipelines.iter_mut() {
 | 
			
		||||
            pipeline.specialization.sample_count = msaa.samples;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut drawable = DrawableRenderPipelines {
 | 
			
		||||
            render_pipelines: &mut render_pipelines,
 | 
			
		||||
            render_resource_bindings: &mut render_resource_bindings,
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,18 @@ use crate::{
 | 
			
		||||
};
 | 
			
		||||
use bevy_window::WindowId;
 | 
			
		||||
 | 
			
		||||
pub struct Msaa {
 | 
			
		||||
    pub samples: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Msaa {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            samples: 4,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct BaseRenderGraphConfig {
 | 
			
		||||
    pub add_2d_camera: bool,
 | 
			
		||||
    pub add_3d_camera: bool,
 | 
			
		||||
@ -28,6 +40,7 @@ pub mod node {
 | 
			
		||||
    pub const CAMERA2D: &str = "camera2d";
 | 
			
		||||
    pub const TEXTURE_COPY: &str = "texture_copy";
 | 
			
		||||
    pub const MAIN_DEPTH_TEXTURE: &str = "main_pass_depth_texture";
 | 
			
		||||
    pub const MAIN_SAMPLED_COLOR_ATTACHMENT: &str = "main_pass_sampled_color_attachment";
 | 
			
		||||
    pub const MAIN_PASS: &str = "main_pass";
 | 
			
		||||
    pub const SHARED_BUFFERS: &str = "shared_buffers";
 | 
			
		||||
}
 | 
			
		||||
@ -53,11 +66,11 @@ impl Default for BaseRenderGraphConfig {
 | 
			
		||||
/// By itself this graph doesn't do much, but it allows Render plugins to interop with each other by having a common
 | 
			
		||||
/// set of nodes. It can be customized using `BaseRenderGraphConfig`.
 | 
			
		||||
pub trait BaseRenderGraphBuilder {
 | 
			
		||||
    fn add_base_graph(&mut self, config: &BaseRenderGraphConfig) -> &mut Self;
 | 
			
		||||
    fn add_base_graph(&mut self, config: &BaseRenderGraphConfig, msaa: &Msaa) -> &mut Self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl BaseRenderGraphBuilder for RenderGraph {
 | 
			
		||||
    fn add_base_graph(&mut self, config: &BaseRenderGraphConfig) -> &mut Self {
 | 
			
		||||
    fn add_base_graph(&mut self, config: &BaseRenderGraphConfig, msaa: &Msaa) -> &mut Self {
 | 
			
		||||
        self.add_node(node::TEXTURE_COPY, TextureCopyNode::default());
 | 
			
		||||
        if config.add_3d_camera {
 | 
			
		||||
            self.add_system_node(node::CAMERA3D, CameraNode::new(camera::CAMERA3D));
 | 
			
		||||
@ -80,7 +93,7 @@ impl BaseRenderGraphBuilder for RenderGraph {
 | 
			
		||||
                            height: 1,
 | 
			
		||||
                        },
 | 
			
		||||
                        mip_level_count: 1,
 | 
			
		||||
                        sample_count: 1,
 | 
			
		||||
                        sample_count: msaa.samples,
 | 
			
		||||
                        dimension: TextureDimension::D2,
 | 
			
		||||
                        format: TextureFormat::Depth32Float, // PERF: vulkan docs recommend using 24 bit depth for better performance
 | 
			
		||||
                        usage: TextureUsage::OUTPUT_ATTACHMENT,
 | 
			
		||||
@ -90,15 +103,29 @@ impl BaseRenderGraphBuilder for RenderGraph {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if config.add_main_pass {
 | 
			
		||||
            let mut main_pass_node = PassNode::<&MainPass>::new(PassDescriptor {
 | 
			
		||||
                color_attachments: vec![RenderPassColorAttachmentDescriptor {
 | 
			
		||||
                    attachment: TextureAttachment::Input("color".to_string()),
 | 
			
		||||
            let color_attachment = if msaa.samples > 1 {
 | 
			
		||||
                RenderPassColorAttachmentDescriptor {
 | 
			
		||||
                    attachment: TextureAttachment::Input("color_attachment".to_string()),
 | 
			
		||||
                    resolve_target: Some(TextureAttachment::Input(
 | 
			
		||||
                        "color_resolve_target".to_string(),
 | 
			
		||||
                    )),
 | 
			
		||||
                    ops: Operations {
 | 
			
		||||
                        load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.1)),
 | 
			
		||||
                        store: true,
 | 
			
		||||
                    },
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                RenderPassColorAttachmentDescriptor {
 | 
			
		||||
                    attachment: TextureAttachment::Input("color_attachment".to_string()),
 | 
			
		||||
                    resolve_target: None,
 | 
			
		||||
                    ops: Operations {
 | 
			
		||||
                        load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.1)),
 | 
			
		||||
                        store: true,
 | 
			
		||||
                    },
 | 
			
		||||
                }],
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            let mut main_pass_node = PassNode::<&MainPass>::new(PassDescriptor {
 | 
			
		||||
                color_attachments: vec![color_attachment],
 | 
			
		||||
                depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor {
 | 
			
		||||
                    attachment: TextureAttachment::Input("depth".to_string()),
 | 
			
		||||
                    depth_ops: Some(Operations {
 | 
			
		||||
@ -107,7 +134,7 @@ impl BaseRenderGraphBuilder for RenderGraph {
 | 
			
		||||
                    }),
 | 
			
		||||
                    stencil_ops: None,
 | 
			
		||||
                }),
 | 
			
		||||
                sample_count: 1,
 | 
			
		||||
                sample_count: msaa.samples,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            main_pass_node.use_default_clear_color(0);
 | 
			
		||||
@ -146,7 +173,40 @@ impl BaseRenderGraphBuilder for RenderGraph {
 | 
			
		||||
                node::PRIMARY_SWAP_CHAIN,
 | 
			
		||||
                WindowSwapChainNode::OUT_TEXTURE,
 | 
			
		||||
                node::MAIN_PASS,
 | 
			
		||||
                "color",
 | 
			
		||||
                if msaa.samples > 1 {
 | 
			
		||||
                    "color_resolve_target"
 | 
			
		||||
                } else {
 | 
			
		||||
                    "color_attachment"
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if msaa.samples > 1 {
 | 
			
		||||
            self.add_node(
 | 
			
		||||
                node::MAIN_SAMPLED_COLOR_ATTACHMENT,
 | 
			
		||||
                WindowTextureNode::new(
 | 
			
		||||
                    WindowId::primary(),
 | 
			
		||||
                    TextureDescriptor {
 | 
			
		||||
                        size: Extent3d {
 | 
			
		||||
                            depth: 1,
 | 
			
		||||
                            width: 1,
 | 
			
		||||
                            height: 1,
 | 
			
		||||
                        },
 | 
			
		||||
                        mip_level_count: 1,
 | 
			
		||||
                        sample_count: msaa.samples,
 | 
			
		||||
                        dimension: TextureDimension::D2,
 | 
			
		||||
                        format: TextureFormat::Bgra8UnormSrgb,
 | 
			
		||||
                        usage: TextureUsage::OUTPUT_ATTACHMENT,
 | 
			
		||||
                    },
 | 
			
		||||
                ),
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            self.add_slot_edge(
 | 
			
		||||
                node::MAIN_SAMPLED_COLOR_ATTACHMENT,
 | 
			
		||||
                WindowSwapChainNode::OUT_TEXTURE,
 | 
			
		||||
                node::MAIN_PASS,
 | 
			
		||||
                "color_attachment",
 | 
			
		||||
            )
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ pub struct PassNode<Q: HecsQuery> {
 | 
			
		||||
    inputs: Vec<ResourceSlotInfo>,
 | 
			
		||||
    cameras: Vec<CameraInfo>,
 | 
			
		||||
    color_attachment_input_indices: Vec<Option<usize>>,
 | 
			
		||||
    color_resolve_target_indices: Vec<Option<usize>>,
 | 
			
		||||
    depth_stencil_attachment_input_index: Option<usize>,
 | 
			
		||||
    default_clear_color_inputs: Vec<usize>,
 | 
			
		||||
    camera_bind_group_descriptor: BindGroupDescriptor,
 | 
			
		||||
@ -34,26 +35,37 @@ impl<Q: HecsQuery> PassNode<Q> {
 | 
			
		||||
    pub fn new(descriptor: PassDescriptor) -> Self {
 | 
			
		||||
        let mut inputs = Vec::new();
 | 
			
		||||
        let mut color_attachment_input_indices = Vec::new();
 | 
			
		||||
        let mut color_resolve_target_indices = Vec::new();
 | 
			
		||||
        for color_attachment in descriptor.color_attachments.iter() {
 | 
			
		||||
            if let TextureAttachment::Input(ref name) = color_attachment.attachment {
 | 
			
		||||
                color_attachment_input_indices.push(Some(inputs.len()));
 | 
			
		||||
                inputs.push(ResourceSlotInfo::new(
 | 
			
		||||
                    name.to_string(),
 | 
			
		||||
                    RenderResourceType::Texture,
 | 
			
		||||
                ));
 | 
			
		||||
                color_attachment_input_indices.push(Some(inputs.len() - 1));
 | 
			
		||||
            } else {
 | 
			
		||||
                color_attachment_input_indices.push(None);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if let Some(TextureAttachment::Input(ref name)) = color_attachment.resolve_target {
 | 
			
		||||
                color_resolve_target_indices.push(Some(inputs.len()));
 | 
			
		||||
                inputs.push(ResourceSlotInfo::new(
 | 
			
		||||
                    name.to_string(),
 | 
			
		||||
                    RenderResourceType::Texture,
 | 
			
		||||
                ));
 | 
			
		||||
            } else {
 | 
			
		||||
                color_resolve_target_indices.push(None);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut depth_stencil_attachment_input_index = None;
 | 
			
		||||
        if let Some(ref depth_stencil_attachment) = descriptor.depth_stencil_attachment {
 | 
			
		||||
            if let TextureAttachment::Input(ref name) = depth_stencil_attachment.attachment {
 | 
			
		||||
                depth_stencil_attachment_input_index = Some(inputs.len());
 | 
			
		||||
                inputs.push(ResourceSlotInfo::new(
 | 
			
		||||
                    name.to_string(),
 | 
			
		||||
                    RenderResourceType::Texture,
 | 
			
		||||
                ));
 | 
			
		||||
                depth_stencil_attachment_input_index = Some(inputs.len() - 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -74,6 +86,7 @@ impl<Q: HecsQuery> PassNode<Q> {
 | 
			
		||||
            inputs,
 | 
			
		||||
            cameras: Vec::new(),
 | 
			
		||||
            color_attachment_input_indices,
 | 
			
		||||
            color_resolve_target_indices,
 | 
			
		||||
            depth_stencil_attachment_input_index,
 | 
			
		||||
            default_clear_color_inputs: Vec::new(),
 | 
			
		||||
            camera_bind_group_descriptor,
 | 
			
		||||
@ -120,6 +133,10 @@ impl<Q: HecsQuery + Send + Sync + 'static> Node for PassNode<Q> {
 | 
			
		||||
                color_attachment.attachment =
 | 
			
		||||
                    TextureAttachment::Id(input.get(input_index).unwrap().get_texture().unwrap());
 | 
			
		||||
            }
 | 
			
		||||
            if let Some(input_index) = self.color_resolve_target_indices[i] {
 | 
			
		||||
                color_attachment.resolve_target =
 | 
			
		||||
                    Some(TextureAttachment::Id(input.get(input_index).unwrap().get_texture().unwrap()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let Some(input_index) = self.depth_stencil_attachment_input_index {
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ use bevy_render::{
 | 
			
		||||
    renderer::{
 | 
			
		||||
        AssetRenderResourceBindings, BindGroup, BufferUsage, RenderResourceBindings,
 | 
			
		||||
        RenderResourceId,
 | 
			
		||||
    },
 | 
			
		||||
    }, prelude::Msaa,
 | 
			
		||||
};
 | 
			
		||||
use bevy_sprite::{TextureAtlas, TextureAtlasSprite};
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@ pub struct DrawableText<'a> {
 | 
			
		||||
    pub container_size: Vec2,
 | 
			
		||||
    pub style: &'a TextStyle,
 | 
			
		||||
    pub text: &'a str,
 | 
			
		||||
    pub msaa: &'a Msaa,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Drawable for DrawableText<'a> {
 | 
			
		||||
@ -45,8 +46,10 @@ impl<'a> Drawable for DrawableText<'a> {
 | 
			
		||||
        context.set_pipeline(
 | 
			
		||||
            draw,
 | 
			
		||||
            bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE,
 | 
			
		||||
            // TODO: remove this shader def specialization when its easier to manually bind global render resources to specific bind groups
 | 
			
		||||
            &PipelineSpecialization::default(),
 | 
			
		||||
            &PipelineSpecialization {
 | 
			
		||||
                sample_count: self.msaa.samples,
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            },
 | 
			
		||||
        )?;
 | 
			
		||||
 | 
			
		||||
        let render_resource_context = &**context.render_resource_context;
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ use bevy_render::{
 | 
			
		||||
        RenderPassDepthStencilAttachmentDescriptor, TextureAttachment,
 | 
			
		||||
    },
 | 
			
		||||
    pipeline::*,
 | 
			
		||||
    prelude::Msaa,
 | 
			
		||||
    render_graph::{
 | 
			
		||||
        base, CameraNode, PassNode, RenderGraph, RenderResourcesNode, WindowSwapChainNode,
 | 
			
		||||
        WindowTextureNode,
 | 
			
		||||
@ -82,17 +83,31 @@ impl UiRenderGraphBuilder for RenderGraph {
 | 
			
		||||
    fn add_ui_graph(&mut self, resources: &Resources) -> &mut Self {
 | 
			
		||||
        let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
 | 
			
		||||
        let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
 | 
			
		||||
        let msaa = resources.get::<Msaa>().unwrap();
 | 
			
		||||
        pipelines.set(UI_PIPELINE_HANDLE, build_ui_pipeline(&mut shaders));
 | 
			
		||||
 | 
			
		||||
        let mut ui_pass_node = PassNode::<&Node>::new(PassDescriptor {
 | 
			
		||||
            color_attachments: vec![RenderPassColorAttachmentDescriptor {
 | 
			
		||||
                attachment: TextureAttachment::Input("color".to_string()),
 | 
			
		||||
        let color_attachment = if msaa.samples > 1 {
 | 
			
		||||
            RenderPassColorAttachmentDescriptor {
 | 
			
		||||
                attachment: TextureAttachment::Input("color_attachment".to_string()),
 | 
			
		||||
                resolve_target: Some(TextureAttachment::Input("color_resolve_target".to_string())),
 | 
			
		||||
                ops: Operations {
 | 
			
		||||
                    load: LoadOp::Load,
 | 
			
		||||
                    store: true,
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            RenderPassColorAttachmentDescriptor {
 | 
			
		||||
                attachment: TextureAttachment::Input("color_attachment".to_string()),
 | 
			
		||||
                resolve_target: None,
 | 
			
		||||
                ops: Operations {
 | 
			
		||||
                    load: LoadOp::Load,
 | 
			
		||||
                    store: true,
 | 
			
		||||
                },
 | 
			
		||||
            }],
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let mut ui_pass_node = PassNode::<&Node>::new(PassDescriptor {
 | 
			
		||||
            color_attachments: vec![color_attachment],
 | 
			
		||||
            depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor {
 | 
			
		||||
                attachment: TextureAttachment::Input("depth".to_string()),
 | 
			
		||||
                depth_ops: Some(Operations {
 | 
			
		||||
@ -101,7 +116,7 @@ impl UiRenderGraphBuilder for RenderGraph {
 | 
			
		||||
                }),
 | 
			
		||||
                stencil_ops: None,
 | 
			
		||||
            }),
 | 
			
		||||
            sample_count: 1,
 | 
			
		||||
            sample_count: msaa.samples,
 | 
			
		||||
        });
 | 
			
		||||
        ui_pass_node.add_camera(camera::UI_CAMERA);
 | 
			
		||||
        self.add_node(node::UI_PASS, ui_pass_node);
 | 
			
		||||
@ -110,7 +125,11 @@ impl UiRenderGraphBuilder for RenderGraph {
 | 
			
		||||
            base::node::PRIMARY_SWAP_CHAIN,
 | 
			
		||||
            WindowSwapChainNode::OUT_TEXTURE,
 | 
			
		||||
            node::UI_PASS,
 | 
			
		||||
            "color",
 | 
			
		||||
            if msaa.samples > 1 {
 | 
			
		||||
                "color_resolve_target"
 | 
			
		||||
            } else {
 | 
			
		||||
                "color_attachment"
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
@ -122,6 +141,17 @@ impl UiRenderGraphBuilder for RenderGraph {
 | 
			
		||||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
        if msaa.samples > 1 {
 | 
			
		||||
            self.add_slot_edge(
 | 
			
		||||
                base::node::MAIN_SAMPLED_COLOR_ATTACHMENT,
 | 
			
		||||
                WindowSwapChainNode::OUT_TEXTURE,
 | 
			
		||||
                node::UI_PASS,
 | 
			
		||||
                "color_attachment",
 | 
			
		||||
            )
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // ensure ui pass runs after main pass
 | 
			
		||||
        self.add_node_edge(base::node::MAIN_PASS, node::UI_PASS)
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ use bevy_math::Size;
 | 
			
		||||
use bevy_render::{
 | 
			
		||||
    draw::{Draw, DrawContext, Drawable},
 | 
			
		||||
    renderer::{AssetRenderResourceBindings, RenderResourceBindings},
 | 
			
		||||
    texture::Texture,
 | 
			
		||||
    texture::Texture, prelude::Msaa,
 | 
			
		||||
};
 | 
			
		||||
use bevy_sprite::TextureAtlas;
 | 
			
		||||
use bevy_text::{DrawableText, Font, FontAtlasSet, TextStyle};
 | 
			
		||||
@ -51,6 +51,7 @@ pub fn text_system(
 | 
			
		||||
pub fn draw_text_system(
 | 
			
		||||
    mut draw_context: DrawContext,
 | 
			
		||||
    fonts: Res<Assets<Font>>,
 | 
			
		||||
    msaa: Res<Msaa>,
 | 
			
		||||
    font_atlas_sets: Res<Assets<FontAtlasSet>>,
 | 
			
		||||
    texture_atlases: Res<Assets<TextureAtlas>>,
 | 
			
		||||
    mut render_resource_bindings: ResMut<RenderResourceBindings>,
 | 
			
		||||
@ -69,6 +70,7 @@ pub fn draw_text_system(
 | 
			
		||||
            render_resource_bindings: &mut render_resource_bindings,
 | 
			
		||||
            asset_render_resource_bindings: &mut asset_render_resource_bindings,
 | 
			
		||||
            position,
 | 
			
		||||
            msaa: &msaa,
 | 
			
		||||
            style: &text.style,
 | 
			
		||||
            text: &text.value,
 | 
			
		||||
            container_size: node.size,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								examples/3d/msaa.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								examples/3d/msaa.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
use bevy::prelude::*;
 | 
			
		||||
 | 
			
		||||
/// This example shows how to configure Multi-Sample Anti-Aliasing. Setting the sample count higher will result in smoother edges,
 | 
			
		||||
/// but it will also increase the cost to render those edges. The range should generally be somewhere between 1 (no multi sampling,
 | 
			
		||||
/// but cheap) to 8 (crisp but expensive)
 | 
			
		||||
fn main() {
 | 
			
		||||
    App::build()
 | 
			
		||||
        .add_resource(Msaa { samples: 4 })
 | 
			
		||||
        .add_default_plugins()
 | 
			
		||||
        .add_startup_system(setup.system())
 | 
			
		||||
        .run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// set up a simple 3D scene
 | 
			
		||||
fn setup(
 | 
			
		||||
    mut commands: Commands,
 | 
			
		||||
    mut meshes: ResMut<Assets<Mesh>>,
 | 
			
		||||
    mut materials: ResMut<Assets<StandardMaterial>>,
 | 
			
		||||
) {
 | 
			
		||||
    // add entities to the world
 | 
			
		||||
    commands
 | 
			
		||||
        // cube
 | 
			
		||||
        .spawn(PbrComponents {
 | 
			
		||||
            mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
 | 
			
		||||
            material: materials.add(StandardMaterial {
 | 
			
		||||
                albedo: Color::rgb(0.5, 0.4, 0.3),
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            }),
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        })
 | 
			
		||||
        // light
 | 
			
		||||
        .spawn(LightComponents {
 | 
			
		||||
            translation: Translation::new(4.0, 8.0, 4.0),
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        })
 | 
			
		||||
        // camera
 | 
			
		||||
        .spawn(Camera3dComponents {
 | 
			
		||||
            transform: Transform::new_sync_disabled(Mat4::face_toward(
 | 
			
		||||
                Vec3::new(-3.0, 3.0, 5.0),
 | 
			
		||||
                Vec3::new(0.0, 0.0, 0.0),
 | 
			
		||||
                Vec3::new(0.0, 1.0, 0.0),
 | 
			
		||||
            )),
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        });
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user