Added feature switch to default Standard Material's new anisotropy texture 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>
This commit is contained in:
Gagnus 2024-07-02 19:02:05 +01:00 committed by GitHub
parent 7e0d262d77
commit a47b91cccc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 59 additions and 21 deletions

View file

@ -318,6 +318,9 @@ pbr_multi_layer_material_textures = [
"bevy_internal/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. # 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"] webgl2 = ["bevy_internal/webgl"]
@ -3239,7 +3242,7 @@ wasm = true
name = "anisotropy" name = "anisotropy"
path = "examples/3d/anisotropy.rs" path = "examples/3d/anisotropy.rs"
doc-scrape-examples = true doc-scrape-examples = true
required-features = ["jpeg"] required-features = ["jpeg", "pbr_anisotropy_texture"]
[package.metadata.example.anisotropy] [package.metadata.example.anisotropy]
name = "Anisotropy" name = "Anisotropy"

View file

@ -12,6 +12,7 @@ keywords = ["bevy"]
dds = ["bevy_render/dds"] dds = ["bevy_render/dds"]
pbr_transmission_textures = ["bevy_pbr/pbr_transmission_textures"] pbr_transmission_textures = ["bevy_pbr/pbr_transmission_textures"]
pbr_multi_layer_material_textures = [] pbr_multi_layer_material_textures = []
pbr_anisotropy_texture = []
[dependencies] [dependencies]
# bevy # bevy

View file

