bevy/examples/2d/custom_gltf_vertex_attribute.rs

84 lines
3 KiB
Rust
Raw Normal View History

//! Renders a glTF mesh in 2D with a custom vertex attribute.
use bevy::gltf::GltfPlugin;
use bevy::prelude::*;
reflect: stable type path v2 (#7184) # Objective - Introduce a stable alternative to [`std::any::type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html). - Rewrite of #5805 with heavy inspiration in design. - On the path to #5830. - Part of solving #3327. ## Solution - Add a `TypePath` trait for static stable type path/name information. - Add a `TypePath` derive macro. - Add a `impl_type_path` macro for implementing internal and foreign types in `bevy_reflect`. --- ## Changelog - Added `TypePath` trait. - Added `DynamicTypePath` trait and `get_type_path` method to `Reflect`. - Added a `TypePath` derive macro. - Added a `bevy_reflect::impl_type_path` for implementing `TypePath` on internal and foreign types in `bevy_reflect`. - Changed `bevy_reflect::utility::(Non)GenericTypeInfoCell` to `(Non)GenericTypedCell<T>` which allows us to be generic over both `TypeInfo` and `TypePath`. - `TypePath` is now a supertrait of `Asset`, `Material` and `Material2d`. - `impl_reflect_struct` needs a `#[type_path = "..."]` attribute to be specified. - `impl_reflect_value` needs to either specify path starting with a double colon (`::core::option::Option`) or an `in my_crate::foo` declaration. - Added `bevy_reflect_derive::ReflectTypePath`. - Most uses of `Ident` in `bevy_reflect_derive` changed to use `ReflectTypePath`. ## Migration Guide - Implementors of `Asset`, `Material` and `Material2d` now also need to derive `TypePath`. - Manual implementors of `Reflect` will need to implement the new `get_type_path` method. ## Open Questions - [x] ~This PR currently does not migrate any usages of `std::any::type_name` to use `bevy_reflect::TypePath` to ease the review process. Should it?~ Migration will be left to a follow-up PR. - [ ] This PR adds a lot of `#[derive(TypePath)]` and `T: TypePath` to satisfy new bounds, mostly when deriving `TypeUuid`. Should we make `TypePath` a supertrait of `TypeUuid`? [Should we remove `TypeUuid` in favour of `TypePath`?](https://github.com/bevyengine/bevy/pull/5805/files/2afbd855327c4b68e0a6b6f03118f289988441a4#r961067892)
2023-06-05 20:31:20 +00:00
use bevy::reflect::{TypePath, TypeUuid};
use bevy::render::mesh::{MeshVertexAttribute, MeshVertexBufferLayout};
use bevy::render::render_resource::*;
use bevy::sprite::{
Material2d, Material2dKey, Material2dPlugin, MaterialMesh2dBundle, Mesh2dHandle,
};
/// This vertex attribute supplies barycentric coordinates for each triangle.
/// Each component of the vector corresponds to one corner of a triangle. It's
/// equal to 1.0 in that corner and 0.0 in the other two. Hence, its value in
/// the fragment shader indicates proximity to a corner or the opposite edge.
const ATTRIBUTE_BARYCENTRIC: MeshVertexAttribute =
MeshVertexAttribute::new("Barycentric", 2137464976, VertexFormat::Float32x3);
fn main() {
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0 / 5.0f32,
})
.add_plugins((
DefaultPlugins.set(
GltfPlugin::default()
// Map a custom glTF attribute name to a `MeshVertexAttribute`.
.add_custom_vertex_attribute("_BARYCENTRIC", ATTRIBUTE_BARYCENTRIC),
),
Material2dPlugin::<CustomMaterial>::default(),
))
.add_systems(Startup, setup)
.run();
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<CustomMaterial>>,
) {
// Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
let mesh = asset_server.load("models/barycentric/barycentric.gltf#Mesh0/Primitive0");
commands.spawn(MaterialMesh2dBundle {
mesh: Mesh2dHandle(mesh),
material: materials.add(CustomMaterial {}),
transform: Transform::from_scale(150.0 * Vec3::ONE),
..default()
});
// Add a camera
commands.spawn(Camera2dBundle { ..default() });
}
/// This custom material uses barycentric coordinates from
/// `ATTRIBUTE_BARYCENTRIC` to shade a white border around each triangle. The
/// thickness of the border is animated using the global time shader uniform.
reflect: stable type path v2 (#7184) # Objective - Introduce a stable alternative to [`std::any::type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html). - Rewrite of #5805 with heavy inspiration in design. - On the path to #5830. - Part of solving #3327. ## Solution - Add a `TypePath` trait for static stable type path/name information. - Add a `TypePath` derive macro. - Add a `impl_type_path` macro for implementing internal and foreign types in `bevy_reflect`. --- ## Changelog - Added `TypePath` trait. - Added `DynamicTypePath` trait and `get_type_path` method to `Reflect`. - Added a `TypePath` derive macro. - Added a `bevy_reflect::impl_type_path` for implementing `TypePath` on internal and foreign types in `bevy_reflect`. - Changed `bevy_reflect::utility::(Non)GenericTypeInfoCell` to `(Non)GenericTypedCell<T>` which allows us to be generic over both `TypeInfo` and `TypePath`. - `TypePath` is now a supertrait of `Asset`, `Material` and `Material2d`. - `impl_reflect_struct` needs a `#[type_path = "..."]` attribute to be specified. - `impl_reflect_value` needs to either specify path starting with a double colon (`::core::option::Option`) or an `in my_crate::foo` declaration. - Added `bevy_reflect_derive::ReflectTypePath`. - Most uses of `Ident` in `bevy_reflect_derive` changed to use `ReflectTypePath`. ## Migration Guide - Implementors of `Asset`, `Material` and `Material2d` now also need to derive `TypePath`. - Manual implementors of `Reflect` will need to implement the new `get_type_path` method. ## Open Questions - [x] ~This PR currently does not migrate any usages of `std::any::type_name` to use `bevy_reflect::TypePath` to ease the review process. Should it?~ Migration will be left to a follow-up PR. - [ ] This PR adds a lot of `#[derive(TypePath)]` and `T: TypePath` to satisfy new bounds, mostly when deriving `TypeUuid`. Should we make `TypePath` a supertrait of `TypeUuid`? [Should we remove `TypeUuid` in favour of `TypePath`?](https://github.com/bevyengine/bevy/pull/5805/files/2afbd855327c4b68e0a6b6f03118f289988441a4#r961067892)
2023-06-05 20:31:20 +00:00
#[derive(AsBindGroup, TypeUuid, TypePath, Debug, Clone)]
#[uuid = "50ffce9e-1582-42e9-87cb-2233724426c0"]
struct CustomMaterial {}
impl Material2d for CustomMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/custom_gltf_2d.wgsl".into()
}
fn vertex_shader() -> ShaderRef {
"shaders/custom_gltf_2d.wgsl".into()
}
fn specialize(
descriptor: &mut RenderPipelineDescriptor,
layout: &MeshVertexBufferLayout,
_key: Material2dKey<Self>,
) -> Result<(), SpecializedMeshPipelineError> {
let vertex_layout = layout.get_layout(&[
Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
Mesh::ATTRIBUTE_COLOR.at_shader_location(1),
ATTRIBUTE_BARYCENTRIC.at_shader_location(2),
])?;
descriptor.vertex.buffers = vec![vertex_layout];
Ok(())
}
}