Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/transmission/mod.rs
9419 views
1
mod node;
2
mod phase;
3
mod texture;
4
5
use bevy_app::{App, Plugin};
6
use bevy_camera::Camera3d;
7
use bevy_core_pipeline::{
8
core_3d::{main_opaque_pass_3d, main_transparent_pass_3d},
9
schedule::{Core3d, Core3dSystems},
10
};
11
use bevy_ecs::{prelude::*, schedule::IntoScheduleConfigs};
12
use bevy_reflect::prelude::*;
13
use bevy_render::{
14
extract_component::{ExtractComponent, ExtractComponentPlugin},
15
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions, ViewSortedRenderPhases},
16
ExtractSchedule, Render, RenderApp, RenderSystems,
17
};
18
use bevy_shader::load_shader_library;
19
pub use node::main_transmissive_pass_3d;
20
pub use phase::Transmissive3d;
21
pub use texture::ViewTransmissionTexture;
22
23
use texture::prepare_core_3d_transmission_textures;
24
25
use crate::{DrawMaterial, MeshPipelineKey};
26
27
/// Enables screen-space transmission for cameras.
28
pub struct ScreenSpaceTransmissionPlugin;
29
30
impl Plugin for ScreenSpaceTransmissionPlugin {
31
fn build(&self, app: &mut App) {
32
load_shader_library!(app, "transmission.wgsl");
33
34
app.add_plugins(ExtractComponentPlugin::<ScreenSpaceTransmission>::default())
35
.register_required_components::<Camera3d, ScreenSpaceTransmission>();
36
37
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
38
return;
39
};
40
41
render_app
42
.init_resource::<DrawFunctions<Transmissive3d>>()
43
.init_resource::<ViewSortedRenderPhases<Transmissive3d>>()
44
.add_render_command::<Transmissive3d, DrawMaterial>()
45
.add_systems(
46
Render,
47
sort_phase_system::<Transmissive3d>.in_set(RenderSystems::PhaseSort),
48
)
49
.add_systems(ExtractSchedule, phase::extract_transmissive_camera_phases)
50
.add_systems(
51
Render,
52
prepare_core_3d_transmission_textures.in_set(RenderSystems::PrepareResources),
53
)
54
.add_systems(
55
Core3d,
56
main_transmissive_pass_3d
57
.after(main_opaque_pass_3d)
58
.before(main_transparent_pass_3d)
59
.in_set(Core3dSystems::MainPass),
60
);
61
}
62
}
63
64
/// Configures transmission behavior, offering a trade-off between performance and visual fidelity.
65
#[derive(Component, Reflect, Clone, ExtractComponent)]
66
#[reflect(Component, Default, Clone)]
67
pub struct ScreenSpaceTransmission {
68
/// How many individual steps should be performed in the `Transmissive3d` pass.
69
///
70
/// Roughly corresponds to how many layers of transparency are rendered for screen space
71
/// specular transmissive objects. Each step requires making one additional
72
/// texture copy, so it's recommended to keep this number to a reasonably low value. Defaults to `1`.
73
///
74
/// ### Notes
75
///
76
/// - No copies will be performed if there are no transmissive materials currently being rendered,
77
/// regardless of this setting.
78
/// - Setting this to `0` disables the screen-space refraction effect entirely, and falls
79
/// back to refracting only the environment map light's texture.
80
/// - If set to more than `0`, any opaque [`clear_color`](bevy_camera::Camera::clear_color) will obscure the environment
81
/// map light's texture, preventing it from being visible through transmissive materials. If you'd like
82
/// to still have the environment map show up in your refractions, you can set the clear color's alpha to `0.0`.
83
/// Keep in mind that depending on the platform and your window settings, this may cause the window to become
84
/// transparent.
85
pub steps: usize,
86
/// The quality of the screen space specular transmission blur effect, applied to whatever's behind transmissive
87
/// objects when their `roughness` is greater than `0.0`.
88
///
89
/// Higher qualities are more GPU-intensive.
90
///
91
/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: `TemporalAntiAliasPlugin`
92
pub quality: ScreenSpaceTransmissionQuality,
93
}
94
95
impl Default for ScreenSpaceTransmission {
96
fn default() -> Self {
97
Self {
98
steps: 1,
99
quality: Default::default(),
100
}
101
}
102
}
103
104
/// The quality of the screen space transmission blur effect, applied to whatever's behind transmissive
105
/// objects when their `roughness` is greater than `0.0`.
106
///
107
/// Higher qualities are more GPU-intensive.
108
///
109
/// **Note:** You can get better-looking results at any quality level by enabling TAA. See: `TemporalAntiAliasPlugin`
110
#[derive(Default, Clone, Copy, Reflect, PartialEq, PartialOrd, Debug)]
111
#[reflect(Default, Clone, Debug, PartialEq)]
112
pub enum ScreenSpaceTransmissionQuality {
113
/// Best performance at the cost of quality. Suitable for lower end GPUs. (e.g. Mobile)
114
///
115
/// `num_taps` = 4
116
Low,
117
118
/// A balanced option between quality and performance.
119
///
120
/// `num_taps` = 8
121
#[default]
122
Medium,
123
124
/// Better quality. Suitable for high end GPUs. (e.g. Desktop)
125
///
126
/// `num_taps` = 16
127
High,
128
129
/// The highest quality, suitable for non-realtime rendering. (e.g. Pre-rendered cinematics and photo mode)
130
///
131
/// `num_taps` = 32
132
Ultra,
133
}
134
135
impl ScreenSpaceTransmissionQuality {
136
pub const fn pipeline_key(self) -> MeshPipelineKey {
137
match self {
138
ScreenSpaceTransmissionQuality::Low => {
139
MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_LOW
140
}
141
ScreenSpaceTransmissionQuality::Medium => {
142
MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_MEDIUM
143
}
144
ScreenSpaceTransmissionQuality::High => {
145
MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_HIGH
146
}
147
ScreenSpaceTransmissionQuality::Ultra => {
148
MeshPipelineKey::SCREEN_SPACE_SPECULAR_TRANSMISSION_ULTRA
149
}
150
}
151
}
152
}
153
154