From 5fac1fe0a909a7e16f9fb8944d7a8103a9676052 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 17 Aug 2023 12:46:43 -0700 Subject: [PATCH] Fix temporal jitter bug (#9462) * Fixed jitter being applied in the wrong coordinate space, leading to aliasing. * Fixed incorrectly using the cached view_proj instead of account for temporal jitter. * Added a diagram to ensure the coordinate space is clear. Before: ![image](https://github.com/bevyengine/bevy/assets/47158642/55b4bed4-4fb0-4fb2-a271-cc10a987e4d7) After: ![image](https://github.com/bevyengine/bevy/assets/47158642/cbde4553-4e35-44d9-8ccf-f3a06e64a31f) --- crates/bevy_render/src/camera/camera.rs | 5 +++-- crates/bevy_render/src/view/mod.rs | 12 +++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index c85e8d68cfc9d..d6aa154dc174d 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -19,7 +19,7 @@ use bevy_ecs::{ system::{Commands, Query, Res, ResMut, Resource}, }; use bevy_log::warn; -use bevy_math::{Mat4, Ray, Rect, URect, UVec2, UVec4, Vec2, Vec3}; +use bevy_math::{vec2, Mat4, Ray, Rect, URect, UVec2, UVec4, Vec2, Vec3}; use bevy_reflect::prelude::*; use bevy_transform::components::GlobalTransform; use bevy_utils::{HashMap, HashSet}; @@ -806,7 +806,8 @@ impl TemporalJitter { return; } - let jitter = self.offset / view_size; + // https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK/blob/d7531ae47d8b36a5d4025663e731a47a38be882f/docs/techniques/media/super-resolution-temporal/jitter-space.svg + let jitter = (self.offset * vec2(2.0, -2.0)) / view_size; projection.z_axis.x += jitter.x; projection.z_axis.y += jitter.y; diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index b2b773787c6e4..9167279081b2d 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -375,11 +375,17 @@ pub fn prepare_view_uniforms( let view = camera.transform.compute_matrix(); let inverse_view = view.inverse(); + let view_proj = if temporal_jitter.is_some() { + projection * inverse_view + } else { + camera + .view_projection + .unwrap_or_else(|| projection * inverse_view) + }; + let view_uniforms = ViewUniformOffset { offset: view_uniforms.uniforms.push(ViewUniform { - view_proj: camera - .view_projection - .unwrap_or_else(|| projection * inverse_view), + view_proj, unjittered_view_proj: unjittered_projection * inverse_view, inverse_view_proj: view * inverse_projection, view,