diff --git a/crates/bevy_pbr/src/interpolation.rs b/crates/bevy_pbr/src/interpolation.rs new file mode 100644 index 0000000000..21cb3d4342 --- /dev/null +++ b/crates/bevy_pbr/src/interpolation.rs @@ -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, +} diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 45aa6297d2..61b2c4cb5c 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -31,6 +31,7 @@ pub mod decal; pub mod deferred; mod extended_material; mod fog; +mod interpolation; mod light_probe; mod lightmap; mod material; @@ -60,6 +61,7 @@ pub use components::*; pub use decal::clustered::ClusteredDecalPlugin; pub use extended_material::*; pub use fog::*; +pub use interpolation::*; pub use light_probe::*; pub use lightmap::*; pub use material::*; diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index d7baef3a9a..37f91f089c 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -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. pub uv_transform: Affine2, + + pub interpolation_method: InterpolationMethod, } impl StandardMaterial { @@ -924,6 +926,7 @@ impl Default for StandardMaterial { opaque_render_method: OpaqueRendererMethod::Auto, deferred_lighting_pass_id: DEFAULT_PBR_DEFERRED_LIGHTING_PASS_ID, uv_transform: Affine2::IDENTITY, + interpolation_method: InterpolationMethod::Linear, } } } @@ -1228,6 +1231,7 @@ bitflags! { const CLEARCOAT_NORMAL_UV = 0x100000; const SPECULAR_UV = 0x200000; const SPECULAR_TINT_UV = 0x400000; + const FLAT_INTERPOLATION = 0x800000; 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( // 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) (material.depth_bias as i32 as u64) << STANDARD_MATERIAL_KEY_DEPTH_BIAS_SHIFT, )); + key } } @@ -1517,6 +1527,10 @@ impl Material for StandardMaterial { StandardMaterialKey::SPECULAR_TINT_UV, "STANDARD_MATERIAL_SPECULAR_TINT_UV_B", ), + ( + StandardMaterialKey::FLAT_INTERPOLATION, + "STANDARD_MATERIAL_FLAT_INTERPOLATION", + ), ] { if key.bind_group_data.intersects(flags) { shader_defs.push(shader_def.into()); diff --git a/crates/bevy_pbr/src/render/forward_io.wgsl b/crates/bevy_pbr/src/render/forward_io.wgsl index 99f2ecced7..044d5d8b7e 100644 --- a/crates/bevy_pbr/src/render/forward_io.wgsl +++ b/crates/bevy_pbr/src/render/forward_io.wgsl @@ -34,7 +34,11 @@ struct VertexOutput { // and `frag coord` when used as a fragment stage input @builtin(position) position: vec4, @location(0) world_position: vec4, +#ifdef STANDARD_MATERIAL_FLAT_INTERPOLATION + @location(1) @interpolate(flat) world_normal: vec3, +#else @location(1) world_normal: vec3, +#endif #ifdef VERTEX_UVS_A @location(2) uv: vec2, #endif @@ -45,8 +49,12 @@ struct VertexOutput { @location(4) world_tangent: vec4, #endif #ifdef VERTEX_COLORS +#ifdef STANDARD_MATERIAL_FLAT_INTERPOLATION + @location(5) @interpolate(flat) color: vec4, +#else @location(5) color: vec4, #endif +#endif #ifdef VERTEX_OUTPUT_INSTANCE_INDEX @location(6) @interpolate(flat) instance_index: u32, #endif diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000000..271800cb2f --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" \ No newline at end of file