From 7125dcb268eeb1dc4c5c8a59086629ab0a9eb592 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Thu, 18 Jan 2024 15:33:42 -0500 Subject: [PATCH] Customizable camera main texture usage (#11412) # Objective - Some users want to change the default texture usage of the main camera but they are currently hardcoded ## Solution - Add a component that is used to configure the main texture usage field --- ## Changelog Added `CameraMainTextureUsage` Added `CameraMainTextureUsage` to `Camera3dBundle` and `Camera2dBundle` ## Migration Guide Add `main_texture_usages: Default::default()` to your camera bundle. # Notes Inspired by: #6815 --- .../bevy_core_pipeline/src/core_2d/camera_2d.rs | 8 +++++++- .../bevy_core_pipeline/src/core_3d/camera_3d.rs | 4 +++- crates/bevy_render/src/camera/camera.rs | 16 +++++++++++++++- crates/bevy_render/src/camera/mod.rs | 5 +++-- crates/bevy_render/src/view/mod.rs | 17 ++++++++++------- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs index f68b302acc..d76c0c315c 100644 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs @@ -2,7 +2,10 @@ use crate::tonemapping::{DebandDither, Tonemapping}; use bevy_ecs::prelude::*; use bevy_reflect::Reflect; use bevy_render::{ - camera::{Camera, CameraProjection, CameraRenderGraph, OrthographicProjection}, + camera::{ + Camera, CameraMainTextureUsages, CameraProjection, CameraRenderGraph, + OrthographicProjection, + }, extract_component::ExtractComponent, primitives::Frustum, view::VisibleEntities, @@ -26,6 +29,7 @@ pub struct Camera2dBundle { pub camera_2d: Camera2d, pub tonemapping: Tonemapping, pub deband_dither: DebandDither, + pub main_texture_usages: CameraMainTextureUsages, } impl Default for Camera2dBundle { @@ -55,6 +59,7 @@ impl Default for Camera2dBundle { camera_2d: Camera2d, tonemapping: Tonemapping::None, deband_dither: DebandDither::Disabled, + main_texture_usages: Default::default(), } } } @@ -93,6 +98,7 @@ impl Camera2dBundle { camera_2d: Camera2d, tonemapping: Tonemapping::None, deband_dither: DebandDither::Disabled, + main_texture_usages: Default::default(), } } } diff --git a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs index bdcd81c923..0b8e21da0e 100644 --- a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs +++ b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs @@ -2,7 +2,7 @@ use crate::tonemapping::{DebandDither, Tonemapping}; use bevy_ecs::prelude::*; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_render::{ - camera::{Camera, CameraRenderGraph, Projection}, + camera::{Camera, CameraMainTextureUsages, CameraRenderGraph, Projection}, extract_component::ExtractComponent, primitives::Frustum, render_resource::{LoadOp, TextureUsages}, @@ -143,6 +143,7 @@ pub struct Camera3dBundle { pub tonemapping: Tonemapping, pub dither: DebandDither, pub color_grading: ColorGrading, + pub main_texture_usages: CameraMainTextureUsages, } // NOTE: ideally Perspective and Orthographic defaults can share the same impl, but sadly it breaks rust's type inference @@ -160,6 +161,7 @@ impl Default for Camera3dBundle { tonemapping: Default::default(), dither: DebandDither::Enabled, color_grading: ColorGrading::default(), + main_texture_usages: Default::default(), } } } diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index e6e9469bc9..540f0fc3e3 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -24,6 +24,7 @@ use bevy_math::{ primitives::Direction3d, vec2, Mat4, Ray3d, Rect, URect, UVec2, UVec4, Vec2, Vec3, }; use bevy_reflect::prelude::*; +use bevy_render_macros::ExtractComponent; use bevy_transform::components::GlobalTransform; use bevy_utils::{HashMap, HashSet}; use bevy_window::{ @@ -31,7 +32,7 @@ use bevy_window::{ WindowScaleFactorChanged, }; use std::{borrow::Cow, ops::Range}; -use wgpu::{BlendState, LoadOp, TextureFormat}; +use wgpu::{BlendState, LoadOp, TextureFormat, TextureUsages}; use super::{ClearColorConfig, Projection}; @@ -750,6 +751,19 @@ pub fn camera_system( } } +/// This component lets you control the [`TextureUsages`] field of the main texture generated for the camera +#[derive(Component, ExtractComponent, Clone, Copy)] +pub struct CameraMainTextureUsages(pub TextureUsages); +impl Default for CameraMainTextureUsages { + fn default() -> Self { + Self( + TextureUsages::RENDER_ATTACHMENT + | TextureUsages::TEXTURE_BINDING + | TextureUsages::COPY_SRC, + ) + } +} + #[derive(Component, Debug)] pub struct ExtractedCamera { pub target: Option, diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 2796fb36e5..214ced79d2 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -12,8 +12,8 @@ pub use manual_texture_view::*; pub use projection::*; use crate::{ - extract_resource::ExtractResourcePlugin, render_graph::RenderGraph, ExtractSchedule, Render, - RenderApp, RenderSet, + extract_component::ExtractComponentPlugin, extract_resource::ExtractResourcePlugin, + render_graph::RenderGraph, ExtractSchedule, Render, RenderApp, RenderSet, }; use bevy_app::{App, Plugin}; use bevy_ecs::schedule::IntoSystemConfigs; @@ -39,6 +39,7 @@ impl Plugin for CameraPlugin { CameraProjectionPlugin::::default(), ExtractResourcePlugin::::default(), ExtractResourcePlugin::::default(), + ExtractComponentPlugin::::default(), )); if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index 7866fdcdcc..acaa1818b2 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -7,8 +7,8 @@ pub use window::*; use crate::{ camera::{ - ClearColor, ClearColorConfig, ExposureSettings, ExtractedCamera, ManualTextureViews, - MipBias, TemporalJitter, + CameraMainTextureUsages, ClearColor, ClearColorConfig, ExposureSettings, ExtractedCamera, + ManualTextureViews, MipBias, TemporalJitter, }, extract_resource::{ExtractResource, ExtractResourcePlugin}, prelude::{Image, Shader}, @@ -465,11 +465,16 @@ fn prepare_view_targets( clear_color_global: Res, render_device: Res, mut texture_cache: ResMut, - cameras: Query<(Entity, &ExtractedCamera, &ExtractedView)>, + cameras: Query<( + Entity, + &ExtractedCamera, + &ExtractedView, + &CameraMainTextureUsages, + )>, manual_texture_views: Res, ) { let mut textures = HashMap::default(); - for (entity, camera, view) in cameras.iter() { + for (entity, camera, view, texture_usage) in cameras.iter() { if let (Some(target_size), Some(target)) = (camera.physical_target_size, &camera.target) { if let (Some(out_texture_view), Some(out_texture_format)) = ( target.get_texture_view(&windows, &images, &manual_texture_views), @@ -502,9 +507,7 @@ fn prepare_view_targets( sample_count: 1, dimension: TextureDimension::D2, format: main_texture_format, - usage: TextureUsages::RENDER_ATTACHMENT - | TextureUsages::TEXTURE_BINDING - | TextureUsages::COPY_SRC, + usage: texture_usage.0, view_formats: match main_texture_format { TextureFormat::Bgra8Unorm => &[TextureFormat::Bgra8UnormSrgb], TextureFormat::Rgba8Unorm => &[TextureFormat::Rgba8UnormSrgb],