Path: blob/main/crates/bevy_pbr/src/transmission/texture.rs
9408 views
use bevy_core_pipeline::core_3d::{AlphaMask3d, Opaque3d, Transparent3d};1use bevy_ecs::{2component::Component,3entity::Entity,4system::{Commands, Query, Res, ResMut},5};6use bevy_image::{BevyDefault, ToExtents};7use bevy_platform::collections::HashMap;8use bevy_render::{9camera::ExtractedCamera,10render_phase::{ViewBinnedRenderPhases, ViewSortedRenderPhases},11render_resource::{12FilterMode, Sampler, SamplerDescriptor, Texture, TextureDescriptor, TextureDimension,13TextureFormat, TextureUsages, TextureView,14},15renderer::RenderDevice,16texture::TextureCache,17view::{ExtractedView, ViewTarget},18};1920use crate::{ScreenSpaceTransmission, Transmissive3d};2122#[derive(Component)]23pub struct ViewTransmissionTexture {24pub texture: Texture,25pub view: TextureView,26pub sampler: Sampler,27}2829pub fn prepare_core_3d_transmission_textures(30mut commands: Commands,31mut texture_cache: ResMut<TextureCache>,32render_device: Res<RenderDevice>,33opaque_3d_phases: Res<ViewBinnedRenderPhases<Opaque3d>>,34alpha_mask_3d_phases: Res<ViewBinnedRenderPhases<AlphaMask3d>>,35transmissive_3d_phases: Res<ViewSortedRenderPhases<Transmissive3d>>,36transparent_3d_phases: Res<ViewSortedRenderPhases<Transparent3d>>,37views_3d: Query<(38Entity,39&ExtractedCamera,40&ScreenSpaceTransmission,41&ExtractedView,42)>,43) {44let mut textures = <HashMap<_, _>>::default();45for (entity, camera, transmission, view) in &views_3d {46if !opaque_3d_phases.contains_key(&view.retained_view_entity)47|| !alpha_mask_3d_phases.contains_key(&view.retained_view_entity)48|| !transparent_3d_phases.contains_key(&view.retained_view_entity)49{50continue;51};5253let Some(transmissive_3d_phase) = transmissive_3d_phases.get(&view.retained_view_entity)54else {55continue;56};5758let Some(physical_target_size) = camera.physical_target_size else {59continue;60};6162// Don't prepare a transmission texture if the number of steps is set to 063if transmission.steps == 0 {64continue;65}6667// Don't prepare a transmission texture if there are no transmissive items to render68if transmissive_3d_phase.items.is_empty() {69continue;70}7172let cached_texture = textures73.entry(camera.target.clone())74.or_insert_with(|| {75let usage = TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST;7677let format = if view.hdr {78ViewTarget::TEXTURE_FORMAT_HDR79} else {80TextureFormat::bevy_default()81};8283let descriptor = TextureDescriptor {84label: Some("view_transmission_texture"),85// The size of the transmission texture86size: physical_target_size.to_extents(),87mip_level_count: 1,88sample_count: 1, // No need for MSAA, as we'll only copy the main texture here89dimension: TextureDimension::D2,90format,91usage,92view_formats: &[],93};9495texture_cache.get(&render_device, descriptor)96})97.clone();9899let sampler = render_device.create_sampler(&SamplerDescriptor {100label: Some("view_transmission_sampler"),101mag_filter: FilterMode::Linear,102min_filter: FilterMode::Linear,103..Default::default()104});105106commands.entity(entity).insert(ViewTransmissionTexture {107texture: cached_texture.texture,108view: cached_texture.default_view,109sampler,110});111}112}113114115