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
This commit is contained in:
IceSentry 2024-01-18 15:33:42 -05:00 committed by GitHub
parent 03ee959809
commit 7125dcb268
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 38 additions and 12 deletions

View File

@ -2,7 +2,10 @@ use crate::tonemapping::{DebandDither, Tonemapping};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use bevy_render::{ use bevy_render::{
camera::{Camera, CameraProjection, CameraRenderGraph, OrthographicProjection}, camera::{
Camera, CameraMainTextureUsages, CameraProjection, CameraRenderGraph,
OrthographicProjection,
},
extract_component::ExtractComponent, extract_component::ExtractComponent,
primitives::Frustum, primitives::Frustum,
view::VisibleEntities, view::VisibleEntities,
@ -26,6 +29,7 @@ pub struct Camera2dBundle {
pub camera_2d: Camera2d, pub camera_2d: Camera2d,
pub tonemapping: Tonemapping, pub tonemapping: Tonemapping,
pub deband_dither: DebandDither, pub deband_dither: DebandDither,
pub main_texture_usages: CameraMainTextureUsages,
} }
impl Default for Camera2dBundle { impl Default for Camera2dBundle {
@ -55,6 +59,7 @@ impl Default for Camera2dBundle {
camera_2d: Camera2d, camera_2d: Camera2d,
tonemapping: Tonemapping::None, tonemapping: Tonemapping::None,
deband_dither: DebandDither::Disabled, deband_dither: DebandDither::Disabled,
main_texture_usages: Default::default(),
} }
} }
} }
@ -93,6 +98,7 @@ impl Camera2dBundle {
camera_2d: Camera2d, camera_2d: Camera2d,
tonemapping: Tonemapping::None, tonemapping: Tonemapping::None,
deband_dither: DebandDither::Disabled, deband_dither: DebandDither::Disabled,
main_texture_usages: Default::default(),
} }
} }
} }

View File

@ -2,7 +2,7 @@ use crate::tonemapping::{DebandDither, Tonemapping};
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use bevy_render::{ use bevy_render::{
camera::{Camera, CameraRenderGraph, Projection}, camera::{Camera, CameraMainTextureUsages, CameraRenderGraph, Projection},
extract_component::ExtractComponent, extract_component::ExtractComponent,
primitives::Frustum, primitives::Frustum,
render_resource::{LoadOp, TextureUsages}, render_resource::{LoadOp, TextureUsages},
@ -143,6 +143,7 @@ pub struct Camera3dBundle {
pub tonemapping: Tonemapping, pub tonemapping: Tonemapping,
pub dither: DebandDither, pub dither: DebandDither,
pub color_grading: ColorGrading, 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 // 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(), tonemapping: Default::default(),
dither: DebandDither::Enabled, dither: DebandDither::Enabled,
color_grading: ColorGrading::default(), color_grading: ColorGrading::default(),
main_texture_usages: Default::default(),
} }
} }
} }

View File

