Path: blob/main/crates/bevy_pbr/src/transmission/mod.rs
9419 views
mod node;1mod phase;2mod texture;34use bevy_app::{App, Plugin};5use bevy_camera::Camera3d;6use bevy_core_pipeline::{7core_3d::{main_opaque_pass_3d, main_transparent_pass_3d},8schedule::{Core3d, Core3dSystems},9};10use bevy_ecs::{prelude::*, schedule::IntoScheduleConfigs};11use bevy_reflect::prelude::*;12use bevy_render::{13extract_component::{ExtractComponent, ExtractComponentPlugin},14render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions, ViewSortedRenderPhases},15ExtractSchedule, Render, RenderApp, RenderSystems,16};17use bevy_shader::load_shader_library;18pub use node::main_transmissive_pass_3d;19pub use phase::Transmissive3d;20pub use texture::ViewTransmissionTexture;2122use texture::prepare_core_3d_transmission_textures;2324use crate::{DrawMaterial, MeshPipelineKey};2526/// Enables screen-space transmission for cameras.27pub struct ScreenSpaceTransmissionPlugin;2829impl Plugin for ScreenSpaceTransmissionPlugin {30fn build(&self, app: &mut App) {31load_shader_library!(app, "transmission.wgsl");3233app.add_plugins(ExtractComponentPlugin::<ScreenSpaceTransmission>::default())34.register_required_components::<Camera3d, ScreenSpaceTransmission>();3536let Some(render_app) = app.get_sub_app_mut(RenderApp) else {37return;38};3940render_app41.init_resource::<DrawFunctions<Transmissive3d>>()42.init_resource::<ViewSortedRenderPhases<Transmissive3d>>()43.add_render_command::<Transmissive3d, DrawMaterial>()44.add_systems(45Render,46sort_phase_system::<Transmissive3d>.in_set(RenderSystems::PhaseSort),47)48.add_systems(ExtractSchedule, phase::extract_transmissive_camera_phases)49.add_systems(50Render,51prepare_core_3d_transmission_textures.in_set(RenderSystems::PrepareResources),52)53.add_systems(54Core3d,55main_transmissive_pass_3d56.after(main_opaque_pass_3d)57.before(main_transparent_pass_3d)58.in_set(Core3dSystems::MainPass),59);60}61}6263/// Configures transmission behavior, offering a trade-off between performance and visual fidelity.64#[derive(Component, Reflect, Clone, ExtractComponent)]65#[reflect(Component, Default, Clone)]66pub struct ScreenSpaceTransmission {67/// How many individual steps should be performed in the `Transmissive3d` pass.68///69/// Roughly corresponds to how many layers of transparency are rendered for screen space70/// specular transmissive objects. Each step requires making one additional71/// texture copy, so it's recommended to keep this number to a reasonably low value. Defaults to `1`.72///73/// ### Notes74///75/// - No copies will be performed if there are no transmissive materials currently being rendered,76/// regardless of this setting.77/// - Setting this to `0` disables the screen-space refraction effect entirely, and falls78/// back to refracting only the environment map light's texture.79/// - If set to more than `0`, any opaque [`clear_color`](bevy_camera::Camera::clear_color) will obscure the environment80/// map light's texture, preventing it from being visible through transmissive materials. If you'd like81/// to still have the environment map show up in your refractions, you can set the clear color's alpha to `0.0`.82/// Keep in mind that depending on the platform and your window settings, this may cause the window to become83/// transparent.84pub steps: usize,85/// The quality of the screen space specular transmission blur effect, applied to whatever's behind transmissive86/// objects when their `roughness` is greater than `0.0`.87///88/// Higher qualities are more GPU-intensive.89///90/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: `TemporalAntiAliasPlugin`91pub quality: ScreenSpaceTransmissionQuality,92}9394impl Default for ScreenSpaceTransmission {95fn default() -> Self {96Self {97steps: 1,98quality: Default::default(),99}100}101}102103/// The quality of the screen space transmission blur effect, applied to whatever's behind transmissive104/// objects when their `roughness` is greater than `0.0`.105///106/// Higher qualities are more GPU-intensive.107///108/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: `TemporalAntiAliasPlugin`109#[derive(Default, Clone, Copy, Reflect, PartialEq, PartialOrd, Debug)]110#[reflect(Default, Clone, Debug, PartialEq)]111pub enum ScreenSpaceTransmissionQuality {112/// Best performance at the cost of quality. Suitable for lower end GPUs. (e.g. Mobile)113///114/// `num_taps` = 4115Low,116117/// A balanced option between quality and performance.118///119/// `num_taps` = 8120#[default]121Medium,122123/// Better quality. Suitable for high end GPUs. (e.g. Desktop)124///125/// `num_taps` = 16126High,127128/// The highest quality, suitable for non-realtime rendering. (e.g. Pre-rendered cinematics and photo mode)129///130/// `num_taps` = 32131Ultra,132}133134impl ScreenSpaceTransmissionQuality {135pub const fn pipeline_key(self) -> MeshPipelineKey {136match self {137ScreenSpaceTransmissionQuality::Low => {138MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_LOW139}140ScreenSpaceTransmissionQuality::Medium => {141MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_MEDIUM142}143ScreenSpaceTransmissionQuality::High => {144MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_HIGH145}146ScreenSpaceTransmissionQuality::Ultra => {147MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_ULTRA148}149}150}151}152153154