Path: blob/main/crates/bevy_pbr/src/meshlet/material_shade_nodes.rs
9294 views
use super::{1material_pipeline_prepare::{2MeshletViewMaterialsDeferredGBufferPrepass, MeshletViewMaterialsMainOpaquePass,3MeshletViewMaterialsPrepass,4},5resource_manager::{MeshletViewBindGroups, MeshletViewResources},6InstanceManager,7};8use crate::{9MeshViewBindGroup, PrepassViewBindGroup, ViewContactShadowsUniformOffset,10ViewEnvironmentMapUniformOffset, ViewFogUniformOffset, ViewLightProbesUniformOffset,11ViewLightsUniformOffset, ViewScreenSpaceReflectionsUniformOffset,12};13use bevy_camera::MainPassResolutionOverride;14use bevy_camera::Viewport;15use bevy_core_pipeline::prepass::{16MotionVectorPrepass, PreviousViewUniformOffset, ViewPrepassTextures,17};18use bevy_ecs::{prelude::*, query::Has};19use bevy_render::{20camera::ExtractedCamera,21render_resource::{22LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor,23StoreOp,24},25renderer::{RenderContext, ViewQuery},26view::{ViewTarget, ViewUniformOffset},27};2829///30/// Fullscreen shading pass based on the visibility buffer generated from rasterizing meshlets.31pub fn meshlet_main_opaque_pass(32view: ViewQuery<(33&ExtractedCamera,34&ViewTarget,35&MeshViewBindGroup,36&ViewUniformOffset,37&ViewLightsUniformOffset,38&ViewFogUniformOffset,39&ViewLightProbesUniformOffset,40&ViewScreenSpaceReflectionsUniformOffset,41&ViewContactShadowsUniformOffset,42&ViewEnvironmentMapUniformOffset,43Option<&MainPassResolutionOverride>,44&MeshletViewMaterialsMainOpaquePass,45&MeshletViewBindGroups,46&MeshletViewResources,47)>,48instance_manager: Res<InstanceManager>,49pipeline_cache: Res<PipelineCache>,50mut ctx: RenderContext,51) {52let (53camera,54target,55mesh_view_bind_group,56view_uniform_offset,57view_lights_offset,58view_fog_offset,59view_light_probes_offset,60view_ssr_offset,61view_contact_shadows_offset,62view_environment_map_offset,63resolution_override,64meshlet_view_materials,65meshlet_view_bind_groups,66meshlet_view_resources,67) = view.into_inner();6869if meshlet_view_materials.is_empty() {70return;71}7273let (Some(meshlet_material_depth), Some(meshlet_material_shade_bind_group)) = (74meshlet_view_resources.material_depth.as_ref(),75meshlet_view_bind_groups.material_shade.as_ref(),76) else {77return;78};7980let mut render_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {81label: Some("meshlet_material_opaque_3d_pass"),82color_attachments: &[Some(target.get_color_attachment())],83depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {84view: &meshlet_material_depth.default_view,85depth_ops: Some(Operations {86load: LoadOp::Load,87store: StoreOp::Store,88}),89stencil_ops: None,90}),91timestamp_writes: None,92occlusion_query_set: None,93multiview_mask: None,94});9596if let Some(viewport) =97Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)98{99render_pass.set_camera_viewport(&viewport);100}101102render_pass.set_bind_group(1030,104&mesh_view_bind_group.main,105&[106view_uniform_offset.offset,107view_lights_offset.offset,108view_fog_offset.offset,109**view_light_probes_offset,110**view_ssr_offset,111**view_contact_shadows_offset,112**view_environment_map_offset,113],114);115render_pass.set_bind_group(1, &mesh_view_bind_group.binding_array, &[]);116render_pass.set_bind_group(2, meshlet_material_shade_bind_group, &[]);117118// 1 fullscreen triangle draw per material119for (material_id, material_pipeline_id, material_bind_group) in meshlet_view_materials.iter() {120if instance_manager.material_present_in_scene(material_id)121&& let Some(material_pipeline) =122pipeline_cache.get_render_pipeline(*material_pipeline_id)123{124let x = *material_id * 3;125render_pass.set_render_pipeline(material_pipeline);126render_pass.set_bind_group(3, material_bind_group, &[]);127render_pass.draw(x..(x + 3), 0..1);128}129}130}131132///133/// Fullscreen pass to generate prepass textures based on the visibility buffer generated from rasterizing meshlets.134pub fn meshlet_prepass(135view: ViewQuery<(136&ExtractedCamera,137&ViewPrepassTextures,138&ViewUniformOffset,139&PreviousViewUniformOffset,140Option<&MainPassResolutionOverride>,141Has<MotionVectorPrepass>,142&MeshletViewMaterialsPrepass,143&MeshletViewBindGroups,144&MeshletViewResources,145)>,146prepass_view_bind_group: Res<PrepassViewBindGroup>,147instance_manager: Res<InstanceManager>,148pipeline_cache: Res<PipelineCache>,149mut ctx: RenderContext,150) {151let (152camera,153view_prepass_textures,154view_uniform_offset,155previous_view_uniform_offset,156resolution_override,157view_has_motion_vector_prepass,158meshlet_view_materials,159meshlet_view_bind_groups,160meshlet_view_resources,161) = view.into_inner();162163if meshlet_view_materials.is_empty() {164return;165}166167let (Some(meshlet_material_depth), Some(meshlet_material_shade_bind_group)) = (168meshlet_view_resources.material_depth.as_ref(),169meshlet_view_bind_groups.material_shade.as_ref(),170) else {171return;172};173174let color_attachments = vec![175view_prepass_textures176.normal177.as_ref()178.map(|normals_texture| normals_texture.get_attachment()),179view_prepass_textures180.motion_vectors181.as_ref()182.map(|motion_vectors_texture| motion_vectors_texture.get_attachment()),183// Use None in place of Deferred attachments184None,185None,186];187188let mut render_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {189label: Some("meshlet_material_prepass"),190color_attachments: &color_attachments,191depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {192view: &meshlet_material_depth.default_view,193depth_ops: Some(Operations {194load: LoadOp::Load,195store: StoreOp::Store,196}),197stencil_ops: None,198}),199timestamp_writes: None,200occlusion_query_set: None,201multiview_mask: None,202});203204if let Some(viewport) =205Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)206{207render_pass.set_camera_viewport(&viewport);208}209210if view_has_motion_vector_prepass {211render_pass.set_bind_group(2120,213prepass_view_bind_group.motion_vectors.as_ref().unwrap(),214&[215view_uniform_offset.offset,216previous_view_uniform_offset.offset,217],218);219} else {220render_pass.set_bind_group(2210,222prepass_view_bind_group.no_motion_vectors.as_ref().unwrap(),223&[view_uniform_offset.offset],224);225}226227render_pass.set_bind_group(1, &prepass_view_bind_group.empty_bind_group, &[]);228render_pass.set_bind_group(2, meshlet_material_shade_bind_group, &[]);229230// 1 fullscreen triangle draw per material231for (material_id, material_pipeline_id, material_bind_group) in meshlet_view_materials.iter() {232if instance_manager.material_present_in_scene(material_id)233&& let Some(material_pipeline) =234pipeline_cache.get_render_pipeline(*material_pipeline_id)235{236let x = *material_id * 3;237render_pass.set_render_pipeline(material_pipeline);238render_pass.set_bind_group(2, material_bind_group, &[]);239render_pass.draw(x..(x + 3), 0..1);240}241}242}243244/// Fullscreen pass to generate a gbuffer based on the visibility buffer generated from rasterizing meshlets.245pub fn meshlet_deferred_gbuffer_prepass(246view: ViewQuery<(247&ExtractedCamera,248&ViewPrepassTextures,249&ViewUniformOffset,250&PreviousViewUniformOffset,251Option<&MainPassResolutionOverride>,252Has<MotionVectorPrepass>,253&MeshletViewMaterialsDeferredGBufferPrepass,254&MeshletViewBindGroups,255&MeshletViewResources,256)>,257prepass_view_bind_group: Res<PrepassViewBindGroup>,258instance_manager: Res<InstanceManager>,259pipeline_cache: Res<PipelineCache>,260mut ctx: RenderContext,261) {262let (263camera,264view_prepass_textures,265view_uniform_offset,266previous_view_uniform_offset,267resolution_override,268view_has_motion_vector_prepass,269meshlet_view_materials,270meshlet_view_bind_groups,271meshlet_view_resources,272) = view.into_inner();273274if meshlet_view_materials.is_empty() {275return;276}277278let (Some(meshlet_material_depth), Some(meshlet_material_shade_bind_group)) = (279meshlet_view_resources.material_depth.as_ref(),280meshlet_view_bind_groups.material_shade.as_ref(),281) else {282return;283};284285let color_attachments = vec![286view_prepass_textures287.normal288.as_ref()289.map(|normals_texture| normals_texture.get_attachment()),290view_prepass_textures291.motion_vectors292.as_ref()293.map(|motion_vectors_texture| motion_vectors_texture.get_attachment()),294view_prepass_textures295.deferred296.as_ref()297.map(|deferred_texture| deferred_texture.get_attachment()),298view_prepass_textures299.deferred_lighting_pass_id300.as_ref()301.map(|deferred_lighting_pass_id| deferred_lighting_pass_id.get_attachment()),302];303304let mut render_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {305label: Some("meshlet_material_deferred_prepass"),306color_attachments: &color_attachments,307depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {308view: &meshlet_material_depth.default_view,309depth_ops: Some(Operations {310load: LoadOp::Load,311store: StoreOp::Store,312}),313stencil_ops: None,314}),315timestamp_writes: None,316occlusion_query_set: None,317multiview_mask: None,318});319320if let Some(viewport) =321Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)322{323render_pass.set_camera_viewport(&viewport);324}325326if view_has_motion_vector_prepass {327render_pass.set_bind_group(3280,329prepass_view_bind_group.motion_vectors.as_ref().unwrap(),330&[331view_uniform_offset.offset,332previous_view_uniform_offset.offset,333],334);335} else {336render_pass.set_bind_group(3370,338prepass_view_bind_group.no_motion_vectors.as_ref().unwrap(),339&[view_uniform_offset.offset],340);341}342343render_pass.set_bind_group(1, &prepass_view_bind_group.empty_bind_group, &[]);344render_pass.set_bind_group(2, meshlet_material_shade_bind_group, &[]);345346// 1 fullscreen triangle draw per material347for (material_id, material_pipeline_id, material_bind_group) in meshlet_view_materials.iter() {348if instance_manager.material_present_in_scene(material_id)349&& let Some(material_pipeline) =350pipeline_cache.get_render_pipeline(*material_pipeline_id)351{352let x = *material_id * 3;353render_pass.set_render_pipeline(material_pipeline);354render_pass.set_bind_group(2, material_bind_group, &[]);355render_pass.draw(x..(x + 3), 0..1);356}357}358}359360361