Path: blob/main/examples/2d/custom_gltf_vertex_attribute.rs
6592 views
//! Renders a glTF mesh in 2D with a custom vertex attribute.12use bevy::{3gltf::GltfPlugin,4mesh::{MeshVertexAttribute, MeshVertexBufferLayoutRef},5prelude::*,6reflect::TypePath,7render::render_resource::*,8shader::ShaderRef,9sprite_render::{Material2d, Material2dKey, Material2dPlugin},10};1112/// This example uses a shader source file from the assets subdirectory13const SHADER_ASSET_PATH: &str = "shaders/custom_gltf_2d.wgsl";1415/// This vertex attribute supplies barycentric coordinates for each triangle.16///17/// Each component of the vector corresponds to one corner of a triangle. It's18/// equal to 1.0 in that corner and 0.0 in the other two. Hence, its value in19/// the fragment shader indicates proximity to a corner or the opposite edge.20const ATTRIBUTE_BARYCENTRIC: MeshVertexAttribute =21MeshVertexAttribute::new("Barycentric", 2137464976, VertexFormat::Float32x3);2223fn main() {24App::new()25.insert_resource(AmbientLight {26color: Color::WHITE,27brightness: 1.0 / 5.0f32,28..default()29})30.add_plugins((31DefaultPlugins.set(32GltfPlugin::default()33// Map a custom glTF attribute name to a `MeshVertexAttribute`.34// The glTF file used here has an attribute name with *two*35// underscores: __BARYCENTRIC36// One is stripped to do the comparison here.37.add_custom_vertex_attribute("_BARYCENTRIC", ATTRIBUTE_BARYCENTRIC),38),39Material2dPlugin::<CustomMaterial>::default(),40))41.add_systems(Startup, setup)42.run();43}4445fn setup(46mut commands: Commands,47asset_server: Res<AssetServer>,48mut materials: ResMut<Assets<CustomMaterial>>,49) {50// Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.51let mesh = asset_server.load(52GltfAssetLabel::Primitive {53mesh: 0,54primitive: 0,55}56.from_asset("models/barycentric/barycentric.gltf"),57);58commands.spawn((59Mesh2d(mesh),60MeshMaterial2d(materials.add(CustomMaterial {})),61Transform::from_scale(150.0 * Vec3::ONE),62));6364commands.spawn(Camera2d);65}6667/// This custom material uses barycentric coordinates from68/// `ATTRIBUTE_BARYCENTRIC` to shade a white border around each triangle. The69/// thickness of the border is animated using the global time shader uniform.70#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]71struct CustomMaterial {}7273impl Material2d for CustomMaterial {74fn vertex_shader() -> ShaderRef {75SHADER_ASSET_PATH.into()76}77fn fragment_shader() -> ShaderRef {78SHADER_ASSET_PATH.into()79}8081fn specialize(82descriptor: &mut RenderPipelineDescriptor,83layout: &MeshVertexBufferLayoutRef,84_key: Material2dKey<Self>,85) -> Result<(), SpecializedMeshPipelineError> {86let vertex_layout = layout.0.get_layout(&[87Mesh::ATTRIBUTE_POSITION.at_shader_location(0),88Mesh::ATTRIBUTE_COLOR.at_shader_location(1),89ATTRIBUTE_BARYCENTRIC.at_shader_location(2),90])?;91descriptor.vertex.buffers = vec![vertex_layout];92Ok(())93}94}959697