mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Fix meshlet interactions with regular shading passes (#13816)
* Fixes https://github.com/bevyengine/bevy/issues/13813 * Fixes https://github.com/bevyengine/bevy/issues/13810 Tested a combined scene with both regular meshes and meshlet meshes with: * Regular forward setup * Forward + normal/motion vector prepasses * Deferred (with depth prepass since that's required) * Deferred + depth/normal/motion vector prepasses Still broken: * Using meshlet meshes rendering in deferred and regular meshes rendering in forward + depth/normal prepass. I don't know how to fix this at the moment, so for now I've just add instructions to not mix them.
This commit is contained in:
parent
073db8cf36
commit
b56a693c34
5 changed files with 32 additions and 18 deletions
|
@ -122,17 +122,17 @@ impl ViewNode for DeferredGBufferPrepassNode {
|
|||
let view_entity = graph.view_entity();
|
||||
render_context.add_command_buffer_generation_task(move |render_device| {
|
||||
#[cfg(feature = "trace")]
|
||||
let _deferred_span = info_span!("deferred").entered();
|
||||
let _deferred_span = info_span!("deferred_prepass").entered();
|
||||
|
||||
// Command encoder setup
|
||||
let mut command_encoder =
|
||||
render_device.create_command_encoder(&CommandEncoderDescriptor {
|
||||
label: Some("deferred_command_encoder"),
|
||||
label: Some("deferred_prepass_command_encoder"),
|
||||
});
|
||||
|
||||
// Render pass setup
|
||||
let render_pass = command_encoder.begin_render_pass(&RenderPassDescriptor {
|
||||
label: Some("deferred"),
|
||||
label: Some("deferred_prepass"),
|
||||
color_attachments: &color_attachments,
|
||||
depth_stencil_attachment,
|
||||
timestamp_writes: None,
|
||||
|
@ -148,20 +148,20 @@ impl ViewNode for DeferredGBufferPrepassNode {
|
|||
|| !opaque_deferred_phase.unbatchable_keys.is_empty()
|
||||
{
|
||||
#[cfg(feature = "trace")]
|
||||
let _opaque_prepass_span = info_span!("opaque_deferred").entered();
|
||||
let _opaque_prepass_span = info_span!("opaque_deferred_prepass").entered();
|
||||
opaque_deferred_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
// Alpha masked draws
|
||||
if !alpha_mask_deferred_phase.is_empty() {
|
||||
#[cfg(feature = "trace")]
|
||||
let _alpha_mask_deferred_span = info_span!("alpha_mask_deferred").entered();
|
||||
let _alpha_mask_deferred_span = info_span!("alpha_mask_deferred_prepass").entered();
|
||||
alpha_mask_deferred_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
drop(render_pass);
|
||||
|
||||
// Copy prepass depth to the main depth texture
|
||||
// After rendering to the view depth texture, copy it to the prepass depth texture
|
||||
if let Some(prepass_depth_texture) = &view_prepass_textures.depth {
|
||||
command_encoder.copy_texture_to_texture(
|
||||
view_depth_texture.texture.as_image_copy(),
|
||||
|
|
|
@ -162,7 +162,7 @@ impl ViewNode for PrepassNode {
|
|||
pass_span.end(&mut render_pass);
|
||||
drop(render_pass);
|
||||
|
||||
// Copy prepass depth to the main depth texture if deferred isn't going to
|
||||
// After rendering to the view depth texture, copy it to the prepass depth texture if deferred isn't going to
|
||||
if deferred_prepass.is_none() {
|
||||
if let Some(prepass_depth_texture) = &view_prepass_textures.depth {
|
||||
command_encoder.copy_texture_to_texture(
|
||||
|
|
|
@ -10,8 +10,13 @@ use crate::{
|
|||
MeshViewBindGroup, PrepassViewBindGroup, ViewFogUniformOffset, ViewLightProbesUniformOffset,
|
||||
ViewLightsUniformOffset, ViewScreenSpaceReflectionsUniformOffset,
|
||||
};
|
||||
use bevy_core_pipeline::prepass::{PreviousViewUniformOffset, ViewPrepassTextures};
|
||||
use bevy_ecs::{query::QueryItem, world::World};
|
||||
use bevy_core_pipeline::prepass::{
|
||||
MotionVectorPrepass, PreviousViewUniformOffset, ViewPrepassTextures,
|
||||
};
|
||||
use bevy_ecs::{
|
||||
query::{Has, QueryItem},
|
||||
world::World,
|
||||
};
|
||||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||
|
@ -138,7 +143,8 @@ impl ViewNode for MeshletPrepassNode {
|
|||
&'static ExtractedCamera,
|
||||
&'static ViewPrepassTextures,
|
||||
&'static ViewUniformOffset,
|
||||
Option<&'static PreviousViewUniformOffset>,
|
||||
&'static PreviousViewUniformOffset,
|
||||
Has<MotionVectorPrepass>,
|
||||
&'static MeshletViewMaterialsPrepass,
|
||||
&'static MeshletViewBindGroups,
|
||||
&'static MeshletViewResources,
|
||||
|
@ -153,6 +159,7 @@ impl ViewNode for MeshletPrepassNode {
|
|||
view_prepass_textures,
|
||||
view_uniform_offset,
|
||||
previous_view_uniform_offset,
|
||||
view_has_motion_vector_prepass,
|
||||
meshlet_view_materials,
|
||||
meshlet_view_bind_groups,
|
||||
meshlet_view_resources,
|
||||
|
@ -212,7 +219,7 @@ impl ViewNode for MeshletPrepassNode {
|
|||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
if let Some(previous_view_uniform_offset) = previous_view_uniform_offset {
|
||||
if view_has_motion_vector_prepass {
|
||||
render_pass.set_bind_group(
|
||||
0,
|
||||
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
||||
|
@ -259,7 +266,8 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode {
|
|||
&'static ExtractedCamera,
|
||||
&'static ViewPrepassTextures,
|
||||
&'static ViewUniformOffset,
|
||||
Option<&'static PreviousViewUniformOffset>,
|
||||
&'static PreviousViewUniformOffset,
|
||||
Has<MotionVectorPrepass>,
|
||||
&'static MeshletViewMaterialsDeferredGBufferPrepass,
|
||||
&'static MeshletViewBindGroups,
|
||||
&'static MeshletViewResources,
|
||||
|
@ -274,6 +282,7 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode {
|
|||
view_prepass_textures,
|
||||
view_uniform_offset,
|
||||
previous_view_uniform_offset,
|
||||
view_has_motion_vector_prepass,
|
||||
meshlet_view_materials,
|
||||
meshlet_view_bind_groups,
|
||||
meshlet_view_resources,
|
||||
|
@ -338,7 +347,7 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode {
|
|||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
if let Some(previous_view_uniform_offset) = previous_view_uniform_offset {
|
||||
if view_has_motion_vector_prepass {
|
||||
render_pass.set_bind_group(
|
||||
0,
|
||||
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
|
||||
|
|
|
@ -142,7 +142,8 @@ pub fn prepare_material_meshlet_meshes_main_opaque_pass<M: Material>(
|
|||
continue;
|
||||
};
|
||||
|
||||
if material.properties.alpha_mode != AlphaMode::Opaque
|
||||
if material.properties.render_method != OpaqueRendererMethod::Forward
|
||||
|| material.properties.alpha_mode != AlphaMode::Opaque
|
||||
|| material.properties.reads_view_transmission_texture
|
||||
{
|
||||
continue;
|
||||
|
|
|
@ -109,6 +109,10 @@ const MESHLET_MESH_MATERIAL_SHADER_HANDLE: Handle<Shader> =
|
|||
///
|
||||
/// This plugin does not work on WASM.
|
||||
///
|
||||
/// Mixing forward+prepass and deferred rendering for opaque materials is not currently supported when using this plugin.
|
||||
/// You must use one or the other by setting [`crate::DefaultOpaqueRendererMethod`].
|
||||
/// Do not override [`crate::Material::opaque_render_method`] for any material when using this plugin.
|
||||
///
|
||||
/// ![A render of the Stanford dragon as a `MeshletMesh`](https://raw.githubusercontent.com/bevyengine/bevy/main/crates/bevy_pbr/src/meshlet/meshlet_preview.png)
|
||||
pub struct MeshletPlugin;
|
||||
|
||||
|
@ -206,18 +210,18 @@ impl Plugin for MeshletPlugin {
|
|||
.add_render_graph_edges(
|
||||
Core3d,
|
||||
(
|
||||
// TODO: Meshlet VisibilityBufferRaster should be after main pass when not using depth prepass
|
||||
// Non-meshlet shading passes _must_ come before meshlet shading passes
|
||||
NodePbr::ShadowPass,
|
||||
Node3d::Prepass,
|
||||
Node3d::DeferredPrepass,
|
||||
NodeMeshlet::VisibilityBufferRasterPass,
|
||||
NodeMeshlet::Prepass,
|
||||
Node3d::Prepass,
|
||||
NodeMeshlet::DeferredPrepass,
|
||||
Node3d::DeferredPrepass,
|
||||
Node3d::CopyDeferredLightingId,
|
||||
Node3d::EndPrepasses,
|
||||
Node3d::StartMainPass,
|
||||
Node3d::MainOpaquePass,
|
||||
NodeMeshlet::MainOpaquePass,
|
||||
Node3d::MainOpaquePass,
|
||||
Node3d::EndMainPass,
|
||||
),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue