diff --git a/src/render/extract.rs b/src/render/extract.rs index affd6750ee6c97491bef70e13593e5904e2fc35b..0833e9d2882f437407cbf2035a528fd95970d172 100644 --- a/src/render/extract.rs +++ b/src/render/extract.rs @@ -144,6 +144,7 @@ pub struct UIViewUniforms { #[derive(Clone, ShaderType)] pub struct UIViewUniform { pub view_proj: Mat4, + pub unjittered_view_proj: Mat4, pub inverse_view_proj: Mat4, pub view: Mat4, pub inverse_view: Mat4, @@ -153,6 +154,7 @@ pub struct UIViewUniform { // viewport(x_origin, y_origin, width, height) pub viewport: Vec4, pub color_grading: ColorGrading, + pub mip_bias: f32, } #[derive(Component, Debug)] @@ -160,16 +162,31 @@ pub struct UIViewUniformOffset { pub offset: u32, } -fn prepare_view_uniforms( +use bevy::math::Vec4Swizzles; +use bevy::render::camera::{MipBias, TemporalJitter}; + +pub fn prepare_view_uniforms( mut commands: Commands, render_device: Res<RenderDevice>, render_queue: Res<RenderQueue>, mut view_uniforms: ResMut<UIViewUniforms>, - views: Query<(Entity, &UIExtractedView)>, + views: Query<( + Entity, + &UIExtractedView, + Option<&TemporalJitter>, + Option<&MipBias>, + )>, ) { view_uniforms.uniforms.clear(); - for (entity, camera) in &views { - let projection = camera.projection; + for (entity, camera, temporal_jitter, mip_bias) in &views { + let viewport = camera.viewport.as_vec4(); + let unjittered_projection = camera.projection; + let mut projection = unjittered_projection; + + if let Some(temporal_jitter) = temporal_jitter { + temporal_jitter.jitter_projection(&mut projection, viewport.zw()); + } + let inverse_projection = projection.inverse(); let view = camera.transform.compute_matrix(); let inverse_view = view.inverse(); @@ -178,14 +195,16 @@ fn prepare_view_uniforms( view_proj: camera .view_projection .unwrap_or_else(|| projection * inverse_view), + unjittered_view_proj: unjittered_projection * inverse_view, inverse_view_proj: view * inverse_projection, view, inverse_view, projection, inverse_projection, world_position: camera.transform.translation(), - viewport: camera.viewport.as_vec4(), + viewport, color_grading: camera.color_grading, + mip_bias: mip_bias.unwrap_or(&MipBias(0.0)).0, }), }; commands.entity(entity).insert(view_uniforms); diff --git a/src/render/mod.rs b/src/render/mod.rs index 49a7bca4ab4b35612212f72006bd97f97d25f999..3bb49d8a620c1d5a997cffa058d2fb0f9de9afed 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -37,9 +37,6 @@ pub use opacity_layer::MAX_OPACITY_LAYERS; pub mod draw_ui_graph { pub const NAME: &str = "kayak_draw_ui"; - pub mod input { - pub const VIEW_ENTITY: &str = "kayak_view_entity"; - } pub mod node { pub const MAIN_PASS: &str = "kayak_ui_pass"; } diff --git a/src/render/ui_pass.rs b/src/render/ui_pass.rs index e18f4e84bd3e1b907556e3ba2d8433a6bfdd765b..d12de7e035223f978dfff541a521d27e900390b0 100644 --- a/src/render/ui_pass.rs +++ b/src/render/ui_pass.rs @@ -8,7 +8,7 @@ use bevy::render::render_phase::{ }; use bevy::render::render_resource::{CachedRenderPipelineId, RenderPassColorAttachment}; use bevy::render::{ - render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, + render_graph::{Node, NodeRunError, RenderGraphContext}, render_phase::RenderPhase, render_resource::{LoadOp, Operations, RenderPassDescriptor}, renderer::RenderContext, @@ -170,8 +170,6 @@ pub struct MainPassUINode { } impl MainPassUINode { - pub const IN_VIEW: &'static str = "view"; - pub fn new(world: &mut World) -> Self { Self { query: world.query_filtered(), @@ -180,10 +178,6 @@ impl MainPassUINode { } impl Node for MainPassUINode { - fn input(&self) -> Vec<SlotInfo> { - vec![SlotInfo::new(MainPassUINode::IN_VIEW, SlotType::Entity)] - } - fn update(&mut self, world: &mut World) { self.query.update_archetypes(world); } @@ -194,7 +188,7 @@ impl Node for MainPassUINode { render_context: &mut RenderContext, world: &World, ) -> Result<(), NodeRunError> { - let view_entity = graph.get_input_entity(Self::IN_VIEW)?; + let view_entity = graph.view_entity(); // adapted from bevy itself; // see: <https://github.com/bevyengine/bevy/commit/09a3d8abe062984479bf0e99fcc1508bb722baf6> let (transparent_phase, transparent_opacity_phase, target, _camera_ui) = diff --git a/src/render/unified/shaders/bindings.wgsl b/src/render/unified/shaders/bindings.wgsl index ff02245ed819811dc0aee948e01c24ed728b3ef8..8de802c35c05b4f3e4eba7b86fdf5334031b1dde 100644 --- a/src/render/unified/shaders/bindings.wgsl +++ b/src/render/unified/shaders/bindings.wgsl @@ -18,6 +18,9 @@ var<uniform> globals: Globals; struct QuadType { t: i32, + _padding_a: i32, + _padding_b: i32, + _padding_c: i32, }; @group(2) @binding(0) diff --git a/src/render/unified/shaders/sample_quad.wgsl b/src/render/unified/shaders/sample_quad.wgsl index 7a8adee5d46b7e8e1a956695cd1a617272cbdf7c..fb7c8af679f895c8791709ba34595c945df75358 100644 --- a/src/render/unified/shaders/sample_quad.wgsl +++ b/src/render/unified/shaders/sample_quad.wgsl @@ -1,10 +1,6 @@ #define_import_path kayak_ui::sample_quad -#import kayak_ui::bindings font_texture -#import kayak_ui::bindings font_sampler -#import kayak_ui::bindings image_texture -#import kayak_ui::bindings image_sampler -#import kayak_ui::bindings quad_type +#import kayak_ui::bindings font_texture, font_sampler, image_texture, image_sampler, quad_type #import kayak_ui::vertex_output VertexOutput @@ -14,13 +10,13 @@ fn sdRoundBox(p: vec2<f32>, b: vec2<f32>, r: f32) -> f32 { return min(max(q.x, q.y), 0.0) + length(max(q, vec2<f32>(0.0))) - r; } -fn median3(v: vec3<f32>) -> f32 { +fn median_three(v: vec3<f32>) -> f32 { return max(min(v.x, v.y), min(max(v.x, v.y), v.z)); } fn sample_sdf(coords: vec2<f32>, arr: i32, scale: f32) -> f32 { let sample = textureSample(font_texture, font_sampler, vec2(coords.xy), arr); - return median3(sample.rgb); + return median_three(sample.rgb); } fn range_curve(font_size: f32) -> f32 { diff --git a/src/render/unified/shaders/shader.wgsl b/src/render/unified/shaders/shader.wgsl index de7b77442a5e7c31a60a006f5765257f78aee54b..8f0645bbe7b4e513f814c092224186458926dad6 100644 --- a/src/render/unified/shaders/shader.wgsl +++ b/src/render/unified/shaders/shader.wgsl @@ -1,4 +1,4 @@ -#import kayak_ui::bindings +#import kayak_ui::bindings view #import kayak_ui::vertex_output VertexOutput @@ -20,7 +20,7 @@ fn vertex( return out; } -#import kayak_ui::sample_quad +#import kayak_ui::sample_quad sample_quad @fragment fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {