diff --git a/Cargo.toml b/Cargo.toml index 170e9457589c7..c3d21c4418eca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -445,7 +445,7 @@ android_shared_stdcxx = ["bevy_internal/android_shared_stdcxx"] # Enable detailed trace event logging. These trace events are expensive even when off, thus they require compile time opt-in detailed_trace = ["bevy_internal/detailed_trace"] -# Include tonemapping Look Up Tables KTX2 files. If everything is pink, you need to enable this feature or change the `Tonemapping` method for your `Camera2d` or `Camera3d`. +# Include tonemapping Look Up Tables KTX2 files. tonemapping_luts = ["bevy_internal/tonemapping_luts"] # Include SMAA Look Up Tables KTX2 Files diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 8b1379f6b19b2..521ab5a9b64bb 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -1,14 +1,16 @@ use bevy_app::prelude::*; use bevy_asset::{ - embedded_asset, load_embedded_asset, AssetServer, Assets, Handle, RenderAssetUsages, + embedded_asset, load_embedded_asset, uuid_handle, AssetServer, Assets, Handle, + RenderAssetUsages, }; use bevy_camera::Camera; use bevy_ecs::prelude::*; use bevy_image::{CompressedImageFormats, Image, ImageSampler, ImageType}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; +#[cfg(feature = "tonemapping_luts")] +use bevy_render::extract_resource::{ExtractResource, ExtractResourcePlugin}; use bevy_render::{ extract_component::{ExtractComponent, ExtractComponentPlugin}, - extract_resource::{ExtractResource, ExtractResourcePlugin}, render_asset::RenderAssets, render_resource::{ binding_types::{sampler, texture_2d, texture_3d, uniform_buffer}, @@ -21,7 +23,6 @@ use bevy_render::{ }; use bevy_shader::{load_shader_library, Shader, ShaderDefVal}; use bitflags::bitflags; -#[cfg(not(feature = "tonemapping_luts"))] use tracing::error; mod node; @@ -31,8 +32,12 @@ pub use node::TonemappingNode; use crate::FullscreenShader; -/// 3D LUT (look up table) textures used for tonemapping +/// 1x1 image used for the Tonemapping methods that do not use LUTs +const PLACEHOLDER_LUTS_IMAGE: Handle = uuid_handle!("39bd4241-aa05-401a-b5ad-4dd963254fff"); + +/// 3D LUT (look up table) textures used for tonemapping. #[derive(Resource, Clone, ExtractResource)] +#[cfg(feature = "tonemapping_luts")] pub struct TonemappingLuts { pub blender_filmic: Handle, pub agx: Handle, @@ -48,40 +53,33 @@ impl Plugin for TonemappingPlugin { embedded_asset!(app, "tonemapping.wgsl"); + #[cfg(feature = "tonemapping_luts")] if !app.world().is_resource_added::() { let mut images = app.world_mut().resource_mut::>(); - - #[cfg(feature = "tonemapping_luts")] - let tonemapping_luts = { - TonemappingLuts { - blender_filmic: images.add(setup_tonemapping_lut_image( - include_bytes!("luts/Blender_-11_12.ktx2"), - ImageType::Extension("ktx2"), - )), - agx: images.add(setup_tonemapping_lut_image( - include_bytes!("luts/AgX-default_contrast.ktx2"), - ImageType::Extension("ktx2"), - )), - tony_mc_mapface: images.add(setup_tonemapping_lut_image( - include_bytes!("luts/tony_mc_mapface.ktx2"), - ImageType::Extension("ktx2"), - )), - } - }; - - #[cfg(not(feature = "tonemapping_luts"))] - let tonemapping_luts = { - let placeholder = images.add(lut_placeholder()); - TonemappingLuts { - blender_filmic: placeholder.clone(), - agx: placeholder.clone(), - tony_mc_mapface: placeholder, - } + let tonemapping_luts = TonemappingLuts { + blender_filmic: images.add(setup_tonemapping_lut_image( + include_bytes!("luts/Blender_-11_12.ktx2"), + ImageType::Extension("ktx2"), + )), + agx: images.add(setup_tonemapping_lut_image( + include_bytes!("luts/AgX-default_contrast.ktx2"), + ImageType::Extension("ktx2"), + )), + tony_mc_mapface: images.add(setup_tonemapping_lut_image( + include_bytes!("luts/tony_mc_mapface.ktx2"), + ImageType::Extension("ktx2"), + )), }; app.insert_resource(tonemapping_luts); } + let mut images = app.world_mut().resource_mut::>(); + if let Err(err) = images.insert(PLACEHOLDER_LUTS_IMAGE.id(), lut_placeholder()) { + error!("Failed to create Placeholder LUTs due to '{err}'."); + } + + #[cfg(feature = "tonemapping_luts")] app.add_plugins(ExtractResourcePlugin::::default()); app.add_plugins(( @@ -111,6 +109,9 @@ pub struct TonemappingPipeline { } /// Optionally enables a tonemapping shader that attempts to map linear input stimulus into a perceptually uniform image for a given [`Camera`] entity. +/// +/// The default when `tonemapping_luts` is enabled is [`TonyMcMapface`](Tonemapping::TonyMcMapface), +/// otherwise it is [`None`](Tonemapping::None). #[derive( Component, Debug, Hash, Clone, Copy, Reflect, Default, ExtractComponent, PartialEq, Eq, )] @@ -118,6 +119,9 @@ pub struct TonemappingPipeline { #[reflect(Component, Debug, Hash, Default, PartialEq)] pub enum Tonemapping { /// Bypass tonemapping. + /// + /// Default when `tonemapping_luts` is disabled. + #[cfg_attr(not(feature = "tonemapping_luts"), default)] None, /// Suffers from lots hue shifting, brights don't desaturate naturally. /// Bright primaries and secondaries don't desaturate at all. @@ -134,7 +138,7 @@ pub enum Tonemapping { /// /// Very neutral. Image is somewhat desaturated when compared to other tonemappers. /// Little to no hue shifting. Subtle [Abney shifting](https://en.wikipedia.org/wiki/Abney_effect). - /// NOTE: Requires the `tonemapping_luts` cargo feature. + #[cfg(feature = "tonemapping_luts")] AgX, /// By Tomasz Stachowiak /// Has little hue shifting in the darks and mids, but lots in the brights. Brights desaturate across the spectrum. @@ -153,12 +157,14 @@ pub enum Tonemapping { /// Brightness-equivalent luminance of the input stimulus is compressed. The non-linearity resembles Reinhard. /// Color hues are preserved during compression, except for a deliberate [Bezold–Brücke shift](https://en.wikipedia.org/wiki/Bezold%E2%80%93Br%C3%BCcke_shift). /// To avoid posterization, selective desaturation is employed, with care to avoid the [Abney effect](https://en.wikipedia.org/wiki/Abney_effect). - /// NOTE: Requires the `tonemapping_luts` cargo feature. - #[default] + /// + /// Default when `tonemapping_luts` is enabled. + #[cfg_attr(feature = "tonemapping_luts", default)] + #[cfg(feature = "tonemapping_luts")] TonyMcMapface, /// Default Filmic Display Transform from blender. /// Somewhat neutral. Suffers from hue shifting. Brights desaturate across the spectrum. - /// NOTE: Requires the `tonemapping_luts` cargo feature. + #[cfg(feature = "tonemapping_luts")] BlenderFilmic, } @@ -234,34 +240,19 @@ impl SpecializedRenderPipeline for TonemappingPipeline { shader_defs.push("TONEMAP_METHOD_REINHARD_LUMINANCE".into()); } Tonemapping::AcesFitted => shader_defs.push("TONEMAP_METHOD_ACES_FITTED".into()), + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX => { - #[cfg(not(feature = "tonemapping_luts"))] - error!( - "AgX tonemapping requires the `tonemapping_luts` feature. - Either enable the `tonemapping_luts` feature for bevy in `Cargo.toml` (recommended), - or use a different `Tonemapping` method for your `Camera2d`/`Camera3d`." - ); shader_defs.push("TONEMAP_METHOD_AGX".into()); } Tonemapping::SomewhatBoringDisplayTransform => { shader_defs.push("TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM".into()); } + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface => { - #[cfg(not(feature = "tonemapping_luts"))] - error!( - "TonyMcMapFace tonemapping requires the `tonemapping_luts` feature. - Either enable the `tonemapping_luts` feature for bevy in `Cargo.toml` (recommended), - or use a different `Tonemapping` method for your `Camera2d`/`Camera3d`." - ); shader_defs.push("TONEMAP_METHOD_TONY_MC_MAPFACE".into()); } + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic => { - #[cfg(not(feature = "tonemapping_luts"))] - error!( - "BlenderFilmic tonemapping requires the `tonemapping_luts` feature. - Either enable the `tonemapping_luts` feature for bevy in `Cargo.toml` (recommended), - or use a different `Tonemapping` method for your `Camera2d`/`Camera3d`." - ); shader_defs.push("TONEMAP_METHOD_BLENDER_FILMIC".into()); } } @@ -379,7 +370,7 @@ pub enum DebandDither { pub fn get_lut_bindings<'a>( images: &'a RenderAssets, - tonemapping_luts: &'a TonemappingLuts, + #[cfg(feature = "tonemapping_luts")] tonemapping_luts: &'a TonemappingLuts, tonemapping: &Tonemapping, fallback_image: &'a FallbackImage, ) -> (&'a TextureView, &'a Sampler) { @@ -389,9 +380,12 @@ pub fn get_lut_bindings<'a>( | Tonemapping::Reinhard | Tonemapping::ReinhardLuminance | Tonemapping::AcesFitted - | Tonemapping::AgX - | Tonemapping::SomewhatBoringDisplayTransform => &tonemapping_luts.agx, + | Tonemapping::SomewhatBoringDisplayTransform => &PLACEHOLDER_LUTS_IMAGE, + #[cfg(feature = "tonemapping_luts")] + Tonemapping::AgX => &tonemapping_luts.agx, + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface => &tonemapping_luts.tony_mc_mapface, + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic => &tonemapping_luts.blender_filmic, }; let lut_image = images.get(image).unwrap_or(&fallback_image.d3); diff --git a/crates/bevy_core_pipeline/src/tonemapping/node.rs b/crates/bevy_core_pipeline/src/tonemapping/node.rs index d14f1251fc4b6..c5550e9d8e11d 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/node.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/node.rs @@ -1,6 +1,8 @@ use std::sync::Mutex; -use crate::tonemapping::{TonemappingLuts, TonemappingPipeline, ViewTonemappingPipeline}; +#[cfg(feature = "tonemapping_luts")] +use crate::tonemapping::TonemappingLuts; +use crate::tonemapping::{TonemappingPipeline, ViewTonemappingPipeline}; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_render::{ @@ -89,10 +91,16 @@ impl ViewNode for TonemappingNode { bind_group } cached_bind_group => { + #[cfg(feature = "tonemapping_luts")] let tonemapping_luts = world.resource::(); - let lut_bindings = - get_lut_bindings(gpu_images, tonemapping_luts, tonemapping, fallback_image); + let lut_bindings = get_lut_bindings( + gpu_images, + #[cfg(feature = "tonemapping_luts")] + tonemapping_luts, + tonemapping, + fallback_image, + ); let bind_group = render_context.render_device().create_bind_group( None, diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index babb95a4dac1c..7182f5fb68496 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -68,6 +68,8 @@ raw_vulkan_init = ["bevy_render/raw_vulkan_init"] # Include tonemapping LUT KTX2 files. tonemapping_luts = [ "bevy_core_pipeline?/tonemapping_luts", + "bevy_pbr?/tonemapping_luts", + "bevy_sprite_render?/tonemapping_luts", "ktx2", "bevy_image/zstd", ] diff --git a/crates/bevy_pbr/Cargo.toml b/crates/bevy_pbr/Cargo.toml index a5d06399ee3d3..ebef0fe858212 100644 --- a/crates/bevy_pbr/Cargo.toml +++ b/crates/bevy_pbr/Cargo.toml @@ -31,6 +31,7 @@ meshlet_processor = [ "dep:itertools", "dep:bitvec", ] +tonemapping_luts = ["bevy_core_pipeline/tonemapping_luts"] [dependencies] # bevy diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 2eee4303795b3..754b693b27563 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -270,14 +270,17 @@ impl SpecializedRenderPipeline for DeferredLightingLayout { shader_defs.push("TONEMAP_METHOD_REINHARD_LUMINANCE".into()); } else if method == MeshPipelineKey::TONEMAP_METHOD_ACES_FITTED { shader_defs.push("TONEMAP_METHOD_ACES_FITTED".into()); - } else if method == MeshPipelineKey::TONEMAP_METHOD_AGX { - shader_defs.push("TONEMAP_METHOD_AGX".into()); } else if method == MeshPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM { shader_defs.push("TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM".into()); - } else if method == MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC { - shader_defs.push("TONEMAP_METHOD_BLENDER_FILMIC".into()); - } else if method == MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE { - shader_defs.push("TONEMAP_METHOD_TONY_MC_MAPFACE".into()); + } else { + #[cfg(feature = "tonemapping_luts")] + if method == MeshPipelineKey::TONEMAP_METHOD_AGX { + shader_defs.push("TONEMAP_METHOD_AGX".into()); + } else if method == MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC { + shader_defs.push("TONEMAP_METHOD_BLENDER_FILMIC".into()); + } else if method == MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE { + shader_defs.push("TONEMAP_METHOD_TONY_MC_MAPFACE".into()); + } } // Debanding is tied to tonemapping in the shader, cannot run without it. @@ -503,11 +506,14 @@ pub fn prepare_deferred_lighting_pipelines( MeshPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE } Tonemapping::AcesFitted => MeshPipelineKey::TONEMAP_METHOD_ACES_FITTED, + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX => MeshPipelineKey::TONEMAP_METHOD_AGX, Tonemapping::SomewhatBoringDisplayTransform => { MeshPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM } + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface => MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE, + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic => MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC, }; } diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index ec46bd4f9fd16..299862a9756c1 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -632,11 +632,14 @@ pub const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> MeshPipelineK Tonemapping::Reinhard => MeshPipelineKey::TONEMAP_METHOD_REINHARD, Tonemapping::ReinhardLuminance => MeshPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE, Tonemapping::AcesFitted => MeshPipelineKey::TONEMAP_METHOD_ACES_FITTED, + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX => MeshPipelineKey::TONEMAP_METHOD_AGX, Tonemapping::SomewhatBoringDisplayTransform => { MeshPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM } + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface => MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE, + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic => MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC, } } diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 2281366b3757c..87c0480710e04 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -2107,9 +2107,12 @@ bitflags::bitflags! { const TONEMAP_METHOD_REINHARD = 1 << Self::TONEMAP_METHOD_SHIFT_BITS; const TONEMAP_METHOD_REINHARD_LUMINANCE = 2 << Self::TONEMAP_METHOD_SHIFT_BITS; const TONEMAP_METHOD_ACES_FITTED = 3 << Self::TONEMAP_METHOD_SHIFT_BITS; + #[cfg(feature = "tonemapping_luts")] const TONEMAP_METHOD_AGX = 4 << Self::TONEMAP_METHOD_SHIFT_BITS; const TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM = 5 << Self::TONEMAP_METHOD_SHIFT_BITS; + #[cfg(feature = "tonemapping_luts")] const TONEMAP_METHOD_TONY_MC_MAPFACE = 6 << Self::TONEMAP_METHOD_SHIFT_BITS; + #[cfg(feature = "tonemapping_luts")] const TONEMAP_METHOD_BLENDER_FILMIC = 7 << Self::TONEMAP_METHOD_SHIFT_BITS; const SHADOW_FILTER_METHOD_RESERVED_BITS = Self::SHADOW_FILTER_METHOD_MASK_BITS << Self::SHADOW_FILTER_METHOD_SHIFT_BITS; const SHADOW_FILTER_METHOD_HARDWARE_2X2 = 0 << Self::SHADOW_FILTER_METHOD_SHIFT_BITS; @@ -2491,14 +2494,17 @@ impl SpecializedMeshPipeline for MeshPipeline { shader_defs.push("TONEMAP_METHOD_REINHARD_LUMINANCE".into()); } else if method == MeshPipelineKey::TONEMAP_METHOD_ACES_FITTED { shader_defs.push("TONEMAP_METHOD_ACES_FITTED".into()); - } else if method == MeshPipelineKey::TONEMAP_METHOD_AGX { - shader_defs.push("TONEMAP_METHOD_AGX".into()); } else if method == MeshPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM { shader_defs.push("TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM".into()); - } else if method == MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC { - shader_defs.push("TONEMAP_METHOD_BLENDER_FILMIC".into()); - } else if method == MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE { - shader_defs.push("TONEMAP_METHOD_TONY_MC_MAPFACE".into()); + } else { + #[cfg(feature = "tonemapping_luts")] + if method == MeshPipelineKey::TONEMAP_METHOD_AGX { + shader_defs.push("TONEMAP_METHOD_AGX".into()); + } else if method == MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC { + shader_defs.push("TONEMAP_METHOD_BLENDER_FILMIC".into()); + } else if method == MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE { + shader_defs.push("TONEMAP_METHOD_TONY_MC_MAPFACE".into()); + } } // Debanding is tied to tonemapping in the shader, cannot run without it. diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.rs b/crates/bevy_pbr/src/render/mesh_view_bindings.rs index 5c1e0e8a47b7b..fdc07c8baf145 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.rs @@ -1,12 +1,13 @@ use alloc::sync::Arc; +#[cfg(feature = "tonemapping_luts")] +use bevy_core_pipeline::tonemapping::TonemappingLuts; use bevy_core_pipeline::{ core_3d::ViewTransmissionTexture, oit::{resolve::is_oit_supported, OitBuffers, OrderIndependentTransparencySettings}, prepass::ViewPrepassTextures, - tonemapping::{ - get_lut_bind_group_layout_entries, get_lut_bindings, Tonemapping, TonemappingLuts, - }, + tonemapping::{get_lut_bind_group_layout_entries, get_lut_bindings, Tonemapping}, }; + use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ component::Component, @@ -566,7 +567,7 @@ pub fn prepare_mesh_view_bind_groups( Res, ), globals_buffer: Res, - tonemapping_luts: Res, + #[cfg(feature = "tonemapping_luts")] tonemapping_luts: Res, light_probes_buffer: Res, visibility_ranges: Res, ssr_buffer: Res, @@ -653,8 +654,13 @@ pub fn prepare_mesh_view_bind_groups( entries = entries.extend_with_indices(((17, environment_map_binding.clone()),)); - let lut_bindings = - get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); + let lut_bindings = get_lut_bindings( + &images, + #[cfg(feature = "tonemapping_luts")] + &tonemapping_luts, + tonemapping, + &fallback_image, + ); entries = entries.extend_with_indices(((18, lut_bindings.0), (19, lut_bindings.1))); // When using WebGL, we can't have a depth texture with multisampling diff --git a/crates/bevy_sprite_render/Cargo.toml b/crates/bevy_sprite_render/Cargo.toml index d0b20a3052750..8dc2384242ff8 100644 --- a/crates/bevy_sprite_render/Cargo.toml +++ b/crates/bevy_sprite_render/Cargo.toml @@ -12,6 +12,7 @@ keywords = ["bevy"] webgl = [] webgpu = [] bevy_text = ["dep:bevy_text", "bevy_sprite/bevy_text"] +tonemapping_luts = ["bevy_core_pipeline/tonemapping_luts"] [dependencies] # bevy diff --git a/crates/bevy_sprite_render/src/mesh2d/material.rs b/crates/bevy_sprite_render/src/mesh2d/material.rs index a96c1e01a37e1..a8ad39d243e89 100644 --- a/crates/bevy_sprite_render/src/mesh2d/material.rs +++ b/crates/bevy_sprite_render/src/mesh2d/material.rs @@ -555,11 +555,14 @@ pub const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> Mesh2dPipelin Tonemapping::Reinhard => Mesh2dPipelineKey::TONEMAP_METHOD_REINHARD, Tonemapping::ReinhardLuminance => Mesh2dPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE, Tonemapping::AcesFitted => Mesh2dPipelineKey::TONEMAP_METHOD_ACES_FITTED, + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX => Mesh2dPipelineKey::TONEMAP_METHOD_AGX, Tonemapping::SomewhatBoringDisplayTransform => { Mesh2dPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM } + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface => Mesh2dPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE, + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic => Mesh2dPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC, } } diff --git a/crates/bevy_sprite_render/src/mesh2d/mesh.rs b/crates/bevy_sprite_render/src/mesh2d/mesh.rs index 1eff9be1c2904..b59e99107148b 100644 --- a/crates/bevy_sprite_render/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite_render/src/mesh2d/mesh.rs @@ -5,12 +5,11 @@ use bevy_render::RenderStartup; use bevy_shader::{load_shader_library, Shader, ShaderDefVal, ShaderSettings}; use crate::{tonemapping_pipeline_key, Material2dBindGroupId}; +#[cfg(feature = "tonemapping_luts")] +use bevy_core_pipeline::tonemapping::TonemappingLuts; use bevy_core_pipeline::{ core_2d::{AlphaMask2d, Opaque2d, Transparent2d, CORE_2D_DEPTH_FORMAT}, - tonemapping::{ - get_lut_bind_group_layout_entries, get_lut_bindings, DebandDither, Tonemapping, - TonemappingLuts, - }, + tonemapping::{get_lut_bind_group_layout_entries, get_lut_bindings, DebandDither, Tonemapping}, }; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::component::Tick; @@ -488,9 +487,12 @@ bitflags::bitflags! { const TONEMAP_METHOD_REINHARD = 1 << Self::TONEMAP_METHOD_SHIFT_BITS; const TONEMAP_METHOD_REINHARD_LUMINANCE = 2 << Self::TONEMAP_METHOD_SHIFT_BITS; const TONEMAP_METHOD_ACES_FITTED = 3 << Self::TONEMAP_METHOD_SHIFT_BITS; + #[cfg(feature = "tonemapping_luts")] const TONEMAP_METHOD_AGX = 4 << Self::TONEMAP_METHOD_SHIFT_BITS; const TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM = 5 << Self::TONEMAP_METHOD_SHIFT_BITS; + #[cfg(feature = "tonemapping_luts")] const TONEMAP_METHOD_TONY_MC_MAPFACE = 6 << Self::TONEMAP_METHOD_SHIFT_BITS; + #[cfg(feature = "tonemapping_luts")] const TONEMAP_METHOD_BLENDER_FILMIC = 7 << Self::TONEMAP_METHOD_SHIFT_BITS; } } @@ -605,15 +607,18 @@ impl SpecializedMeshPipeline for Mesh2dPipeline { Mesh2dPipelineKey::TONEMAP_METHOD_ACES_FITTED => { shader_defs.push("TONEMAP_METHOD_ACES_FITTED".into()); } + #[cfg(feature = "tonemapping_luts")] Mesh2dPipelineKey::TONEMAP_METHOD_AGX => { shader_defs.push("TONEMAP_METHOD_AGX".into()); } Mesh2dPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM => { shader_defs.push("TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM".into()); } + #[cfg(feature = "tonemapping_luts")] Mesh2dPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC => { shader_defs.push("TONEMAP_METHOD_BLENDER_FILMIC".into()); } + #[cfg(feature = "tonemapping_luts")] Mesh2dPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE => { shader_defs.push("TONEMAP_METHOD_TONY_MC_MAPFACE".into()); } @@ -735,7 +740,7 @@ pub fn prepare_mesh2d_view_bind_groups( view_uniforms: Res, views: Query<(Entity, &Tonemapping), (With, With)>, globals_buffer: Res, - tonemapping_luts: Res, + #[cfg(feature = "tonemapping_luts")] tonemapping_luts: Res, images: Res>, fallback_image: Res, ) { @@ -747,8 +752,13 @@ pub fn prepare_mesh2d_view_bind_groups( }; for (entity, tonemapping) in &views { - let lut_bindings = - get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); + let lut_bindings = get_lut_bindings( + &images, + #[cfg(feature = "tonemapping_luts")] + &tonemapping_luts, + tonemapping, + &fallback_image, + ); let view_bind_group = render_device.create_bind_group( "mesh2d_view_bind_group", &mesh2d_pipeline.view_layout, diff --git a/crates/bevy_sprite_render/src/render/mod.rs b/crates/bevy_sprite_render/src/render/mod.rs index 0ea54bf7f2ed2..904098fb6cdcf 100644 --- a/crates/bevy_sprite_render/src/render/mod.rs +++ b/crates/bevy_sprite_render/src/render/mod.rs @@ -4,12 +4,11 @@ use crate::ComputedTextureSlices; use bevy_asset::{load_embedded_asset, AssetEvent, AssetId, AssetServer, Assets, Handle}; use bevy_camera::visibility::ViewVisibility; use bevy_color::{ColorToComponents, LinearRgba}; +#[cfg(feature = "tonemapping_luts")] +use bevy_core_pipeline::tonemapping::TonemappingLuts; use bevy_core_pipeline::{ core_2d::{Transparent2d, CORE_2D_DEPTH_FORMAT}, - tonemapping::{ - get_lut_bind_group_layout_entries, get_lut_bindings, DebandDither, Tonemapping, - TonemappingLuts, - }, + tonemapping::{get_lut_bind_group_layout_entries, get_lut_bindings, DebandDither, Tonemapping}, }; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ @@ -545,11 +544,14 @@ pub fn queue_sprites( SpritePipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE } Tonemapping::AcesFitted => SpritePipelineKey::TONEMAP_METHOD_ACES_FITTED, + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX => SpritePipelineKey::TONEMAP_METHOD_AGX, Tonemapping::SomewhatBoringDisplayTransform => { SpritePipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM } + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface => SpritePipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE, + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic => SpritePipelineKey::TONEMAP_METHOD_BLENDER_FILMIC, }; } @@ -606,7 +608,7 @@ pub fn prepare_sprite_view_bind_groups( sprite_pipeline: Res, view_uniforms: Res, views: Query<(Entity, &Tonemapping), With>, - tonemapping_luts: Res, + #[cfg(feature = "tonemapping_luts")] tonemapping_luts: Res, images: Res>, fallback_image: Res, ) { @@ -615,8 +617,13 @@ pub fn prepare_sprite_view_bind_groups( }; for (entity, tonemapping) in &views { - let lut_bindings = - get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); + let lut_bindings = get_lut_bindings( + &images, + #[cfg(feature = "tonemapping_luts")] + &tonemapping_luts, + tonemapping, + &fallback_image, + ); let view_bind_group = render_device.create_bind_group( "mesh2d_view_bind_group", &sprite_pipeline.view_layout, diff --git a/docs/cargo_features.md b/docs/cargo_features.md index 530ba2c52a04d..3b086df9a229b 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -59,7 +59,7 @@ The default feature set enables most of the expected features of a game engine, |smaa_luts|Include SMAA Look Up Tables KTX2 Files| |std|Allows access to the `std` crate.| |sysinfo_plugin|Enables system information diagnostic plugin| -|tonemapping_luts|Include tonemapping Look Up Tables KTX2 files. If everything is pink, you need to enable this feature or change the `Tonemapping` method for your `Camera2d` or `Camera3d`.| +|tonemapping_luts|Include tonemapping Look Up Tables KTX2 files.| |vorbis|OGG/VORBIS audio format support| |wayland|Wayland display server support| |webgl2|Enable some limitations to be able to use WebGL2. Please refer to the [WebGL2 and WebGPU](https://github.com/bevyengine/bevy/tree/latest/examples#webgl2-and-webgpu) section of the examples README for more information on how to run Wasm builds with WebGPU.| diff --git a/examples/3d/tonemapping.rs b/examples/3d/tonemapping.rs index 8923beac6ad7b..993ac3e136351 100644 --- a/examples/3d/tonemapping.rs +++ b/examples/3d/tonemapping.rs @@ -1,5 +1,7 @@ //! This examples compares Tonemapping options +#[cfg(feature = "tonemapping_luts")] +use bevy::render::view::ColorGradingSection; use bevy::{ asset::UnapprovedPathMode, core_pipeline::tonemapping::Tonemapping, @@ -9,7 +11,7 @@ use bevy::{ reflect::TypePath, render::{ render_resource::AsBindGroup, - view::{ColorGrading, ColorGradingGlobal, ColorGradingSection, Hdr}, + view::{ColorGrading, ColorGradingGlobal, Hdr}, }, shader::ShaderRef, }; @@ -301,14 +303,17 @@ fn toggle_tonemapping_method( **tonemapping = Tonemapping::ReinhardLuminance; } else if keys.just_pressed(KeyCode::Digit4) { **tonemapping = Tonemapping::AcesFitted; - } else if keys.just_pressed(KeyCode::Digit5) { - **tonemapping = Tonemapping::AgX; } else if keys.just_pressed(KeyCode::Digit6) { **tonemapping = Tonemapping::SomewhatBoringDisplayTransform; - } else if keys.just_pressed(KeyCode::Digit7) { - **tonemapping = Tonemapping::TonyMcMapface; - } else if keys.just_pressed(KeyCode::Digit8) { - **tonemapping = Tonemapping::BlenderFilmic; + } else { + #[cfg(feature = "tonemapping_luts")] + if keys.just_pressed(KeyCode::Digit5) { + **tonemapping = Tonemapping::AgX; + } else if keys.just_pressed(KeyCode::Digit7) { + **tonemapping = Tonemapping::TonyMcMapface; + } else if keys.just_pressed(KeyCode::Digit8) { + **tonemapping = Tonemapping::BlenderFilmic; + } } **color_grading = (*per_method_settings @@ -464,6 +469,7 @@ fn update_ui( "" } )); + #[cfg(feature = "tonemapping_luts")] text.push_str(&format!( "(5) {} AgX\n", if tonemapping == Tonemapping::AgX { @@ -480,6 +486,7 @@ fn update_ui( "" } )); + #[cfg(feature = "tonemapping_luts")] text.push_str(&format!( "(7) {} TonyMcMapface\n", if tonemapping == Tonemapping::TonyMcMapface { @@ -488,6 +495,7 @@ fn update_ui( "" } )); + #[cfg(feature = "tonemapping_luts")] text.push_str(&format!( "(8) {} Blender Filmic\n", if tonemapping == Tonemapping::BlenderFilmic { @@ -558,6 +566,7 @@ impl PerMethodSettings { }, ..default() }, + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX => ColorGrading::with_identical_sections( ColorGradingGlobal { exposure: -0.2, @@ -583,9 +592,12 @@ impl Default for PerMethodSettings { Tonemapping::Reinhard, Tonemapping::ReinhardLuminance, Tonemapping::AcesFitted, + #[cfg(feature = "tonemapping_luts")] Tonemapping::AgX, Tonemapping::SomewhatBoringDisplayTransform, + #[cfg(feature = "tonemapping_luts")] Tonemapping::TonyMcMapface, + #[cfg(feature = "tonemapping_luts")] Tonemapping::BlenderFilmic, ] { settings.insert( diff --git a/release-content/migration-guides/gated-tonemapping.md b/release-content/migration-guides/gated-tonemapping.md new file mode 100644 index 0000000000000..7dfe2080e43c3 --- /dev/null +++ b/release-content/migration-guides/gated-tonemapping.md @@ -0,0 +1,7 @@ +--- +title: `Tonemapping` modes `TonyMcMapface`, `BlenderFilmic`, and `AgX` are now gated behind `tonemapping_luts` +pull_requests: [20924] +--- + +`Tonemapping` mode `TonyMcMapface`, `BlenderFilmic`, and `AgX` are now only present with the `tonemapping_luts` +instead of having a notice on the documentation and logging an error during runtime. diff --git a/release-content/migration-guides/tonemapping-defaults.md b/release-content/migration-guides/tonemapping-defaults.md new file mode 100644 index 0000000000000..d5df7803f8558 --- /dev/null +++ b/release-content/migration-guides/tonemapping-defaults.md @@ -0,0 +1,8 @@ +--- +title: Different defaults for `Tonemapping` based on `tonemapping_luts` feature +pull_requests: [20924] +--- + +`Tonemapping` component now has a different defaults based on `tonemappint_luts` feature. +When `tonemapping_luts` is present the default remains `TonyMcMapface`, but when it is off +the default is now `None`.