@ -1099,7 +1099,9 @@ fn load_material(
clearcoat_normal_texture: clearcoat.clearcoat_normal_texture, clearcoat_normal_texture: clearcoat.clearcoat_normal_texture,
anisotropy_strength: anisotropy.anisotropy_strength.unwrap_or_default() as f32, anisotropy_strength: anisotropy.anisotropy_strength.unwrap_or_default() as f32,
anisotropy_rotation: anisotropy.anisotropy_rotation.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, anisotropy_channel: anisotropy.anisotropy_channel,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture: anisotropy.anisotropy_texture, anisotropy_texture: anisotropy.anisotropy_texture,
..Default::default() ..Default::default()
} }
@ -1910,11 +1912,14 @@ impl ClearcoatExtension {
struct AnisotropyExtension { struct AnisotropyExtension {
anisotropy_strength: Option<f64>, anisotropy_strength: Option<f64>,
anisotropy_rotation: Option<f64>, anisotropy_rotation: Option<f64>,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_channel: UvChannel, anisotropy_channel: UvChannel,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture: Option<Handle<Image>>, anisotropy_texture: Option<Handle<Image>>,
} }
impl AnisotropyExtension { impl AnisotropyExtension {
#[allow(unused_variables)]
fn parse( fn parse(
load_context: &mut LoadContext, load_context: &mut LoadContext,
document: &Document, document: &Document,
@ -1925,6 +1930,7 @@ impl AnisotropyExtension {
.get("KHR_materials_anisotropy")? .get("KHR_materials_anisotropy")?
.as_object()?; .as_object()?;
#[cfg(feature = "pbr_anisotropy_texture")]
let (anisotropy_channel, anisotropy_texture) = extension let (anisotropy_channel, anisotropy_texture) = extension
.get("anisotropyTexture") .get("anisotropyTexture")
.and_then(|value| value::from_value::<json::texture::Info>(value.clone()).ok()) .and_then(|value| value::from_value::<json::texture::Info>(value.clone()).ok())
@ -1939,7 +1945,9 @@ impl AnisotropyExtension {
Some(AnisotropyExtension { Some(AnisotropyExtension {
anisotropy_strength: extension.get("anisotropyStrength").and_then(Value::as_f64), anisotropy_strength: extension.get("anisotropyStrength").and_then(Value::as_f64),
anisotropy_rotation: extension.get("anisotropyRotation").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(), anisotropy_channel: anisotropy_channel.unwrap_or_default(),
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture, anisotropy_texture,
}) })
} }

View file

@ -111,6 +111,12 @@ pbr_multi_layer_material_textures = [
"bevy_gltf?/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 # Optimise for WebGL2
webgl = [ webgl = [
"bevy_core_pipeline?/webgl", "bevy_core_pipeline?/webgl",

View file

@ -13,6 +13,7 @@ webgl = []
webgpu = [] webgpu = []
pbr_transmission_textures = [] pbr_transmission_textures = []
pbr_multi_layer_material_textures = [] pbr_multi_layer_material_textures = []
pbr_anisotropy_texture = []
shader_format_glsl = ["bevy_render/shader_format_glsl"] shader_format_glsl = ["bevy_render/shader_format_glsl"]
trace = ["bevy_render/trace"] trace = ["bevy_render/trace"]
ios_simulator = ["bevy_render/ios_simulator"] ios_simulator = ["bevy_render/ios_simulator"]

View file

@ -215,8 +215,8 @@ pub struct StandardMaterial {
/// ///
/// **Important:** The [`StandardMaterial::diffuse_transmission`] property must be set to a value higher than 0.0, /// **Important:** The [`StandardMaterial::diffuse_transmission`] property must be set to a value higher than 0.0,
/// or this texture won't have any effect. /// or this texture won't have any effect.
#[texture(19)] #[cfg_attr(feature = "pbr_transmission_textures", texture(19))]
#[sampler(20)] #[cfg_attr(feature = "pbr_transmission_textures", sampler(20))]
#[cfg(feature = "pbr_transmission_textures")] #[cfg(feature = "pbr_transmission_textures")]
pub diffuse_transmission_texture: Option<Handle<Image>>, pub diffuse_transmission_texture: Option<Handle<Image>>,
@ -256,8 +256,8 @@ pub struct StandardMaterial {
/// ///
/// **Important:** The [`StandardMaterial::specular_transmission`] property must be set to a value higher than 0.0, /// **Important:** The [`StandardMaterial::specular_transmission`] property must be set to a value higher than 0.0,
/// or this texture won't have any effect. /// or this texture won't have any effect.
#[texture(15)] #[cfg_attr(feature = "pbr_transmission_textures", texture(15))]
#[sampler(16)] #[cfg_attr(feature = "pbr_transmission_textures", sampler(16))]
#[cfg(feature = "pbr_transmission_textures")] #[cfg(feature = "pbr_transmission_textures")]
pub specular_transmission_texture: Option<Handle<Image>>, pub specular_transmission_texture: Option<Handle<Image>>,
@ -285,8 +285,8 @@ pub struct StandardMaterial {
/// ///
/// **Important:** The [`StandardMaterial::thickness`] property must be set to a value higher than 0.0, /// **Important:** The [`StandardMaterial::thickness`] property must be set to a value higher than 0.0,
/// or this texture won't have any effect. /// or this texture won't have any effect.
#[texture(17)] #[cfg_attr(feature = "pbr_transmission_textures", texture(17))]
#[sampler(18)] #[cfg_attr(feature = "pbr_transmission_textures", sampler(18))]
#[cfg(feature = "pbr_transmission_textures")] #[cfg(feature = "pbr_transmission_textures")]
pub thickness_texture: Option<Handle<Image>>, pub thickness_texture: Option<Handle<Image>>,
@ -420,8 +420,8 @@ pub struct StandardMaterial {
/// main [`StandardMaterial::clearcoat`] factor. /// main [`StandardMaterial::clearcoat`] factor.
/// ///
/// As this is a non-color map, it must not be loaded as sRGB. /// As this is a non-color map, it must not be loaded as sRGB.
#[texture(21)] #[cfg_attr(feature = "pbr_multi_layer_material_textures", texture(21))]
#[sampler(22)] #[cfg_attr(feature = "pbr_multi_layer_material_textures", sampler(22))]
#[cfg(feature = "pbr_multi_layer_material_textures")] #[cfg(feature = "pbr_multi_layer_material_textures")]
pub clearcoat_texture: Option<Handle<Image>>, pub clearcoat_texture: Option<Handle<Image>>,
@ -445,8 +445,8 @@ pub struct StandardMaterial {
/// [`StandardMaterial::clearcoat_perceptual_roughness`] factor. /// [`StandardMaterial::clearcoat_perceptual_roughness`] factor.
/// ///
/// As this is a non-color map, it must not be loaded as sRGB. /// As this is a non-color map, it must not be loaded as sRGB.
#[texture(23)] #[cfg_attr(feature = "pbr_multi_layer_material_textures", texture(23))]
#[sampler(24)] #[cfg_attr(feature = "pbr_multi_layer_material_textures", sampler(24))]
#[cfg(feature = "pbr_multi_layer_material_textures")] #[cfg(feature = "pbr_multi_layer_material_textures")]
pub clearcoat_roughness_texture: Option<Handle<Image>>, pub clearcoat_roughness_texture: Option<Handle<Image>>,
@ -467,8 +467,8 @@ pub struct StandardMaterial {
/// in both [`StandardMaterial::normal_map_texture`] and this field. /// in both [`StandardMaterial::normal_map_texture`] and this field.
/// ///
/// As this is a non-color map, it must not be loaded as sRGB. /// As this is a non-color map, it must not be loaded as sRGB.
#[texture(25)] #[cfg_attr(feature = "pbr_multi_layer_material_textures", texture(25))]
#[sampler(26)] #[cfg_attr(feature = "pbr_multi_layer_material_textures", sampler(26))]
#[cfg(feature = "pbr_multi_layer_material_textures")] #[cfg(feature = "pbr_multi_layer_material_textures")]
pub clearcoat_normal_texture: Option<Handle<Image>>, pub clearcoat_normal_texture: Option<Handle<Image>>,
@ -513,6 +513,7 @@ pub struct StandardMaterial {
/// The UV channel to use for the [`StandardMaterial::anisotropy_texture`]. /// The UV channel to use for the [`StandardMaterial::anisotropy_texture`].
/// ///
/// Defaults to [`UvChannel::Uv0`]. /// Defaults to [`UvChannel::Uv0`].
#[cfg(feature = "pbr_anisotropy_texture")]
pub anisotropy_channel: UvChannel, pub anisotropy_channel: UvChannel,
/// An image texture that allows the /// An image texture that allows the
@ -536,8 +537,9 @@ pub struct StandardMaterial {
/// ///
/// [`KHR_materials_anisotropy` specification]: /// [`KHR_materials_anisotropy` specification]:
/// https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md /// https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md
#[texture(13)] #[cfg_attr(feature = "pbr_anisotropy_texture", texture(13))]
#[sampler(14)] #[cfg_attr(feature = "pbr_anisotropy_texture", sampler(14))]
#[cfg(feature = "pbr_anisotropy_texture")]
pub anisotropy_texture: Option<Handle<Image>>, pub anisotropy_texture: Option<Handle<Image>>,
/// Support two-sided lighting by automatically flipping the normals for "back" faces /// Support two-sided lighting by automatically flipping the normals for "back" faces
@ -814,7 +816,9 @@ impl Default for StandardMaterial {
clearcoat_normal_texture: None, clearcoat_normal_texture: None,
anisotropy_strength: 0.0, anisotropy_strength: 0.0,
anisotropy_rotation: 0.0, anisotropy_rotation: 0.0,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_channel: UvChannel::Uv0, anisotropy_channel: UvChannel::Uv0,
#[cfg(feature = "pbr_anisotropy_texture")]
anisotropy_texture: None, anisotropy_texture: None,
flip_normal_map_y: false, flip_normal_map_y: false,
double_sided: false, double_sided: false,
@ -999,8 +1003,11 @@ impl AsBindGroupShaderType<StandardMaterialUniform> for StandardMaterial {
} }
} }
if self.anisotropy_texture.is_some() { #[cfg(feature = "pbr_anisotropy_texture")]
flags |= StandardMaterialFlags::ANISOTROPY_TEXTURE; {
if self.anisotropy_texture.is_some() {
flags |= StandardMaterialFlags::ANISOTROPY_TEXTURE;
}
} }
#[cfg(feature = "pbr_multi_layer_material_textures")] #[cfg(feature = "pbr_multi_layer_material_textures")]
@ -1207,10 +1214,14 @@ impl From<&StandardMaterial> for StandardMaterialKey {
StandardMaterialKey::NORMAL_MAP_UV, StandardMaterialKey::NORMAL_MAP_UV,
material.normal_map_channel != UvChannel::Uv0, material.normal_map_channel != UvChannel::Uv0,
); );
key.set(
StandardMaterialKey::ANISOTROPY_UV, #[cfg(feature = "pbr_anisotropy_texture")]
material.anisotropy_channel != UvChannel::Uv0, {
); key.set(
StandardMaterialKey::ANISOTROPY_UV,
material.anisotropy_channel != UvChannel::Uv0,
);
}
#[cfg(feature = "pbr_multi_layer_material_textures")] #[cfg(feature = "pbr_multi_layer_material_textures")]
{ {

View file

@ -1642,6 +1642,9 @@ impl SpecializedMeshPipeline for MeshPipeline {
if cfg!(feature = "pbr_multi_layer_material_textures") { if cfg!(feature = "pbr_multi_layer_material_textures") {
shader_defs.push("PBR_MULTI_LAYER_MATERIAL_TEXTURES_SUPPORTED".into()); 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()]; let mut bind_group_layout = vec![self.get_view_layout(key.into()).clone()];

View file

@ -15,8 +15,10 @@
@group(2) @binding(10) var normal_map_sampler: sampler; @group(2) @binding(10) var normal_map_sampler: sampler;
@group(2) @binding(11) var depth_map_texture: texture_2d<f32>; @group(2) @binding(11) var depth_map_texture: texture_2d<f32>;
@group(2) @binding(12) var depth_map_sampler: sampler; @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(13) var anisotropy_texture: texture_2d<f32>;
@group(2) @binding(14) var anisotropy_sampler: sampler; @group(2) @binding(14) var anisotropy_sampler: sampler;
#endif
#ifdef PBR_TRANSMISSION_TEXTURES_SUPPORTED #ifdef PBR_TRANSMISSION_TEXTURES_SUPPORTED
@group(2) @binding(15) var specular_transmission_texture: texture_2d<f32>; @group(2) @binding(15) var specular_transmission_texture: texture_2d<f32>;
@group(2) @binding(16) var specular_transmission_sampler: sampler; @group(2) @binding(16) var specular_transmission_sampler: sampler;

View file

@ -420,6 +420,7 @@ fn pbr_input_from_standard_material(
// //
// This code comes from the `KHR_materials_anisotropy` spec: // 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> // <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 VERTEX_TANGENTS
#ifdef STANDARD_MATERIAL_ANISOTROPY #ifdef STANDARD_MATERIAL_ANISOTROPY
@ -456,6 +457,7 @@ fn pbr_input_from_standard_material(
#endif // STANDARD_MATERIAL_ANISOTROPY #endif // STANDARD_MATERIAL_ANISOTROPY
#endif // VERTEX_TANGENTS #endif // VERTEX_TANGENTS
#endif // PBR_ANISOTROPY_TEXTURE_SUPPORTED
#endif // LOAD_PREPASS_NORMALS #endif // LOAD_PREPASS_NORMALS

View file

@ -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| |meshlet_processor|Enables processing meshes into meshlet meshes for bevy_pbr|
|minimp3|MP3 audio format support (through minimp3)| |minimp3|MP3 audio format support (through minimp3)|
|mp3|MP3 audio format support| |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_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| |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| |pnm|PNM image format support, includes pam, pbm, pgm and ppm|