diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 4e1ac3069a95c..041ed36072987 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -16,6 +16,7 @@ use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d}; use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; use bevy_ecs::entity::{EntityHashMap, EntityHashSet}; use bevy_ecs::prelude::*; +use bevy_hierarchy::Parent; use bevy_math::{FloatOrd, Mat4, Rect, URect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles}; use bevy_render::render_phase::ViewSortedRenderPhases; use bevy_render::sync_world::MainEntity; @@ -404,8 +405,10 @@ pub fn extract_uinode_borders( Option<&CalculatedClip>, Option<&TargetCamera>, AnyOf<(&BorderColor, &Outline)>, + Option<&Parent>, )>, >, + parent_clip_query: Extract>, mapping: Extract>, ) { let image = AssetId::::default(); @@ -418,6 +421,7 @@ pub fn extract_uinode_borders( maybe_clip, maybe_camera, (maybe_border_color, maybe_outline), + maybe_parent, ) in &uinode_query { let Some(camera_entity) = maybe_camera @@ -471,6 +475,9 @@ pub fn extract_uinode_borders( if let Some(outline) = maybe_outline { let outline_size = uinode.outlined_node_size(); + let parent_clip = + maybe_parent.and_then(|parent| parent_clip_query.get(parent.get()).ok()); + extracted_uinodes.uinodes.insert( commands.spawn(TemporaryRenderEntity).id(), ExtractedUiNode { @@ -481,7 +488,7 @@ pub fn extract_uinode_borders( ..Default::default() }, image, - clip: maybe_clip.map(|clip| clip.clip), + clip: parent_clip.map(|clip| clip.clip), camera_entity: render_camera_entity, item: ExtractedUiItem::Node { transform: global_transform.compute_matrix(), @@ -768,6 +775,8 @@ struct UiVertex { pub border: [f32; 4], /// Size of the UI node. pub size: [f32; 2], + /// Position relative to the center of the UI node. + pub point: [f32; 2], } #[derive(Resource)] @@ -998,6 +1007,7 @@ pub fn prepare_uinodes( // Specify the corners of the node let positions = QUAD_VERTEX_POSITIONS .map(|pos| (*transform * (pos * rect_size).extend(1.)).xyz()); + let points = QUAD_VERTEX_POSITIONS.map(|pos| pos.xy() * rect_size.xy()); // Calculate the effect of clipping // Note: this won't work with rotation/scaling, but that's much more complex (may need more that 2 quads) @@ -1031,6 +1041,13 @@ pub fn prepare_uinodes( positions[3] + positions_diff[3].extend(0.), ]; + let points = [ + points[0] + positions_diff[0], + points[1] + positions_diff[1], + points[2] + positions_diff[2], + points[3] + positions_diff[3], + ]; + let transformed_rect_size = transform.transform_vector3(rect_size); // Don't try to cull nodes that have a rotation @@ -1113,6 +1130,7 @@ pub fn prepare_uinodes( ], border: [border.left, border.top, border.right, border.bottom], size: rect_size.xy().into(), + point: points[i].into(), }); } @@ -1215,6 +1233,7 @@ pub fn prepare_uinodes( radius: [0.0; 4], border: [0.0; 4], size: size.into(), + point: [0.0; 2], }); } diff --git a/crates/bevy_ui/src/render/pipeline.rs b/crates/bevy_ui/src/render/pipeline.rs index 715a1984b9482..0e99461092ffb 100644 --- a/crates/bevy_ui/src/render/pipeline.rs +++ b/crates/bevy_ui/src/render/pipeline.rs @@ -72,6 +72,8 @@ impl SpecializedRenderPipeline for UiPipeline { VertexFormat::Float32x4, // border size VertexFormat::Float32x2, + // position relative to the center + VertexFormat::Float32x2, ], ); let shader_defs = if key.anti_alias { diff --git a/crates/bevy_ui/src/render/ui.wgsl b/crates/bevy_ui/src/render/ui.wgsl index c46e0b4926279..d73e7bd92949b 100644 --- a/crates/bevy_ui/src/render/ui.wgsl +++ b/crates/bevy_ui/src/render/ui.wgsl @@ -38,6 +38,7 @@ fn vertex( // x: left, y: top, z: right, w: bottom. @location(5) border: vec4, @location(6) size: vec2, + @location(7) point: vec2, ) -> VertexOutput { var out: VertexOutput; out.uv = vertex_uv; @@ -47,13 +48,6 @@ fn vertex( out.radius = radius; out.size = size; out.border = border; - var point = 0.49999 * size; - if (flags & RIGHT_VERTEX) == 0u { - point.x *= -1.; - } - if (flags & BOTTOM_VERTEX) == 0u { - point.y *= -1.; - } out.point = point; return out;