diff --git a/crates/bevy_color/Cargo.toml b/crates/bevy_color/Cargo.toml index 908198a915..4997436e19 100644 --- a/crates/bevy_color/Cargo.toml +++ b/crates/bevy_color/Cargo.toml @@ -15,6 +15,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", features = [ ] } serde = "1.0" thiserror = "1.0" +wgpu = { version = "0.19.1", default-features = false } [lints] workspace = true diff --git a/crates/bevy_color/src/linear_rgba.rs b/crates/bevy_color/src/linear_rgba.rs index 0c3375b5a8..375d910c12 100644 --- a/crates/bevy_color/src/linear_rgba.rs +++ b/crates/bevy_color/src/linear_rgba.rs @@ -23,6 +23,30 @@ pub struct LinearRgba { impl StandardColor for LinearRgba {} impl LinearRgba { + /// A fully black color with full alpha. + pub const BLACK: Self = Self { + red: 0.0, + green: 0.0, + blue: 0.0, + alpha: 1.0, + }; + + /// A fully white color with full alpha. + pub const WHITE: Self = Self { + red: 1.0, + green: 1.0, + blue: 1.0, + alpha: 1.0, + }; + + /// A fully transparent color. + pub const NONE: Self = Self { + red: 0.0, + green: 0.0, + blue: 0.0, + alpha: 0.0, + }; + /// Construct a new [`LinearRgba`] color from components. pub const fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self { Self { @@ -49,6 +73,18 @@ impl LinearRgba { } } + /// Construct a new [`LinearRgba`] color with the same value for all channels and an alpha of 1.0. + /// + /// A value of 0.0 is black, and a value of 1.0 is white. + pub const fn gray(value: f32) -> Self { + Self { + red: value, + green: value, + blue: value, + alpha: 1.0, + } + } + /// Return a copy of this color with the red channel set to the given value. pub const fn with_red(self, red: f32) -> Self { Self { red, ..self } @@ -81,12 +117,7 @@ impl LinearRgba { impl Default for LinearRgba { /// Construct a new [`LinearRgba`] color with the default values (white with full alpha). fn default() -> Self { - Self { - red: 1., - green: 1., - blue: 1., - alpha: 1., - } + Self::WHITE } } @@ -205,6 +236,17 @@ impl From for LinearRgba { } } +impl From for wgpu::Color { + fn from(color: LinearRgba) -> Self { + wgpu::Color { + r: color.red as f64, + g: color.green as f64, + b: color.blue as f64, + a: color.alpha as f64, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/bevy_core_pipeline/Cargo.toml b/crates/bevy_core_pipeline/Cargo.toml index 5460d03e61..7b7aaee4af 100644 --- a/crates/bevy_core_pipeline/Cargo.toml +++ b/crates/bevy_core_pipeline/Cargo.toml @@ -24,6 +24,7 @@ tonemapping_luts = ["bevy_render/ktx2", "bevy_render/zstd"] bevy_app = { path = "../bevy_app", version = "0.14.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } bevy_core = { path = "../bevy_core", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } bevy_derive = { path = "../bevy_derive", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } bevy_log = { path = "../bevy_log", version = "0.14.0-dev" } diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index 2896e86e1e..55d5a70719 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -2,6 +2,7 @@ mod downsampling_pipeline; mod settings; mod upsampling_pipeline; +use bevy_color::LinearRgba; pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings}; use crate::{ @@ -17,7 +18,6 @@ use bevy_render::{ extract_component::{ ComponentUniforms, DynamicUniformIndex, ExtractComponentPlugin, UniformComponentPlugin, }, - prelude::LegacyColor, render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner}, render_resource::*, renderer::{RenderContext, RenderDevice}, @@ -244,7 +244,7 @@ impl ViewNode for BloomNode { mip as f32, (bloom_texture.mip_count - 1) as f32, ); - upsampling_pass.set_blend_constant(LegacyColor::rgb_linear(blend, blend, blend)); + upsampling_pass.set_blend_constant(LinearRgba::gray(blend)); upsampling_pass.draw(0..3, 0..1); } @@ -271,7 +271,7 @@ impl ViewNode for BloomNode { } let blend = compute_blend_factor(bloom_settings, 0.0, (bloom_texture.mip_count - 1) as f32); - upsampling_final_pass.set_blend_constant(LegacyColor::rgb_linear(blend, blend, blend)); + upsampling_final_pass.set_blend_constant(LinearRgba::gray(blend)); upsampling_final_pass.draw(0..3, 0..1); } diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index b4d407776d..ece7101621 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -41,6 +41,7 @@ pub const CORE_3D_DEPTH_FORMAT: TextureFormat = TextureFormat::Depth32Float; use std::ops::Range; use bevy_asset::AssetId; +use bevy_color::LinearRgba; pub use camera_3d::*; pub use main_opaque_pass_3d_node::*; pub use main_transparent_pass_3d_node::*; @@ -49,7 +50,6 @@ use bevy_app::{App, Plugin, PostUpdate}; use bevy_ecs::prelude::*; use bevy_render::{ camera::{Camera, ExtractedCamera}, - color::LegacyColor, extract_component::ExtractComponentPlugin, mesh::Mesh, prelude::Msaa, @@ -836,18 +836,18 @@ pub fn prepare_prepass_textures( commands.entity(entity).insert(ViewPrepassTextures { depth: cached_depth_texture - .map(|t| ColorAttachment::new(t, None, Some(LegacyColor::BLACK))), + .map(|t| ColorAttachment::new(t, None, Some(LinearRgba::BLACK))), normal: cached_normals_texture - .map(|t| ColorAttachment::new(t, None, Some(LegacyColor::BLACK))), + .map(|t| ColorAttachment::new(t, None, Some(LinearRgba::BLACK))), // Red and Green channels are X and Y components of the motion vectors // Blue channel doesn't matter, but set to 0.0 for possible faster clear // https://gpuopen.com/performance/#clears motion_vectors: cached_motion_vectors_texture - .map(|t| ColorAttachment::new(t, None, Some(LegacyColor::BLACK))), + .map(|t| ColorAttachment::new(t, None, Some(LinearRgba::BLACK))), deferred: cached_deferred_texture - .map(|t| ColorAttachment::new(t, None, Some(LegacyColor::BLACK))), + .map(|t| ColorAttachment::new(t, None, Some(LinearRgba::BLACK))), deferred_lighting_pass_id: cached_deferred_lighting_pass_id_texture - .map(|t| ColorAttachment::new(t, None, Some(LegacyColor::BLACK))), + .map(|t| ColorAttachment::new(t, None, Some(LinearRgba::BLACK))), size, }); } diff --git a/crates/bevy_core_pipeline/src/msaa_writeback.rs b/crates/bevy_core_pipeline/src/msaa_writeback.rs index b52bbd0e48..01ca12a4fe 100644 --- a/crates/bevy_core_pipeline/src/msaa_writeback.rs +++ b/crates/bevy_core_pipeline/src/msaa_writeback.rs @@ -4,10 +4,10 @@ use crate::{ core_3d::graph::{Core3d, Node3d}, }; use bevy_app::{App, Plugin}; +use bevy_color::LinearRgba; use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, - color::LegacyColor, render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext}, renderer::RenderContext, view::{Msaa, ViewTarget}, @@ -92,7 +92,7 @@ impl Node for MsaaWritebackNode { view: target.sampled_main_texture_view().unwrap(), resolve_target: Some(post_process.destination), ops: Operations { - load: LoadOp::Clear(LegacyColor::BLACK.into()), + load: LoadOp::Clear(LinearRgba::BLACK.into()), store: StoreOp::Store, }, })], diff --git a/crates/bevy_render/src/render_phase/draw_state.rs b/crates/bevy_render/src/render_phase/draw_state.rs index 62f668ce95..0c09b6aba6 100644 --- a/crates/bevy_render/src/render_phase/draw_state.rs +++ b/crates/bevy_render/src/render_phase/draw_state.rs @@ -1,12 +1,12 @@ use crate::{ camera::Viewport, - prelude::LegacyColor, render_resource::{ BindGroup, BindGroupId, Buffer, BufferId, BufferSlice, RenderPipeline, RenderPipelineId, ShaderStages, }, renderer::RenderDevice, }; +use bevy_color::LinearRgba; use bevy_utils::{default, detailed_trace}; use std::ops::Range; use wgpu::{IndexFormat, RenderPass}; @@ -598,7 +598,7 @@ impl<'a> TrackedRenderPass<'a> { /// Sets the blend color as used by some of the blending modes. /// /// Subsequent blending tests will test against this value. - pub fn set_blend_constant(&mut self, color: LegacyColor) { + pub fn set_blend_constant(&mut self, color: LinearRgba) { detailed_trace!("set blend constant: {:?}", color); self.pass.set_blend_constant(wgpu::Color::from(color)); } diff --git a/crates/bevy_render/src/texture/texture_attachment.rs b/crates/bevy_render/src/texture/texture_attachment.rs index 425b12146c..220b9c5e03 100644 --- a/crates/bevy_render/src/texture/texture_attachment.rs +++ b/crates/bevy_render/src/texture/texture_attachment.rs @@ -1,5 +1,6 @@ use super::CachedTexture; -use crate::{prelude::LegacyColor, render_resource::TextureView}; +use crate::render_resource::TextureView; +use bevy_color::LinearRgba; use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -13,7 +14,7 @@ use wgpu::{ pub struct ColorAttachment { pub texture: CachedTexture, pub resolve_target: Option, - clear_color: Option, + clear_color: Option, is_first_call: Arc, } @@ -21,7 +22,7 @@ impl ColorAttachment { pub fn new( texture: CachedTexture, resolve_target: Option, - clear_color: Option, + clear_color: Option, ) -> Self { Self { texture, diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index 73299084d6..444888b569 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -551,9 +551,11 @@ pub fn prepare_view_targets( (a, b, sampled, main_texture) }); + let converted_clear_color = clear_color.map(|color| color.into()); + let main_textures = MainTargetTextures { - a: ColorAttachment::new(a.clone(), sampled.clone(), clear_color), - b: ColorAttachment::new(b.clone(), sampled.clone(), clear_color), + a: ColorAttachment::new(a.clone(), sampled.clone(), converted_clear_color), + b: ColorAttachment::new(b.clone(), sampled.clone(), converted_clear_color), main_texture: main_texture.clone(), };