Skip to content

Commit

Permalink
Sprite, UI works without picking
Browse files Browse the repository at this point in the history
Signed-off-by: Torstein Grindvik <[email protected]>
  • Loading branch information
torsteingrindvik committed Dec 23, 2022
1 parent 4e178a0 commit 9e75efe
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 104 deletions.
38 changes: 21 additions & 17 deletions crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub struct MainPass2dNode {
&'static RenderPhase<Transparent2d>,
&'static ViewTarget,
&'static Camera2d,
&'static PickingTextures,
Option<&'static PickingTextures>,
),
With<ExtractedView>,
>,
Expand Down Expand Up @@ -64,24 +64,28 @@ impl Node for MainPass2dNode {
{
#[cfg(feature = "trace")]
let _main_pass_2d = info_span!("main_pass_2d").entered();

let mut color_attachments = vec![Some(target.get_color_attachment(Operations {
load: match camera_2d.clear_color {
ClearColorConfig::Default => {
LoadOp::Clear(world.resource::<ClearColor>().0.into())
}
ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
ClearColorConfig::None => LoadOp::Load,
},
store: true,
}))];

if let Some(picking_textures) = picking_textures {
color_attachments.push(Some(picking_textures.get_color_attachment(Operations {
load: LoadOp::Clear(PickingTextures::clear_color()),
store: true,
})))
}

let pass_descriptor = RenderPassDescriptor {
label: Some("main_pass_2d"),
color_attachments: &[
Some(target.get_color_attachment(Operations {
load: match camera_2d.clear_color {
ClearColorConfig::Default => {
LoadOp::Clear(world.resource::<ClearColor>().0.into())
}
ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
ClearColorConfig::None => LoadOp::Load,
},
store: true,
})),
Some(picking_textures.get_color_attachment(Operations {
load: LoadOp::Clear(PickingTextures::clear_color()),
store: true,
})),
],
color_attachments: &color_attachments,
depth_stencil_attachment: None,
};

Expand Down
1 change: 1 addition & 0 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
true => ViewTarget::TEXTURE_FORMAT_HDR,
false => TextureFormat::bevy_default(),
};

let mut targets = vec![Some(ColorTargetState {
format,
blend,
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ struct FragmentInput {
};

struct FragmentOutput {
@location(0) color: vec4<f32>,
@location(0) color: vec4<f32>,
#ifdef PICKING
@location(1) picking: u32,
@location(1) picking: u32,
#endif
}
}

@fragment
fn fragment(in: FragmentInput) -> FragmentOutput {
Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_sprite/src/mesh2d/color_material.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ struct FragmentInput {
};

struct FragmentOutput {
@location(0) color: vec4<f32>,
@location(1) picking: u32,
}
@location(0) color: vec4<f32>,
#ifdef PICKING
@location(1) picking: u32,
#endif
}

@fragment
fn fragment(in: FragmentInput) -> FragmentOutput {
Expand All @@ -40,7 +42,10 @@ fn fragment(in: FragmentInput) -> FragmentOutput {
var out: FragmentOutput;

out.color = output_color;

#ifdef PICKING
out.picking = mesh.entity_index;
#endif

return out;
}
8 changes: 7 additions & 1 deletion crates/bevy_sprite/src/mesh2d/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use bevy_reflect::TypeUuid;
use bevy_render::{
extract_component::ExtractComponentPlugin,
mesh::{Mesh, MeshVertexBufferLayout},
picking::Picking,
prelude::Image,
render_asset::{PrepareAssetLabel, RenderAssets},
render_phase::{
Expand Down Expand Up @@ -310,6 +311,7 @@ pub fn queue_material2d_meshes<M: Material2d>(
&ExtractedView,
&VisibleEntities,
Option<&Tonemapping>,
Option<&Picking>,
&mut RenderPhase<Transparent2d>,
)>,
) where
Expand All @@ -319,7 +321,7 @@ pub fn queue_material2d_meshes<M: Material2d>(
return;
}

for (view, visible_entities, tonemapping, mut transparent_phase) in &mut views {
for (view, visible_entities, tonemapping, picking, mut transparent_phase) in &mut views {
let draw_transparent_pbr = transparent_draw_functions.read().id::<DrawMaterial2d<M>>();

let mut view_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples)
Expand All @@ -335,6 +337,10 @@ pub fn queue_material2d_meshes<M: Material2d>(
}
}

if picking.is_some() {
view_key |= Mesh2dPipelineKey::PICKING;
}

for visible_entity in &visible_entities.entities {
if let Ok((material2d_handle, mesh2d_handle, mesh2d_uniform)) =
material2d_meshes.get(*visible_entity)
Expand Down
30 changes: 18 additions & 12 deletions crates/bevy_sprite/src/mesh2d/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ bitflags::bitflags! {
const HDR = (1 << 0);
const TONEMAP_IN_SHADER = (1 << 1);
const DEBAND_DITHER = (1 << 2);
const PICKING = (1 << 3);
const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS;
const PRIMITIVE_TOPOLOGY_RESERVED_BITS = Self::PRIMITIVE_TOPOLOGY_MASK_BITS << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
}
Expand Down Expand Up @@ -393,6 +394,22 @@ impl SpecializedMeshPipeline for Mesh2dPipeline {
false => TextureFormat::bevy_default(),
};

let mut targets = vec![Some(ColorTargetState {
format,
blend: Some(BlendState::ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
})];

if key.contains(Mesh2dPipelineKey::PICKING) {
shader_defs.push("PICKING".into());

targets.push(Some(ColorTargetState {
format: TextureFormat::R32Uint,
blend: None,
write_mask: ColorWrites::ALL,
}))
}

Ok(RenderPipelineDescriptor {
vertex: VertexState {
shader: MESH2D_SHADER_HANDLE.typed::<Shader>(),
Expand All @@ -404,18 +421,7 @@ impl SpecializedMeshPipeline for Mesh2dPipeline {
shader: MESH2D_SHADER_HANDLE.typed::<Shader>(),
shader_defs,
entry_point: "fragment".into(),
targets: vec![
Some(ColorTargetState {
format,
blend: Some(BlendState::ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
}),
Some(ColorTargetState {
format: TextureFormat::R32Uint,
blend: None,
write_mask: ColorWrites::ALL,
}),
],
targets,
}),
layout: Some(vec![self.view_layout.clone(), self.mesh_layout.clone()]),
primitive: PrimitiveState {
Expand Down
39 changes: 26 additions & 13 deletions crates/bevy_sprite/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use bevy_math::{Rect, Vec2};
use bevy_reflect::Uuid;
use bevy_render::{
color::Color,
picking::Picking,
render_asset::RenderAssets,
render_phase::{
BatchedPhaseItem, DrawFunctions, EntityRenderCommand, RenderCommand, RenderCommandResult,
Expand Down Expand Up @@ -152,6 +153,7 @@ bitflags::bitflags! {
const HDR = (1 << 1);
const TONEMAP_IN_SHADER = (1 << 2);
const DEBAND_DITHER = (1 << 3);
const PICKING = (1 << 4);
const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS;
}
}
Expand Down Expand Up @@ -227,6 +229,22 @@ impl SpecializedRenderPipeline for SpritePipeline {
false => TextureFormat::bevy_default(),
};

let mut targets = vec![Some(ColorTargetState {
format,
blend: Some(BlendState::ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
})];

if key.contains(SpritePipelineKey::PICKING) {
shader_defs.push("PICKING".into());

targets.push(Some(ColorTargetState {
format: TextureFormat::R32Uint,
blend: None,
write_mask: ColorWrites::ALL,
}))
}

RenderPipelineDescriptor {
vertex: VertexState {
shader: SPRITE_SHADER_HANDLE.typed::<Shader>(),
Expand All @@ -238,18 +256,7 @@ impl SpecializedRenderPipeline for SpritePipeline {
shader: SPRITE_SHADER_HANDLE.typed::<Shader>(),
shader_defs,
entry_point: "fragment".into(),
targets: vec![
Some(ColorTargetState {
format,
blend: Some(BlendState::ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
}),
Some(ColorTargetState {
format: TextureFormat::R32Uint,
blend: None,
write_mask: ColorWrites::ALL,
}),
],
targets,
}),
layout: Some(vec![self.view_layout.clone(), self.material_layout.clone()]),
primitive: PrimitiveState {
Expand Down Expand Up @@ -468,6 +475,7 @@ pub fn queue_sprites(
&VisibleEntities,
&ExtractedView,
Option<&Tonemapping>,
Option<&Picking>,
)>,
events: Res<SpriteAssetEvents>,
) {
Expand Down Expand Up @@ -523,7 +531,7 @@ pub fn queue_sprites(
});
let image_bind_groups = &mut *image_bind_groups;

for (mut transparent_phase, visible_entities, view, tonemapping) in &mut views {
for (mut transparent_phase, visible_entities, view, tonemapping, picking) in &mut views {
let mut view_key = SpritePipelineKey::from_hdr(view.hdr) | msaa_key;
if let Some(Tonemapping::Enabled { deband_dither }) = tonemapping {
if !view.hdr {
Expand All @@ -534,6 +542,11 @@ pub fn queue_sprites(
}
}
}

if picking.is_some() {
view_key |= SpritePipelineKey::PICKING;
}

let pipeline = pipelines.specialize(
&mut pipeline_cache,
&sprite_pipeline,
Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_sprite/src/render/sprite.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ var sprite_texture: texture_2d<f32>;
var sprite_sampler: sampler;

struct FragmentOutput {
@location(0) color: vec4<f32>,
@location(1) picking: u32,
}
@location(0) color: vec4<f32>,
#ifdef PICKING
@location(1) picking: u32,
#endif
}

@fragment
fn fragment(in: VertexOutput) -> FragmentOutput {
Expand All @@ -68,7 +70,10 @@ fn fragment(in: VertexOutput) -> FragmentOutput {
var out: FragmentOutput;

out.color = color;

#ifdef PICKING
out.picking = in.entity_index;
#endif

return out;
}
1 change: 1 addition & 0 deletions crates/bevy_ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ serde = { version = "1", features = ["derive"] }
smallvec = { version = "1.6", features = ["union", "const_generics"] }
bytemuck = { version = "1.5", features = ["derive"] }
thiserror = "1.0.0"
bitflags = "1.2"
23 changes: 15 additions & 8 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod pipeline;
mod render_pass;

use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
use bevy_render::picking::Picking;
pub use pipeline::*;
pub use render_pass::*;

Expand Down Expand Up @@ -387,8 +388,8 @@ pub fn extract_text_uinodes(
struct UiVertex {
pub position: [f32; 3],
pub uv: [f32; 2],
pub entity_index: u32,
pub color: [f32; 4],
pub entity_index: u32,
}

#[derive(Resource)]
Expand Down Expand Up @@ -579,7 +580,11 @@ pub fn queue_uinodes(
mut image_bind_groups: ResMut<UiImageBindGroups>,
gpu_images: Res<RenderAssets<Image>>,
ui_batches: Query<(Entity, &UiBatch)>,
mut views: Query<(&ExtractedView, &mut RenderPhase<TransparentUi>)>,
mut views: Query<(
&ExtractedView,
Option<&Picking>,
&mut RenderPhase<TransparentUi>,
)>,
events: Res<SpriteAssetEvents>,
) {
// If an image has changed, the GpuImage has (probably) changed
Expand All @@ -602,12 +607,14 @@ pub fn queue_uinodes(
layout: &ui_pipeline.view_layout,
}));
let draw_ui_function = draw_functions.read().id::<DrawUi>();
for (view, mut transparent_phase) in &mut views {
let pipeline = pipelines.specialize(
&mut pipeline_cache,
&ui_pipeline,
UiPipelineKey { hdr: view.hdr },
);
for (view, picking, mut transparent_phase) in &mut views {
let mut key = UiPipelineKey::from_hdr(view.hdr);

if picking.is_some() {
key |= UiPipelineKey::PICKING;
}

let pipeline = pipelines.specialize(&mut pipeline_cache, &ui_pipeline, key);
for (entity, batch) in &ui_batches {
image_bind_groups
.values
Expand Down
Loading

0 comments on commit 9e75efe

Please sign in to comment.