Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support non-sRGB texture formats #3903

Closed
wants to merge 21 commits into from
Closed
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ tga = ["bevy_internal/tga"]
jpeg = ["bevy_internal/jpeg"]
bmp = ["bevy_internal/bmp"]

# Disable sRGB (needed for certain physical devices)
no_srgb = ["bevy_internal/no_srgb"]

# Audio format support (MP3 is enabled by default)
flac = ["bevy_internal/flac"]
mp3 = ["bevy_internal/mp3"]
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ tga = ["bevy_render/tga"]
jpeg = ["bevy_render/jpeg"]
bmp = ["bevy_render/bmp"]

# Disable sRGB (needed for certain physical devices)
no_srgb = ["bevy_render/no_srgb", "bevy_pbr/no_srgb", "bevy_sprite/no_srgb"]

# Audio format support (MP3 is enabled by default)
flac = ["bevy_audio/flac"]
mp3 = ["bevy_audio/mp3"]
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_pbr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ keywords = ["bevy"]

[features]
webgl = []
no_srgb = []

[dependencies]
# bevy
Expand Down
11 changes: 10 additions & 1 deletion crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,16 @@ impl Plugin for PbrPlugin {
let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
shaders.set_untracked(
PBR_SHADER_HANDLE,
Shader::from_wgsl(include_str!("render/pbr.wgsl")),
#[cfg(not(feature = "no_srgb"))]
Shader::from_wgsl(
"let ENABLE_GAMMA_CORRECTION: bool = false;\n".to_owned()
+ include_str!("render/pbr.wgsl"),
),
#[cfg(feature = "no_srgb")]
Shader::from_wgsl(
"let ENABLE_GAMMA_CORRECTION: bool = true;\n".to_owned()
+ include_str!("render/pbr.wgsl"),
),
);
shaders.set_untracked(
SHADOW_SHADER_HANDLE,
Expand Down
6 changes: 4 additions & 2 deletions crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,10 @@ fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
// tone_mapping
output_color = vec4<f32>(reinhard_luminance(output_color.rgb), output_color.a);
// Gamma correction.
// Not needed with sRGB buffer
// output_color.rgb = pow(output_color.rgb, vec3(1.0 / 2.2));
// Not needed with sRGB buffer, but needed if sRGB is disabled
if (ENABLE_GAMMA_CORRECTION) {
output_color = vec4<f32>(pow(output_color.rgb, vec3<f32>(1.0 / 2.2)), output_color.a);
}
}

return output_color;
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ trace = []
wgpu_trace = ["wgpu/trace"]
ci_limits = []
webgl = ["wgpu/webgl"]
no_srgb = []

[dependencies]
# bevy
Expand Down
13 changes: 13 additions & 0 deletions crates/bevy_render/src/texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub trait BevyDefault {
fn bevy_default() -> Self;
}

#[cfg(not(feature = "no_srgb"))]
impl BevyDefault for wgpu::TextureFormat {
fn bevy_default() -> Self {
if cfg!(target_os = "android") || cfg!(target_arch = "wasm32") {
Expand All @@ -69,3 +70,15 @@ impl BevyDefault for wgpu::TextureFormat {
}
}
}

#[cfg(feature = "no_srgb")]
impl BevyDefault for wgpu::TextureFormat {
fn bevy_default() -> Self {
if cfg!(target_os = "android") || cfg!(target_arch = "wasm32") {
// Bgra8UnormSrgb texture missing on some Android devices
wgpu::TextureFormat::Rgba8Unorm
} else {
wgpu::TextureFormat::Bgra8Unorm
}
}
}
3 changes: 3 additions & 0 deletions crates/bevy_sprite/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ rectangle-pack = "0.4"
serde = { version = "1", features = ["derive"] }
bitflags = "1.2"
copyless = "0.1.5"

[features]
no_srgb = []
11 changes: 10 additions & 1 deletion crates/bevy_sprite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,16 @@ pub enum SpriteSystem {
impl Plugin for SpritePlugin {
fn build(&self, app: &mut App) {
let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
let sprite_shader = Shader::from_wgsl(include_str!("render/sprite.wgsl"));
#[cfg(not(feature = "no_srgb"))]
let sprite_shader = Shader::from_wgsl(
"let ENABLE_GAMMA_CORRECTION: bool = false;\n".to_owned()
+ include_str!("render/sprite.wgsl"),
);
#[cfg(feature = "no_srgb")]
let sprite_shader = Shader::from_wgsl(
"let ENABLE_GAMMA_CORRECTION: bool = true;\n".to_owned()
+ include_str!("render/sprite.wgsl"),
);
shaders.set_untracked(SPRITE_SHADER_HANDLE, sprite_shader);
app.add_asset::<TextureAtlas>()
.register_type::<Sprite>()
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_sprite/src/render/sprite.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,8 @@ fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
#ifdef COLORED
color = in.color * color;
#endif
if (ENABLE_GAMMA_CORRECTION) {
color = vec4<f32>(pow(color.rgb, vec3<f32>(1.0 / 2.2)), color.a);
}
return color;
}
1 change: 1 addition & 0 deletions docs/cargo_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@
|serialize|Enables serialization of `bevy_input` types.|
|wayland|Enable this to use Wayland display server protocol other than X11.|
|subpixel_glyph_atlas|Enable this to cache glyphs using subpixel accuracy. This increases texture memory usage as each position requires a separate sprite in the glyph atlas, but provide more accurate character spacing.|
|no_srgb|Disable sRGB texture formats for devices that don't support it.|
|bevy_ci_testing|Used for running examples in CI.|