Skip to content
Merged
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
1 change: 1 addition & 0 deletions crates/bevy_color/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
54 changes: 48 additions & 6 deletions crates/bevy_color/src/linear_rgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 }
Expand Down Expand Up @@ -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
}
}

Expand Down Expand Up @@ -205,6 +236,17 @@ impl From<Hsla> for LinearRgba {
}
}

impl From<LinearRgba> 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,
}
}
}
Comment on lines +239 to +248
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since bevy_color is our new color management library specifically for Bevy, would it be worth moving to f64 internally to avoid this casting? The extra precision will eat up more memory, but also expose the full precision of wgpu to end users.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question. I think that should be investigated after migration: then we can get both benchmark results and see if there's meaningfully improved color fidelity or numerical stability.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably won't make a big difference on the code-path where wgpu almost immediately casts the color back to a f32 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, at this rate I guess we're getting bevy_wgpu


#[cfg(test)]
mod tests {
use super::*;
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_core_pipeline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod downsampling_pipeline;
mod settings;
mod upsampling_pipeline;

use bevy_color::LinearRgba;
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};

use crate::{
Expand All @@ -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},
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand Down
12 changes: 6 additions & 6 deletions crates/bevy_core_pipeline/src/core_3d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub const CORE_3D_DEPTH_FORMAT: TextureFormat = TextureFormat::Depth32Float;
use std::{cmp::Reverse, 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::*;
Expand All @@ -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,
Expand Down Expand Up @@ -837,18 +837,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,
});
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_core_pipeline/src/msaa_writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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,
},
})],
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/render_phase/draw_state.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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));
}
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_render/src/texture/texture_attachment.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -13,15 +14,15 @@ use wgpu::{
pub struct ColorAttachment {
pub texture: CachedTexture,
pub resolve_target: Option<CachedTexture>,
clear_color: Option<LegacyColor>,
clear_color: Option<LinearRgba>,
is_first_call: Arc<AtomicBool>,
}

impl ColorAttachment {
pub fn new(
texture: CachedTexture,
resolve_target: Option<CachedTexture>,
clear_color: Option<LegacyColor>,
clear_color: Option<LinearRgba>,
) -> Self {
Self {
texture,
Expand Down
6 changes: 4 additions & 2 deletions crates/bevy_render/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
};

Expand Down