add flat color and normal interpolation to standard material
Some checks are pending
Deploy Docs / build-and-deploy (push) Waiting to run
Example Run / run-examples-macos-metal (push) Waiting to run
Example Run / Compare Macos screenshots (push) Blocked by required conditions
Example Run / run-examples-linux-vulkan (push) Waiting to run
Example Run / Compare Linux screenshots (push) Blocked by required conditions
Example Run / run-examples-on-windows-dx12 (push) Waiting to run
Example Run / Compare Windows screenshots (push) Blocked by required conditions

This commit is contained in:
Arkitu 2025-07-18 20:03:26 +02:00
parent 877d278785
commit 08459422f9
5 changed files with 35 additions and 0 deletions

View File

@ -0,0 +1,9 @@
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Reflect)]
#[reflect(Default, Clone, PartialEq)]
pub enum InterpolationMethod {
#[default]
Linear,
Flat,
}

View File

@ -31,6 +31,7 @@ pub mod decal;
pub mod deferred; pub mod deferred;
mod extended_material; mod extended_material;
mod fog; mod fog;
mod interpolation;
mod light_probe; mod light_probe;
mod lightmap; mod lightmap;
mod material; mod material;
@ -60,6 +61,7 @@ pub use components::*;
pub use decal::clustered::ClusteredDecalPlugin; pub use decal::clustered::ClusteredDecalPlugin;
pub use extended_material::*; pub use extended_material::*;
pub use fog::*; pub use fog::*;
pub use interpolation::*;
pub use light_probe::*; pub use light_probe::*;
pub use lightmap::*; pub use lightmap::*;
pub use material::*; pub use material::*;

View File

@ -769,6 +769,8 @@ pub struct StandardMaterial {
/// The transform applied to the UVs corresponding to `ATTRIBUTE_UV_0` on the mesh before sampling. Default is identity. /// The transform applied to the UVs corresponding to `ATTRIBUTE_UV_0` on the mesh before sampling. Default is identity.
pub uv_transform: Affine2, pub uv_transform: Affine2,
pub interpolation_method: InterpolationMethod,
} }
impl StandardMaterial { impl StandardMaterial {
@ -924,6 +926,7 @@ impl Default for StandardMaterial {
opaque_render_method: OpaqueRendererMethod::Auto, opaque_render_method: OpaqueRendererMethod::Auto,
deferred_lighting_pass_id: DEFAULT_PBR_DEFERRED_LIGHTING_PASS_ID, deferred_lighting_pass_id: DEFAULT_PBR_DEFERRED_LIGHTING_PASS_ID,
uv_transform: Affine2::IDENTITY, uv_transform: Affine2::IDENTITY,
interpolation_method: InterpolationMethod::Linear,
} }
} }
} }
@ -1228,6 +1231,7 @@ bitflags! {
const CLEARCOAT_NORMAL_UV = 0x100000; const CLEARCOAT_NORMAL_UV = 0x100000;
const SPECULAR_UV = 0x200000; const SPECULAR_UV = 0x200000;
const SPECULAR_TINT_UV = 0x400000; const SPECULAR_TINT_UV = 0x400000;
const FLAT_INTERPOLATION = 0x800000;
const DEPTH_BIAS = 0xffffffff_00000000; const DEPTH_BIAS = 0xffffffff_00000000;
} }
} }
@ -1352,11 +1356,17 @@ impl From<&StandardMaterial> for StandardMaterialKey {
); );
} }
key.set(
StandardMaterialKey::FLAT_INTERPOLATION,
material.interpolation_method == InterpolationMethod::Flat,
);
key.insert(StandardMaterialKey::from_bits_retain( key.insert(StandardMaterialKey::from_bits_retain(
// Casting to i32 first to ensure the full i32 range is preserved. // Casting to i32 first to ensure the full i32 range is preserved.
// (wgpu expects the depth_bias as an i32 when this is extracted in a later step) // (wgpu expects the depth_bias as an i32 when this is extracted in a later step)
(material.depth_bias as i32 as u64) << STANDARD_MATERIAL_KEY_DEPTH_BIAS_SHIFT, (material.depth_bias as i32 as u64) << STANDARD_MATERIAL_KEY_DEPTH_BIAS_SHIFT,
)); ));
key key
} }
} }
@ -1517,6 +1527,10 @@ impl Material for StandardMaterial {
StandardMaterialKey::SPECULAR_TINT_UV, StandardMaterialKey::SPECULAR_TINT_UV,
"STANDARD_MATERIAL_SPECULAR_TINT_UV_B", "STANDARD_MATERIAL_SPECULAR_TINT_UV_B",
), ),
(
StandardMaterialKey::FLAT_INTERPOLATION,
"STANDARD_MATERIAL_FLAT_INTERPOLATION",
),
] { ] {
if key.bind_group_data.intersects(flags) { if key.bind_group_data.intersects(flags) {
shader_defs.push(shader_def.into()); shader_defs.push(shader_def.into());

View File

@ -34,7 +34,11 @@ struct VertexOutput {
// and `frag coord` when used as a fragment stage input // and `frag coord` when used as a fragment stage input
@builtin(position) position: vec4<f32>, @builtin(position) position: vec4<f32>,
@location(0) world_position: vec4<f32>, @location(0) world_position: vec4<f32>,
#ifdef STANDARD_MATERIAL_FLAT_INTERPOLATION
@location(1) @interpolate(flat) world_normal: vec3<f32>,
#else
@location(1) world_normal: vec3<f32>, @location(1) world_normal: vec3<f32>,
#endif
#ifdef VERTEX_UVS_A #ifdef VERTEX_UVS_A
@location(2) uv: vec2<f32>, @location(2) uv: vec2<f32>,
#endif #endif
@ -45,8 +49,12 @@ struct VertexOutput {
@location(4) world_tangent: vec4<f32>, @location(4) world_tangent: vec4<f32>,
#endif #endif
#ifdef VERTEX_COLORS #ifdef VERTEX_COLORS
#ifdef STANDARD_MATERIAL_FLAT_INTERPOLATION
@location(5) @interpolate(flat) color: vec4<f32>,
#else
@location(5) color: vec4<f32>, @location(5) color: vec4<f32>,
#endif #endif
#endif
#ifdef VERTEX_OUTPUT_INSTANCE_INDEX #ifdef VERTEX_OUTPUT_INSTANCE_INDEX
@location(6) @interpolate(flat) instance_index: u32, @location(6) @interpolate(flat) instance_index: u32,
#endif #endif

2
rust-toolchain.toml Normal file
View File

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"