Skip to content

Commit

Permalink
Added feature switch to default Standard Material's new anisotropy te…
Browse files Browse the repository at this point in the history
…xture to off (#14048)

# Objective

- Standard Material is starting to run out of samplers (currently uses
13 with no additional features off, I think in 0.13 it was 12).
- This change adds a new feature switch, modelled on the other ones
which add features to Standard Material, to turn off the new anisotropy
feature by default.

## Solution

- feature + texture define

## Testing

- Anisotropy example still works fine
- Other samples work fine
- Standard Material now takes 12 samplers by default on my Mac instead
of 13

## Migration Guide

- Add feature pbr_anisotropy_texture if you are using that texture in
any standard materials.

---------

Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
  • Loading branch information
gagnus and gagnus authored Jul 2, 2024
1 parent 7e0d262 commit a47b91c
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 21 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ pbr_multi_layer_material_textures = [
"bevy_internal/pbr_multi_layer_material_textures",
]

# Enable support for anisotropy texture in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs
pbr_anisotropy_texture = ["bevy_internal/pbr_anisotropy_texture"]

# 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.
webgl2 = ["bevy_internal/webgl"]

Expand Down Expand Up @@ -3239,7 +3242,7 @@ wasm = true
name = "anisotropy"
path = "examples/3d/anisotropy.rs"
doc-scrape-examples = true
required-features = ["jpeg"]
required-features = ["jpeg", "pbr_anisotropy_texture"]

[package.metadata.example.anisotropy]
name = "Anisotropy"
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_gltf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ keywords = ["bevy"]
dds = ["bevy_render/dds"]
pbr_transmission_textures = ["bevy_pbr/pbr_transmission_textures"]
pbr_multi_layer_material_textures = []
pbr_anisotropy_texture = []

[dependencies]
# bevy
Expand Down
8 changes: 8 additions & 0 deletions crates/bevy_gltf/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,9 @@ fn load_material(
clearcoat_normal_texture: clearcoat.clearcoat_normal_texture,
anisotropy_strength: anisotropy.anisotropy_strength.unwrap_or_default() as f32,
anisotropy_rotation: anisotropy.anisotropy_rotation.unwrap_or_default() as f32,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_channel: anisotropy.anisotropy_channel,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture: anisotropy.anisotropy_texture,
..Default::default()
}
Expand Down Expand Up @@ -1910,11 +1912,14 @@ impl ClearcoatExtension {
struct AnisotropyExtension {
anisotropy_strength: Option<f64>,
anisotropy_rotation: Option<f64>,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_channel: UvChannel,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture: Option<Handle<Image>>,
}

impl AnisotropyExtension {
#[allow(unused_variables)]
fn parse(
load_context: &mut LoadContext,
document: &Document,
Expand All @@ -1925,6 +1930,7 @@ impl AnisotropyExtension {
.get("KHR_materials_anisotropy")?
.as_object()?;

#[cfg(feature = "pbr_anisotropy_texture")]
let (anisotropy_channel, anisotropy_texture) = extension
.get("anisotropyTexture")
.and_then(|value| value::from_value::<json::texture::Info>(value.clone()).ok())
Expand All @@ -1939,7 +1945,9 @@ impl AnisotropyExtension {
Some(AnisotropyExtension {
anisotropy_strength: extension.get("anisotropyStrength").and_then(Value::as_f64),
anisotropy_rotation: extension.get("anisotropyRotation").and_then(Value::as_f64),
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_channel: anisotropy_channel.unwrap_or_default(),
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture,
})
}
Expand Down
6 changes: 6 additions & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ pbr_multi_layer_material_textures = [
"bevy_gltf?/pbr_multi_layer_material_textures",
]

# Anisotropy texture in `StandardMaterial`:
pbr_anisotropy_texture = [
"bevy_pbr?/pbr_anisotropy_texture",
"bevy_gltf?/pbr_anisotropy_texture",
]

# Optimise for WebGL2
webgl = [
"bevy_core_pipeline?/webgl",
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 @@ -13,6 +13,7 @@ webgl = []
webgpu = []
pbr_transmission_textures = []
pbr_multi_layer_material_textures = []
pbr_anisotropy_texture = []
shader_format_glsl = ["bevy_render/shader_format_glsl"]
trace = ["bevy_render/trace"]
ios_simulator = ["bevy_render/ios_simulator"]
Expand Down
51 changes: 31 additions & 20 deletions crates/bevy_pbr/src/pbr_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ pub struct StandardMaterial {
///
/// **Important:** The [`StandardMaterial::diffuse_transmission`] property must be set to a value higher than 0.0,
/// or this texture won't have any effect.
#[texture(19)]
#[sampler(20)]
#[cfg_attr(feature = "pbr_transmission_textures", texture(19))]
#[cfg_attr(feature = "pbr_transmission_textures", sampler(20))]
#[cfg(feature = "pbr_transmission_textures")]
pub diffuse_transmission_texture: Option<Handle<Image>>,

Expand Down Expand Up @@ -256,8 +256,8 @@ pub struct StandardMaterial {
///
/// **Important:** The [`StandardMaterial::specular_transmission`] property must be set to a value higher than 0.0,
/// or this texture won't have any effect.
#[texture(15)]
#[sampler(16)]
#[cfg_attr(feature = "pbr_transmission_textures", texture(15))]
#[cfg_attr(feature = "pbr_transmission_textures", sampler(16))]
#[cfg(feature = "pbr_transmission_textures")]
pub specular_transmission_texture: Option<Handle<Image>>,

Expand Down Expand Up @@ -285,8 +285,8 @@ pub struct StandardMaterial {
///
/// **Important:** The [`StandardMaterial::thickness`] property must be set to a value higher than 0.0,
/// or this texture won't have any effect.
#[texture(17)]
#[sampler(18)]
#[cfg_attr(feature = "pbr_transmission_textures", texture(17))]
#[cfg_attr(feature = "pbr_transmission_textures", sampler(18))]
#[cfg(feature = "pbr_transmission_textures")]
pub thickness_texture: Option<Handle<Image>>,

Expand Down Expand Up @@ -420,8 +420,8 @@ pub struct StandardMaterial {
/// main [`StandardMaterial::clearcoat`] factor.
///
/// As this is a non-color map, it must not be loaded as sRGB.
#[texture(21)]
#[sampler(22)]
#[cfg_attr(feature = "pbr_multi_layer_material_textures", texture(21))]
#[cfg_attr(feature = "pbr_multi_layer_material_textures", sampler(22))]
#[cfg(feature = "pbr_multi_layer_material_textures")]
pub clearcoat_texture: Option<Handle<Image>>,

Expand All @@ -445,8 +445,8 @@ pub struct StandardMaterial {
/// [`StandardMaterial::clearcoat_perceptual_roughness`] factor.
///
/// As this is a non-color map, it must not be loaded as sRGB.
#[texture(23)]
#[sampler(24)]
#[cfg_attr(feature = "pbr_multi_layer_material_textures", texture(23))]
#[cfg_attr(feature = "pbr_multi_layer_material_textures", sampler(24))]
#[cfg(feature = "pbr_multi_layer_material_textures")]
pub clearcoat_roughness_texture: Option<Handle<Image>>,

Expand All @@ -467,8 +467,8 @@ pub struct StandardMaterial {
/// in both [`StandardMaterial::normal_map_texture`] and this field.
///
/// As this is a non-color map, it must not be loaded as sRGB.
#[texture(25)]
#[sampler(26)]
#[cfg_attr(feature = "pbr_multi_layer_material_textures", texture(25))]
#[cfg_attr(feature = "pbr_multi_layer_material_textures", sampler(26))]
#[cfg(feature = "pbr_multi_layer_material_textures")]
pub clearcoat_normal_texture: Option<Handle<Image>>,

Expand Down Expand Up @@ -513,6 +513,7 @@ pub struct StandardMaterial {
/// The UV channel to use for the [`StandardMaterial::anisotropy_texture`].
///
/// Defaults to [`UvChannel::Uv0`].
#[cfg(feature = "pbr_anisotropy_texture")]
pub anisotropy_channel: UvChannel,

/// An image texture that allows the
Expand All @@ -536,8 +537,9 @@ pub struct StandardMaterial {
///
/// [`KHR_materials_anisotropy` specification]:
/// https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md
#[texture(13)]
#[sampler(14)]
#[cfg_attr(feature = "pbr_anisotropy_texture", texture(13))]
#[cfg_attr(feature = "pbr_anisotropy_texture", sampler(14))]
#[cfg(feature = "pbr_anisotropy_texture")]
pub anisotropy_texture: Option<Handle<Image>>,

/// Support two-sided lighting by automatically flipping the normals for "back" faces
Expand Down Expand Up @@ -814,7 +816,9 @@ impl Default for StandardMaterial {
clearcoat_normal_texture: None,
anisotropy_strength: 0.0,
anisotropy_rotation: 0.0,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_channel: UvChannel::Uv0,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture: None,
flip_normal_map_y: false,
double_sided: false,
Expand Down Expand Up @@ -999,8 +1003,11 @@ impl AsBindGroupShaderType<StandardMaterialUniform> for StandardMaterial {
}
}

if self.anisotropy_texture.is_some() {
flags |= StandardMaterialFlags::ANISOTROPY_TEXTURE;
#[cfg(feature = "pbr_anisotropy_texture")]
{
if self.anisotropy_texture.is_some() {
flags |= StandardMaterialFlags::ANISOTROPY_TEXTURE;
}
}

#[cfg(feature = "pbr_multi_layer_material_textures")]
Expand Down Expand Up @@ -1207,10 +1214,14 @@ impl From<&StandardMaterial> for StandardMaterialKey {
StandardMaterialKey::NORMAL_MAP_UV,
material.normal_map_channel != UvChannel::Uv0,
);
key.set(
StandardMaterialKey::ANISOTROPY_UV,
material.anisotropy_channel != UvChannel::Uv0,
);

#[cfg(feature = "pbr_anisotropy_texture")]
{
key.set(
StandardMaterialKey::ANISOTROPY_UV,
material.anisotropy_channel != UvChannel::Uv0,
);
}

#[cfg(feature = "pbr_multi_layer_material_textures")]
{
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1642,6 +1642,9 @@ impl SpecializedMeshPipeline for MeshPipeline {
if cfg!(feature = "pbr_multi_layer_material_textures") {
shader_defs.push("PBR_MULTI_LAYER_MATERIAL_TEXTURES_SUPPORTED".into());
}
if cfg!(feature = "pbr_anisotropy_texture") {
shader_defs.push("PBR_ANISOTROPY_TEXTURE_SUPPORTED".into());
}

let mut bind_group_layout = vec![self.get_view_layout(key.into()).clone()];

Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_pbr/src/render/pbr_bindings.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
@group(2) @binding(10) var normal_map_sampler: sampler;
@group(2) @binding(11) var depth_map_texture: texture_2d<f32>;
@group(2) @binding(12) var depth_map_sampler: sampler;
#ifdef PBR_ANISOTROPY_TEXTURE_SUPPORTED
@group(2) @binding(13) var anisotropy_texture: texture_2d<f32>;
@group(2) @binding(14) var anisotropy_sampler: sampler;
#endif
#ifdef PBR_TRANSMISSION_TEXTURES_SUPPORTED
@group(2) @binding(15) var specular_transmission_texture: texture_2d<f32>;
@group(2) @binding(16) var specular_transmission_sampler: sampler;
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_pbr/src/render/pbr_fragment.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ fn pbr_input_from_standard_material(
//
// This code comes from the `KHR_materials_anisotropy` spec:
// <https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md#individual-lights>
#ifdef PBR_ANISOTROPY_TEXTURE_SUPPORTED
#ifdef VERTEX_TANGENTS
#ifdef STANDARD_MATERIAL_ANISOTROPY

Expand Down Expand Up @@ -456,6 +457,7 @@ fn pbr_input_from_standard_material(

#endif // STANDARD_MATERIAL_ANISOTROPY
#endif // VERTEX_TANGENTS
#endif // PBR_ANISOTROPY_TEXTURE_SUPPORTED

#endif // LOAD_PREPASS_NORMALS

Expand Down
1 change: 1 addition & 0 deletions docs/cargo_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ The default feature set enables most of the expected features of a game engine,
|meshlet_processor|Enables processing meshes into meshlet meshes for bevy_pbr|
|minimp3|MP3 audio format support (through minimp3)|
|mp3|MP3 audio format support|
|pbr_anisotropy_texture|Enable support for anisotropy texture in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
|pbr_multi_layer_material_textures|Enable support for multi-layer material textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
|pbr_transmission_textures|Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
|pnm|PNM image format support, includes pam, pbm, pgm and ppm|
Expand Down

0 comments on commit a47b91c

Please sign in to comment.