Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ path = "examples/3d/texture.rs"
name = "render_to_texture"
path = "examples/3d/render_to_texture.rs"

[[example]]
name = "two_passes"
path = "examples/3d/two_passes.rs"

[[example]]
name = "update_gltf_scene"
path = "examples/3d/update_gltf_scene.rs"
Expand Down
52 changes: 33 additions & 19 deletions crates/bevy_core_pipeline/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use bevy_app::{App, Plugin};
use bevy_core::FloatOrd;
use bevy_ecs::prelude::*;
use bevy_render::{
camera::{ActiveCameras, CameraPlugin, RenderTarget},
camera::{ActiveCameras, CameraPlugin, ExtractedCamera, RenderTarget},
color::Color,
render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType},
render_phase::{
Expand Down Expand Up @@ -393,35 +393,49 @@ pub fn prepare_core_views_system(
msaa: Res<Msaa>,
render_device: Res<RenderDevice>,
views_3d: Query<
(Entity, &ExtractedView),
(Entity, &ExtractedView, Option<&ExtractedCamera>),
(
With<RenderPhase<Opaque3d>>,
With<RenderPhase<AlphaMask3d>>,
With<RenderPhase<Transparent3d>>,
),
>,
) {
for (entity, view) in views_3d.iter() {
let cached_texture = texture_cache.get(
&render_device,
TextureDescriptor {
label: Some("view_depth_texture"),
size: Extent3d {
depth_or_array_layers: 1,
width: view.width as u32,
height: view.height as u32,
let mut textures = HashMap::default();
for (entity, view, camera) in views_3d.iter() {
let mut render_on_top = false;
let mut get_cached_texture = || {
texture_cache.get(
&render_device,
TextureDescriptor {
label: Some("view_depth_texture"),
size: Extent3d {
depth_or_array_layers: 1,
width: view.width as u32,
height: view.height as u32,
},
mip_level_count: 1,
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
* bit depth for better performance */
usage: TextureUsages::RENDER_ATTACHMENT,
},
mip_level_count: 1,
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
* bit depth for better performance */
usage: TextureUsages::RENDER_ATTACHMENT,
},
);
)
};
let cached_texture = if let Some(camera) = camera {
render_on_top = camera.render_on_top;
textures
.entry(camera.target.clone())
.or_insert_with(get_cached_texture)
.clone()
} else {
get_cached_texture()
};
commands.entity(entity).insert(ViewDepthTexture {
texture: cached_texture.texture,
view: cached_texture.default_view,
render_on_top,
});
}
}
8 changes: 6 additions & 2 deletions crates/bevy_core_pipeline/src/main_pass_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ impl Node for MainPass3dNode {
view: &depth.view,
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
depth_ops: Some(Operations {
load: LoadOp::Load,
load: if depth.render_on_top {
LoadOp::Clear(0.0)
} else {
LoadOp::Load
},
store: true,
}),
stencil_ops: None,
Expand Down Expand Up @@ -139,7 +143,7 @@ impl Node for MainPass3dNode {
// transparent ones.
depth_ops: Some(Operations {
load: LoadOp::Load,
store: false,
store: true,
}),
stencil_ops: None,
}),
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct Camera {
pub name: Option<String>,
#[reflect(ignore)]
pub target: RenderTarget,
pub render_on_top: bool,
#[reflect(ignore)]
pub depth_calculation: DepthCalculation,
pub near: f32,
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_render/src/camera/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub struct ExtractedCamera {
pub target: RenderTarget,
pub name: Option<String>,
pub physical_size: Option<UVec2>,
pub render_on_top: bool,
}

fn extract_cameras(
Expand All @@ -96,6 +97,7 @@ fn extract_cameras(
target: camera.target.clone(),
name: camera.name.clone(),
physical_size: camera.target.get_physical_size(&windows, &images),
render_on_top: camera.render_on_top,
},
ExtractedView {
projection: camera.projection_matrix,
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/src/texture/texture_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct CachedTextureMeta {
/// A cached GPU [`Texture`] with corresponding [`TextureView`].
/// This is useful for textures that are created repeatedly (each frame) in the rendering process
/// to reduce the amount of GPU memory allocations.
#[derive(Clone)]
pub struct CachedTexture {
pub texture: Texture,
pub default_view: TextureView,
Expand Down
39 changes: 23 additions & 16 deletions crates/bevy_render/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use bevy_math::{Mat4, Vec3};
use bevy_transform::components::GlobalTransform;
use bevy_utils::HashMap;

pub struct ViewPlugin;

Expand Down Expand Up @@ -136,6 +137,7 @@ impl ViewTarget {
pub struct ViewDepthTexture {
pub texture: Texture,
pub view: TextureView,
pub render_on_top: bool,
}

fn prepare_view_uniforms(
Expand Down Expand Up @@ -183,6 +185,7 @@ fn prepare_view_targets(
mut texture_cache: ResMut<TextureCache>,
cameras: Query<&ExtractedCamera>,
) {
let mut sampled_textures = HashMap::default();
for entity in camera_names.entities.values().copied() {
let camera = if let Ok(camera) = cameras.get(entity) {
camera
Expand All @@ -192,22 +195,26 @@ fn prepare_view_targets(
if let Some(size) = camera.physical_size {
if let Some(texture_view) = camera.target.get_texture_view(&windows, &images) {
let sampled_target = if msaa.samples > 1 {
let sampled_texture = texture_cache.get(
&render_device,
TextureDescriptor {
label: Some("sampled_color_attachment_texture"),
size: Extent3d {
width: size.x,
height: size.y,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::bevy_default(),
usage: TextureUsages::RENDER_ATTACHMENT,
},
);
let sampled_texture = sampled_textures
.entry(camera.target.clone())
.or_insert_with(|| {
texture_cache.get(
&render_device,
TextureDescriptor {
label: Some("sampled_color_attachment_texture"),
size: Extent3d {
width: size.x,
height: size.y,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::bevy_default(),
usage: TextureUsages::RENDER_ATTACHMENT,
},
)
});
Some(sampled_texture.default_view.clone())
} else {
None
Expand Down
Loading