Add previous_view_uniforms.inverse_view (#12902)
# Objective - Upload previous frame's inverse_view matrix to the GPU for use with https://github.com/bevyengine/bevy/pull/12898. --- ## Changelog - Added `prepass_bindings::previous_view_uniforms.inverse_view`. - Renamed `prepass_bindings::previous_view_proj` to `prepass_bindings::previous_view_uniforms.view_proj`. - Renamed `PreviousViewProjectionUniformOffset` to `PreviousViewUniformOffset`. - Renamed `PreviousViewProjection` to `PreviousViewData`. ## Migration Guide - Renamed `prepass_bindings::previous_view_proj` to `prepass_bindings::previous_view_uniforms.view_proj`. - Renamed `PreviousViewProjectionUniformOffset` to `PreviousViewUniformOffset`. - Renamed `PreviousViewProjection` to `PreviousViewData`.
This commit is contained in:
parent
452821dd52
commit
31b5943ad4
@ -7,8 +7,8 @@ use super::{
|
|||||||
MeshletGpuScene,
|
MeshletGpuScene,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
MeshViewBindGroup, PrepassViewBindGroup, PreviousViewProjectionUniformOffset,
|
MeshViewBindGroup, PrepassViewBindGroup, PreviousViewUniformOffset, ViewFogUniformOffset,
|
||||||
ViewFogUniformOffset, ViewLightProbesUniformOffset, ViewLightsUniformOffset,
|
ViewLightProbesUniformOffset, ViewLightsUniformOffset,
|
||||||
};
|
};
|
||||||
use bevy_core_pipeline::prepass::ViewPrepassTextures;
|
use bevy_core_pipeline::prepass::ViewPrepassTextures;
|
||||||
use bevy_ecs::{query::QueryItem, world::World};
|
use bevy_ecs::{query::QueryItem, world::World};
|
||||||
@ -135,7 +135,7 @@ impl ViewNode for MeshletPrepassNode {
|
|||||||
&'static ExtractedCamera,
|
&'static ExtractedCamera,
|
||||||
&'static ViewPrepassTextures,
|
&'static ViewPrepassTextures,
|
||||||
&'static ViewUniformOffset,
|
&'static ViewUniformOffset,
|
||||||
Option<&'static PreviousViewProjectionUniformOffset>,
|
Option<&'static PreviousViewUniformOffset>,
|
||||||
&'static MeshletViewMaterialsPrepass,
|
&'static MeshletViewMaterialsPrepass,
|
||||||
&'static MeshletViewBindGroups,
|
&'static MeshletViewBindGroups,
|
||||||
&'static MeshletViewResources,
|
&'static MeshletViewResources,
|
||||||
@ -149,7 +149,7 @@ impl ViewNode for MeshletPrepassNode {
|
|||||||
camera,
|
camera,
|
||||||
view_prepass_textures,
|
view_prepass_textures,
|
||||||
view_uniform_offset,
|
view_uniform_offset,
|
||||||
previous_view_projection_uniform_offset,
|
previous_view_uniform_offset,
|
||||||
meshlet_view_materials,
|
meshlet_view_materials,
|
||||||
meshlet_view_bind_groups,
|
meshlet_view_bind_groups,
|
||||||
meshlet_view_resources,
|
meshlet_view_resources,
|
||||||
@ -209,15 +209,13 @@ impl ViewNode for MeshletPrepassNode {
|
|||||||
render_pass.set_camera_viewport(viewport);
|
render_pass.set_camera_viewport(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(previous_view_projection_uniform_offset) =
|
if let Some(previous_view_uniform_offset) = previous_view_uniform_offset {
|
||||||
previous_view_projection_uniform_offset
|
|
||||||
{
|
|
||||||
render_pass.set_bind_group(
|
render_pass.set_bind_group(
|
||||||
0,
|
0,
|
||||||
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
||||||
&[
|
&[
|
||||||
view_uniform_offset.offset,
|
view_uniform_offset.offset,
|
||||||
previous_view_projection_uniform_offset.offset,
|
previous_view_uniform_offset.offset,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -258,7 +256,7 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode {
|
|||||||
&'static ExtractedCamera,
|
&'static ExtractedCamera,
|
||||||
&'static ViewPrepassTextures,
|
&'static ViewPrepassTextures,
|
||||||
&'static ViewUniformOffset,
|
&'static ViewUniformOffset,
|
||||||
Option<&'static PreviousViewProjectionUniformOffset>,
|
Option<&'static PreviousViewUniformOffset>,
|
||||||
&'static MeshletViewMaterialsDeferredGBufferPrepass,
|
&'static MeshletViewMaterialsDeferredGBufferPrepass,
|
||||||
&'static MeshletViewBindGroups,
|
&'static MeshletViewBindGroups,
|
||||||
&'static MeshletViewResources,
|
&'static MeshletViewResources,
|
||||||
@ -272,7 +270,7 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode {
|
|||||||
camera,
|
camera,
|
||||||
view_prepass_textures,
|
view_prepass_textures,
|
||||||
view_uniform_offset,
|
view_uniform_offset,
|
||||||
previous_view_projection_uniform_offset,
|
previous_view_uniform_offset,
|
||||||
meshlet_view_materials,
|
meshlet_view_materials,
|
||||||
meshlet_view_bind_groups,
|
meshlet_view_bind_groups,
|
||||||
meshlet_view_resources,
|
meshlet_view_resources,
|
||||||
@ -337,15 +335,13 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode {
|
|||||||
render_pass.set_camera_viewport(viewport);
|
render_pass.set_camera_viewport(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(previous_view_projection_uniform_offset) =
|
if let Some(previous_view_uniform_offset) = previous_view_uniform_offset {
|
||||||
previous_view_projection_uniform_offset
|
|
||||||
{
|
|
||||||
render_pass.set_bind_group(
|
render_pass.set_bind_group(
|
||||||
0,
|
0,
|
||||||
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
||||||
&[
|
&[
|
||||||
view_uniform_offset.offset,
|
view_uniform_offset.offset,
|
||||||
previous_view_projection_uniform_offset.offset,
|
previous_view_uniform_offset.offset,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#ifdef PREPASS_FRAGMENT
|
#ifdef PREPASS_FRAGMENT
|
||||||
#ifdef MOTION_VECTOR_PREPASS
|
#ifdef MOTION_VECTOR_PREPASS
|
||||||
#import bevy_pbr::{
|
#import bevy_pbr::{
|
||||||
prepass_bindings::previous_view_proj,
|
prepass_bindings::previous_view_uniforms,
|
||||||
pbr_prepass_functions::calculate_motion_vector,
|
pbr_prepass_functions::calculate_motion_vector,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -153,9 +153,9 @@ fn resolve_vertex_output(frag_coord: vec4<f32>) -> VertexOutput {
|
|||||||
let previous_world_position_1 = mesh_position_local_to_world(previous_model, vec4(vertex_1.position, 1.0));
|
let previous_world_position_1 = mesh_position_local_to_world(previous_model, vec4(vertex_1.position, 1.0));
|
||||||
let previous_world_position_2 = mesh_position_local_to_world(previous_model, vec4(vertex_2.position, 1.0));
|
let previous_world_position_2 = mesh_position_local_to_world(previous_model, vec4(vertex_2.position, 1.0));
|
||||||
let previous_world_position_3 = mesh_position_local_to_world(previous_model, vec4(vertex_3.position, 1.0));
|
let previous_world_position_3 = mesh_position_local_to_world(previous_model, vec4(vertex_3.position, 1.0));
|
||||||
let previous_clip_position_1 = previous_view_proj * vec4(previous_world_position_1.xyz, 1.0);
|
let previous_clip_position_1 = previous_view_uniforms.view_proj * vec4(previous_world_position_1.xyz, 1.0);
|
||||||
let previous_clip_position_2 = previous_view_proj * vec4(previous_world_position_2.xyz, 1.0);
|
let previous_clip_position_2 = previous_view_uniforms.view_proj * vec4(previous_world_position_2.xyz, 1.0);
|
||||||
let previous_clip_position_3 = previous_view_proj * vec4(previous_world_position_3.xyz, 1.0);
|
let previous_clip_position_3 = previous_view_uniforms.view_proj * vec4(previous_world_position_3.xyz, 1.0);
|
||||||
let previous_partial_derivatives = compute_partial_derivatives(
|
let previous_partial_derivatives = compute_partial_derivatives(
|
||||||
array(previous_clip_position_1, previous_clip_position_2, previous_clip_position_3),
|
array(previous_clip_position_1, previous_clip_position_2, previous_clip_position_3),
|
||||||
frag_coord_ndc,
|
frag_coord_ndc,
|
||||||
|
@ -143,7 +143,7 @@ where
|
|||||||
PreUpdate,
|
PreUpdate,
|
||||||
(
|
(
|
||||||
update_mesh_previous_global_transforms,
|
update_mesh_previous_global_transforms,
|
||||||
update_previous_view_projections,
|
update_previous_view_data,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ where
|
|||||||
|
|
||||||
if no_prepass_plugin_loaded {
|
if no_prepass_plugin_loaded {
|
||||||
render_app
|
render_app
|
||||||
.add_systems(ExtractSchedule, extract_camera_previous_view_projection)
|
.add_systems(ExtractSchedule, extract_camera_previous_view_data)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Render,
|
Render,
|
||||||
(
|
(
|
||||||
@ -163,7 +163,7 @@ where
|
|||||||
sort_binned_render_phase::<AlphaMask3dPrepass>
|
sort_binned_render_phase::<AlphaMask3dPrepass>
|
||||||
).in_set(RenderSet::PhaseSort),
|
).in_set(RenderSet::PhaseSort),
|
||||||
(
|
(
|
||||||
prepare_previous_view_projection_uniforms,
|
prepare_previous_view_uniforms,
|
||||||
batch_and_prepare_binned_render_phase::<Opaque3dPrepass, MeshPipeline>,
|
batch_and_prepare_binned_render_phase::<Opaque3dPrepass, MeshPipeline>,
|
||||||
batch_and_prepare_binned_render_phase::<AlphaMask3dPrepass,
|
batch_and_prepare_binned_render_phase::<AlphaMask3dPrepass,
|
||||||
MeshPipeline>,
|
MeshPipeline>,
|
||||||
@ -201,17 +201,20 @@ where
|
|||||||
struct AnyPrepassPluginLoaded;
|
struct AnyPrepassPluginLoaded;
|
||||||
|
|
||||||
#[derive(Component, ShaderType, Clone)]
|
#[derive(Component, ShaderType, Clone)]
|
||||||
pub struct PreviousViewProjection {
|
pub struct PreviousViewData {
|
||||||
|
pub inverse_view: Mat4,
|
||||||
pub view_proj: Mat4,
|
pub view_proj: Mat4,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_previous_view_projections(
|
pub fn update_previous_view_data(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
query: Query<(Entity, &Camera, &GlobalTransform), (With<Camera3d>, With<MotionVectorPrepass>)>,
|
query: Query<(Entity, &Camera, &GlobalTransform), (With<Camera3d>, With<MotionVectorPrepass>)>,
|
||||||
) {
|
) {
|
||||||
for (entity, camera, camera_transform) in &query {
|
for (entity, camera, camera_transform) in &query {
|
||||||
commands.entity(entity).try_insert(PreviousViewProjection {
|
let inverse_view = camera_transform.compute_matrix().inverse();
|
||||||
view_proj: camera.projection_matrix() * camera_transform.compute_matrix().inverse(),
|
commands.entity(entity).try_insert(PreviousViewData {
|
||||||
|
inverse_view,
|
||||||
|
view_proj: camera.projection_matrix() * inverse_view,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,8 +266,8 @@ impl<M: Material> FromWorld for PrepassPipeline<M> {
|
|||||||
uniform_buffer::<ViewUniform>(true),
|
uniform_buffer::<ViewUniform>(true),
|
||||||
// Globals
|
// Globals
|
||||||
uniform_buffer::<GlobalsUniform>(false),
|
uniform_buffer::<GlobalsUniform>(false),
|
||||||
// PreviousViewProjection
|
// PreviousViewUniforms
|
||||||
uniform_buffer::<PreviousViewProjection>(true),
|
uniform_buffer::<PreviousViewData>(true),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -603,16 +606,16 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract the render phases for the prepass
|
// Extract the render phases for the prepass
|
||||||
pub fn extract_camera_previous_view_projection(
|
pub fn extract_camera_previous_view_data(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
cameras_3d: Extract<Query<(Entity, &Camera, Option<&PreviousViewProjection>), With<Camera3d>>>,
|
cameras_3d: Extract<Query<(Entity, &Camera, Option<&PreviousViewData>), With<Camera3d>>>,
|
||||||
) {
|
) {
|
||||||
for (entity, camera, maybe_previous_view_proj) in cameras_3d.iter() {
|
for (entity, camera, maybe_previous_view_data) in cameras_3d.iter() {
|
||||||
if camera.is_active {
|
if camera.is_active {
|
||||||
let mut entity = commands.get_or_spawn(entity);
|
let mut entity = commands.get_or_spawn(entity);
|
||||||
|
|
||||||
if let Some(previous_view) = maybe_previous_view_proj {
|
if let Some(previous_view_data) = maybe_previous_view_data {
|
||||||
entity.insert(previous_view.clone());
|
entity.insert(previous_view_data.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -620,23 +623,20 @@ pub fn extract_camera_previous_view_projection(
|
|||||||
|
|
||||||
#[derive(Resource, Default)]
|
#[derive(Resource, Default)]
|
||||||
pub struct PreviousViewProjectionUniforms {
|
pub struct PreviousViewProjectionUniforms {
|
||||||
pub uniforms: DynamicUniformBuffer<PreviousViewProjection>,
|
pub uniforms: DynamicUniformBuffer<PreviousViewData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct PreviousViewProjectionUniformOffset {
|
pub struct PreviousViewUniformOffset {
|
||||||
pub offset: u32,
|
pub offset: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_previous_view_projection_uniforms(
|
pub fn prepare_previous_view_uniforms(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
render_device: Res<RenderDevice>,
|
render_device: Res<RenderDevice>,
|
||||||
render_queue: Res<RenderQueue>,
|
render_queue: Res<RenderQueue>,
|
||||||
mut view_uniforms: ResMut<PreviousViewProjectionUniforms>,
|
mut view_uniforms: ResMut<PreviousViewProjectionUniforms>,
|
||||||
views: Query<
|
views: Query<(Entity, &ExtractedView, Option<&PreviousViewData>), With<MotionVectorPrepass>>,
|
||||||
(Entity, &ExtractedView, Option<&PreviousViewProjection>),
|
|
||||||
With<MotionVectorPrepass>,
|
|
||||||
>,
|
|
||||||
) {
|
) {
|
||||||
let views_iter = views.iter();
|
let views_iter = views.iter();
|
||||||
let view_count = views_iter.len();
|
let view_count = views_iter.len();
|
||||||
@ -647,16 +647,20 @@ pub fn prepare_previous_view_projection_uniforms(
|
|||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
for (entity, camera, maybe_previous_view_proj) in views_iter {
|
|
||||||
let view_projection = match maybe_previous_view_proj {
|
for (entity, camera, maybe_previous_view_uniforms) in views_iter {
|
||||||
|
let view_projection = match maybe_previous_view_uniforms {
|
||||||
Some(previous_view) => previous_view.clone(),
|
Some(previous_view) => previous_view.clone(),
|
||||||
None => PreviousViewProjection {
|
None => {
|
||||||
view_proj: camera.projection * camera.transform.compute_matrix().inverse(),
|
let inverse_view = camera.transform.compute_matrix().inverse();
|
||||||
},
|
PreviousViewData {
|
||||||
|
inverse_view,
|
||||||
|
view_proj: camera.projection * inverse_view,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
commands
|
|
||||||
.entity(entity)
|
commands.entity(entity).insert(PreviousViewUniformOffset {
|
||||||
.insert(PreviousViewProjectionUniformOffset {
|
|
||||||
offset: writer.write(&view_projection),
|
offset: writer.write(&view_projection),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -673,7 +677,7 @@ pub fn prepare_prepass_view_bind_group<M: Material>(
|
|||||||
prepass_pipeline: Res<PrepassPipeline<M>>,
|
prepass_pipeline: Res<PrepassPipeline<M>>,
|
||||||
view_uniforms: Res<ViewUniforms>,
|
view_uniforms: Res<ViewUniforms>,
|
||||||
globals_buffer: Res<GlobalsBuffer>,
|
globals_buffer: Res<GlobalsBuffer>,
|
||||||
previous_view_proj_uniforms: Res<PreviousViewProjectionUniforms>,
|
previous_view_uniforms: Res<PreviousViewProjectionUniforms>,
|
||||||
mut prepass_view_bind_group: ResMut<PrepassViewBindGroup>,
|
mut prepass_view_bind_group: ResMut<PrepassViewBindGroup>,
|
||||||
) {
|
) {
|
||||||
if let (Some(view_binding), Some(globals_binding)) = (
|
if let (Some(view_binding), Some(globals_binding)) = (
|
||||||
@ -686,14 +690,14 @@ pub fn prepare_prepass_view_bind_group<M: Material>(
|
|||||||
&BindGroupEntries::sequential((view_binding.clone(), globals_binding.clone())),
|
&BindGroupEntries::sequential((view_binding.clone(), globals_binding.clone())),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Some(previous_view_proj_binding) = previous_view_proj_uniforms.uniforms.binding() {
|
if let Some(previous_view_uniforms_binding) = previous_view_uniforms.uniforms.binding() {
|
||||||
prepass_view_bind_group.motion_vectors = Some(render_device.create_bind_group(
|
prepass_view_bind_group.motion_vectors = Some(render_device.create_bind_group(
|
||||||
"prepass_view_motion_vectors_bind_group",
|
"prepass_view_motion_vectors_bind_group",
|
||||||
&prepass_pipeline.view_layout_motion_vectors,
|
&prepass_pipeline.view_layout_motion_vectors,
|
||||||
&BindGroupEntries::sequential((
|
&BindGroupEntries::sequential((
|
||||||
view_binding,
|
view_binding,
|
||||||
globals_binding,
|
globals_binding,
|
||||||
previous_view_proj_binding,
|
previous_view_uniforms_binding,
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -918,16 +922,16 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetPrepassViewBindGroup<
|
|||||||
type Param = SRes<PrepassViewBindGroup>;
|
type Param = SRes<PrepassViewBindGroup>;
|
||||||
type ViewQuery = (
|
type ViewQuery = (
|
||||||
Read<ViewUniformOffset>,
|
Read<ViewUniformOffset>,
|
||||||
Option<Read<PreviousViewProjectionUniformOffset>>,
|
Option<Read<PreviousViewUniformOffset>>,
|
||||||
);
|
);
|
||||||
type ItemQuery = ();
|
type ItemQuery = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn render<'w>(
|
fn render<'w>(
|
||||||
_item: &P,
|
_item: &P,
|
||||||
(view_uniform_offset, previous_view_projection_uniform_offset): (
|
(view_uniform_offset, previous_view_uniform_offset): (
|
||||||
&'_ ViewUniformOffset,
|
&'_ ViewUniformOffset,
|
||||||
Option<&'_ PreviousViewProjectionUniformOffset>,
|
Option<&'_ PreviousViewUniformOffset>,
|
||||||
),
|
),
|
||||||
_entity: Option<()>,
|
_entity: Option<()>,
|
||||||
prepass_view_bind_group: SystemParamItem<'w, '_, Self::Param>,
|
prepass_view_bind_group: SystemParamItem<'w, '_, Self::Param>,
|
||||||
@ -935,15 +939,13 @@ impl<P: PhaseItem, const I: usize> RenderCommand<P> for SetPrepassViewBindGroup<
|
|||||||
) -> RenderCommandResult {
|
) -> RenderCommandResult {
|
||||||
let prepass_view_bind_group = prepass_view_bind_group.into_inner();
|
let prepass_view_bind_group = prepass_view_bind_group.into_inner();
|
||||||
|
|
||||||
if let Some(previous_view_projection_uniform_offset) =
|
if let Some(previous_view_uniform_offset) = previous_view_uniform_offset {
|
||||||
previous_view_projection_uniform_offset
|
|
||||||
{
|
|
||||||
pass.set_bind_group(
|
pass.set_bind_group(
|
||||||
I,
|
I,
|
||||||
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
||||||
&[
|
&[
|
||||||
view_uniform_offset.offset,
|
view_uniform_offset.offset,
|
||||||
previous_view_projection_uniform_offset.offset,
|
previous_view_uniform_offset.offset,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
prepass_io::{Vertex, VertexOutput, FragmentOutput},
|
prepass_io::{Vertex, VertexOutput, FragmentOutput},
|
||||||
skinning,
|
skinning,
|
||||||
morph,
|
morph,
|
||||||
mesh_view_bindings::{view, previous_view_proj},
|
mesh_view_bindings::view,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEFERRED_PREPASS
|
#ifdef DEFERRED_PREPASS
|
||||||
@ -127,7 +127,7 @@ fn fragment(in: VertexOutput) -> FragmentOutput {
|
|||||||
#ifdef MOTION_VECTOR_PREPASS
|
#ifdef MOTION_VECTOR_PREPASS
|
||||||
let clip_position_t = view.unjittered_view_proj * in.world_position;
|
let clip_position_t = view.unjittered_view_proj * in.world_position;
|
||||||
let clip_position = clip_position_t.xy / clip_position_t.w;
|
let clip_position = clip_position_t.xy / clip_position_t.w;
|
||||||
let previous_clip_position_t = prepass_bindings::previous_view_proj * in.previous_world_position;
|
let previous_clip_position_t = prepass_bindings::previous_view_uniforms.view_proj * in.previous_world_position;
|
||||||
let previous_clip_position = previous_clip_position_t.xy / previous_clip_position_t.w;
|
let previous_clip_position = previous_clip_position_t.xy / previous_clip_position_t.w;
|
||||||
// These motion vectors are used as offsets to UV positions and are stored
|
// These motion vectors are used as offsets to UV positions and are stored
|
||||||
// in the range -1,1 to allow offsetting from the one corner to the
|
// in the range -1,1 to allow offsetting from the one corner to the
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
#define_import_path bevy_pbr::prepass_bindings
|
#define_import_path bevy_pbr::prepass_bindings
|
||||||
|
|
||||||
|
struct PreviousViewUniforms {
|
||||||
|
inverse_view: mat4x4<f32>,
|
||||||
|
view_proj: mat4x4<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MOTION_VECTOR_PREPASS
|
#ifdef MOTION_VECTOR_PREPASS
|
||||||
@group(0) @binding(2) var<uniform> previous_view_proj: mat4x4<f32>;
|
@group(0) @binding(2) var<uniform> previous_view_uniforms: PreviousViewUniforms;
|
||||||
#endif // MOTION_VECTOR_PREPASS
|
#endif // MOTION_VECTOR_PREPASS
|
||||||
|
|
||||||
// Material bindings will be in @group(2)
|
// Material bindings will be in @group(2)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#import bevy_pbr::{
|
#import bevy_pbr::{
|
||||||
prepass_io::VertexOutput,
|
prepass_io::VertexOutput,
|
||||||
prepass_bindings::previous_view_proj,
|
prepass_bindings::previous_view_uniforms,
|
||||||
mesh_view_bindings::view,
|
mesh_view_bindings::view,
|
||||||
pbr_bindings,
|
pbr_bindings,
|
||||||
pbr_types,
|
pbr_types,
|
||||||
@ -47,7 +47,7 @@ fn prepass_alpha_discard(in: VertexOutput) {
|
|||||||
fn calculate_motion_vector(world_position: vec4<f32>, previous_world_position: vec4<f32>) -> vec2<f32> {
|
fn calculate_motion_vector(world_position: vec4<f32>, previous_world_position: vec4<f32>) -> vec2<f32> {
|
||||||
let clip_position_t = view.unjittered_view_proj * world_position;
|
let clip_position_t = view.unjittered_view_proj * world_position;
|
||||||
let clip_position = clip_position_t.xy / clip_position_t.w;
|
let clip_position = clip_position_t.xy / clip_position_t.w;
|
||||||
let previous_clip_position_t = previous_view_proj * previous_world_position;
|
let previous_clip_position_t = previous_view_uniforms.view_proj * previous_world_position;
|
||||||
let previous_clip_position = previous_clip_position_t.xy / previous_clip_position_t.w;
|
let previous_clip_position = previous_clip_position_t.xy / previous_clip_position_t.w;
|
||||||
// These motion vectors are used as offsets to UV positions and are stored
|
// These motion vectors are used as offsets to UV positions and are stored
|
||||||
// in the range -1,1 to allow offsetting from the one corner to the
|
// in the range -1,1 to allow offsetting from the one corner to the
|
||||||
|
Loading…
Reference in New Issue
Block a user