@ -24,6 +24,7 @@ use bevy_math::{
primitives::Direction3d, vec2, Mat4, Ray3d, Rect, URect, UVec2, UVec4, Vec2, Vec3, primitives::Direction3d, vec2, Mat4, Ray3d, Rect, URect, UVec2, UVec4, Vec2, Vec3,
}; };
use bevy_reflect::prelude::*; use bevy_reflect::prelude::*;
use bevy_render_macros::ExtractComponent;
use bevy_transform::components::GlobalTransform; use bevy_transform::components::GlobalTransform;
use bevy_utils::{HashMap, HashSet}; use bevy_utils::{HashMap, HashSet};
use bevy_window::{ use bevy_window::{
@ -31,7 +32,7 @@ use bevy_window::{
WindowScaleFactorChanged, WindowScaleFactorChanged,
}; };
use std::{borrow::Cow, ops::Range}; use std::{borrow::Cow, ops::Range};
use wgpu::{BlendState, LoadOp, TextureFormat}; use wgpu::{BlendState, LoadOp, TextureFormat, TextureUsages};
use super::{ClearColorConfig, Projection}; use super::{ClearColorConfig, Projection};
@ -750,6 +751,19 @@ pub fn camera_system<T: CameraProjection + Component>(
} }
} }
/// 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)] #[derive(Component, Debug)]
pub struct ExtractedCamera { pub struct ExtractedCamera {
pub target: Option<NormalizedRenderTarget>, pub target: Option<NormalizedRenderTarget>,

View File

@ -12,8 +12,8 @@ pub use manual_texture_view::*;
pub use projection::*; pub use projection::*;
use crate::{ use crate::{
extract_resource::ExtractResourcePlugin, render_graph::RenderGraph, ExtractSchedule, Render, extract_component::ExtractComponentPlugin, extract_resource::ExtractResourcePlugin,
RenderApp, RenderSet, render_graph::RenderGraph, ExtractSchedule, Render, RenderApp, RenderSet,
}; };
use bevy_app::{App, Plugin}; use bevy_app::{App, Plugin};
use bevy_ecs::schedule::IntoSystemConfigs; use bevy_ecs::schedule::IntoSystemConfigs;
@ -39,6 +39,7 @@ impl Plugin for CameraPlugin {
CameraProjectionPlugin::<PerspectiveProjection>::default(), CameraProjectionPlugin::<PerspectiveProjection>::default(),
ExtractResourcePlugin::<ManualTextureViews>::default(), ExtractResourcePlugin::<ManualTextureViews>::default(),
ExtractResourcePlugin::<ClearColor>::default(), ExtractResourcePlugin::<ClearColor>::default(),
ExtractComponentPlugin::<CameraMainTextureUsages>::default(),
)); ));
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {

View File

@ -7,8 +7,8 @@ pub use window::*;
use crate::{ use crate::{
camera::{ camera::{
ClearColor, ClearColorConfig, ExposureSettings, ExtractedCamera, ManualTextureViews, CameraMainTextureUsages, ClearColor, ClearColorConfig, ExposureSettings, ExtractedCamera,
MipBias, TemporalJitter, ManualTextureViews, MipBias, TemporalJitter,
}, },
extract_resource::{ExtractResource, ExtractResourcePlugin}, extract_resource::{ExtractResource, ExtractResourcePlugin},
prelude::{Image, Shader}, prelude::{Image, Shader},
@ -465,11 +465,16 @@ fn prepare_view_targets(
clear_color_global: Res<ClearColor>, clear_color_global: Res<ClearColor>,
render_device: Res<RenderDevice>, render_device: Res<RenderDevice>,
mut texture_cache: ResMut<TextureCache>, mut texture_cache: ResMut<TextureCache>,
cameras: Query<(Entity, &ExtractedCamera, &ExtractedView)>, cameras: Query<(
Entity,
&ExtractedCamera,
&ExtractedView,
&CameraMainTextureUsages,
)>,
manual_texture_views: Res<ManualTextureViews>, manual_texture_views: Res<ManualTextureViews>,
) { ) {
let mut textures = HashMap::default(); 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(target_size), Some(target)) = (camera.physical_target_size, &camera.target) {
if let (Some(out_texture_view), Some(out_texture_format)) = ( if let (Some(out_texture_view), Some(out_texture_format)) = (
target.get_texture_view(&windows, &images, &manual_texture_views), target.get_texture_view(&windows, &images, &manual_texture_views),
@ -502,9 +507,7 @@ fn prepare_view_targets(
sample_count: 1, sample_count: 1,
dimension: TextureDimension::D2, dimension: TextureDimension::D2,
format: main_texture_format, format: main_texture_format,
usage: TextureUsages::RENDER_ATTACHMENT usage: texture_usage.0,
| TextureUsages::TEXTURE_BINDING
| TextureUsages::COPY_SRC,
view_formats: match main_texture_format { view_formats: match main_texture_format {
TextureFormat::Bgra8Unorm => &[TextureFormat::Bgra8UnormSrgb], TextureFormat::Bgra8Unorm => &[TextureFormat::Bgra8UnormSrgb],
TextureFormat::Rgba8Unorm => &[TextureFormat::Rgba8UnormSrgb], TextureFormat::Rgba8Unorm => &[TextureFormat::Rgba8UnormSrgb],