diff --git a/assets/docs/Mesh.png b/assets/docs/Mesh.png new file mode 100644 index 0000000000000..fd556d3427f5c Binary files /dev/null and b/assets/docs/Mesh.png differ diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index a494fd0a2cc01..885f194d12bae 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -14,8 +14,8 @@ use std::path::Path; /// A loader for an asset source. /// -/// Types implementing this trait are used by the asset server to load assets into their respective -/// asset storages. +/// Types implementing this trait are used by the [`AssetServer`] to load assets +/// into their respective asset storages. pub trait AssetLoader: Send + Sync + 'static { /// Processes the asset in an asynchronous closure. fn load<'a>( diff --git a/crates/bevy_gltf/src/lib.rs b/crates/bevy_gltf/src/lib.rs index 7277a906269f5..176f473da4387 100644 --- a/crates/bevy_gltf/src/lib.rs +++ b/crates/bevy_gltf/src/lib.rs @@ -57,7 +57,8 @@ impl Plugin for GltfPlugin { } } -/// Representation of a loaded glTF file. +/// Representation of a loaded glTF file +/// (file loaded via the `AssetServer` with the extension `.glb` or `.gltf`). #[derive(Debug, TypeUuid, TypePath)] #[uuid = "5c7d5f8a-f7b0-4e45-a09e-406c0372fea2"] pub struct Gltf { diff --git a/crates/bevy_render/src/mesh/mesh/mod.rs b/crates/bevy_render/src/mesh/mesh/mod.rs index 2110fec6aae89..3bb065b2922aa 100644 --- a/crates/bevy_render/src/mesh/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mesh/mod.rs @@ -26,28 +26,24 @@ use wgpu::{ pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0; pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10; -// TODO: allow values to be unloaded after been submitting to the GPU to conserve memory -#[derive(Debug, TypeUuid, TypePath, Clone)] -#[uuid = "8ecbac0f-f545-4473-ad43-e1f4243af51e"] -pub struct Mesh { - primitive_topology: PrimitiveTopology, - /// `std::collections::BTreeMap` with all defined vertex attributes (Positions, Normals, ...) - /// for this mesh. Attribute ids to attribute values. - /// Uses a BTreeMap because, unlike HashMap, it has a defined iteration order, - /// which allows easy stable VertexBuffers (i.e. same buffer order) - attributes: BTreeMap, - indices: Option, - morph_targets: Option>, - morph_target_names: Option>, -} - -/// Contains geometry in the form of a mesh. +/// A 3D object made out of vertices representing triangles, lines, or points, +/// with "attribute" values for each vertex. +/// +/// Meshes can be automatically generated by a bevy `AssetLoader` (generally by loading a `Gltf` file), +/// or by converting a primitive [`shape`](crate::mesh::shape) using [`into`](std::convert::Into). +/// It is also possible to create one manually. +/// They can be edited after creation. /// -/// Often meshes are automatically generated by bevy's asset loaders or primitives, such as -/// [`shape::Cube`](crate::mesh::shape::Cube) or [`shape::Box`](crate::mesh::shape::Box), but you can also construct -/// one yourself. +/// Meshes can be rendered with a `Material`, like `StandardMaterial` in `PbrBundle` +/// or `ColorMaterial` in `ColorMesh2dBundle`. /// -/// Example of constructing a mesh (to be rendered with a `StandardMaterial`): +/// A [`Mesh`] in Bevy is equivalent to a "primitive" in the glTF format, for a +/// glTF Mesh representation, see `GltfMesh`. +/// +/// ## Manual creation +/// +/// The following function will construct a flat mesh, to be rendered with a +/// `StandardMaterial` or `ColorMaterial`: /// ``` /// # use bevy_render::mesh::{Mesh, Indices}; /// # use bevy_render::render_resource::PrimitiveTopology; @@ -78,50 +74,90 @@ pub struct Mesh { /// 1, 3, 2 /// ]))); /// mesh -/// // For further visualization, explanation, and examples see the built-in Bevy examples -/// // and the implementation of the built-in shapes. /// } /// ``` -/// Common points of confusion: -/// - UV maps in Bevy are "flipped", (0.0, 0.0) = Top-Left (not Bot-Left like `OpenGL`) -/// - It is normal for multiple vertices to have the same position -/// attribute - it's a common technique in 3D modelling for complex UV mapping or other calculations. /// -/// To render correctly with `StandardMaterial` a mesh needs to have properly defined: -/// - [`UVs`](Mesh::ATTRIBUTE_UV_0): Bevy needs to know how to map a texture onto the mesh. -/// - [`Normals`](Mesh::ATTRIBUTE_NORMAL): Bevy needs to know how light interacts with your mesh. ([0.0, 0.0, 1.0] is very -/// common for simple meshes because simple meshes are smooth, and they don't require complex light calculations.) -/// - Vertex winding order - -/// the default behavior is with `StandardMaterial.cull_mode` = Some([`Face::Front`](crate::render_resource::Face::Front)) which means -/// that by default Bevy would *only* render the front of each triangle, and the front -/// is the side of the triangle in which the vertices appear in a *counter-clockwise* order. +/// You can see how it looks like [here](https://github.com/bevyengine/bevy/blob/main/assets/dovs/Mesh.png), +/// used in a `PbrBundle` with a square bevy logo texture, with added axis, points, +/// lines and text for clarity. +/// +/// ## Other examples +/// +/// For further visualization, explanation, and examples, see the built-in Bevy examples, +/// and the [implementation of the built-in shapes](https://github.com/bevyengine/bevy/tree/main/crates/bevy_render/src/mesh/shape). +/// In particular, [generate_custom_mesh](https://github.com/bevyengine/bevy/blob/main/examples/3d/generate_custom_mesh.rs) +/// teaches you to access modify a Mesh's attributes after creating it. +/// +/// ## Common points of confusion /// +/// - UV maps in Bevy start at the top-left, see [`ATTRIBUTE_UV_0`](Mesh::ATTRIBUTE_UV_0), +/// other APIs can have other conventions, `OpenGL` starts at bottom-left. +/// - It is possible and sometimes useful for multiple vertices to have the same +/// [position attribute](Mesh::ATTRIBUTE_POSITION) value, +/// it's a common technique in 3D modelling for complex UV mapping or other calculations. +/// +/// ## Use with `StandardMaterial` +/// +/// To render correctly with `StandardMaterial`, a mesh needs to have properly defined: +/// - [`UVs`](Mesh::ATTRIBUTE_UV_0): Bevy needs to know how to map a texture onto the mesh +/// (also true for `ColorMaterial`). +/// - [`Normals`](Mesh::ATTRIBUTE_NORMAL): Bevy needs to know how light interacts with your mesh. +/// [0.0, 0.0, 1.0] is very common for simple flat meshes on the XY plane, +/// because simple meshes are smooth and they don't require complex light calculations. +/// - Vertex winding order: by default, `StandardMaterial.cull_mode` is [`Some(Face::Back)`](crate::render_resource::Face), +/// which means that Bevy would *only* render the "front" of each triangle, which +/// is the side of the triangle from where the vertices appear in a *counter-clockwise* order. +/// +// TODO: allow values to be unloaded after been submitting to the GPU to conserve memory +#[derive(Debug, TypeUuid, TypePath, Clone)] +#[uuid = "8ecbac0f-f545-4473-ad43-e1f4243af51e"] +pub struct Mesh { + primitive_topology: PrimitiveTopology, + /// `std::collections::BTreeMap` with all defined vertex attributes (Positions, Normals, ...) + /// for this mesh. Attribute ids to attribute values. + /// Uses a BTreeMap because, unlike HashMap, it has a defined iteration order, + /// which allows easy stable VertexBuffers (i.e. same buffer order) + attributes: BTreeMap, + indices: Option, + morph_targets: Option>, + morph_target_names: Option>, +} + impl Mesh { - /// Where the vertex is located in space. Use in conjunction with [`Mesh::insert_attribute`] + /// Where the vertex is located in space. Use in conjunction with [`Mesh::insert_attribute`]. pub const ATTRIBUTE_POSITION: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_Position", 0, VertexFormat::Float32x3); /// The direction the vertex normal is facing in. - /// Use in conjunction with [`Mesh::insert_attribute`] + /// Use in conjunction with [`Mesh::insert_attribute`]. pub const ATTRIBUTE_NORMAL: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_Normal", 1, VertexFormat::Float32x3); - /// Texture coordinates for the vertex. Use in conjunction with [`Mesh::insert_attribute`] + /// Texture coordinates for the vertex. Use in conjunction with [`Mesh::insert_attribute`]. + /// + /// Values are generally between 0. and 1., with `StandardMaterial` and `ColorMaterial` + /// `[0.,0.]` is the top left of the texture, and [1.,1.] the bottom-right. + /// You usually want to only use values in that range, values outside will be + /// clamped per pixel not for the vertex, "stretching" the borders of the texture. + /// This behavior can be useful in some cases, usually when the borders have only + /// one color, for example a logo, and you want to "extend" those borders. pub const ATTRIBUTE_UV_0: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_Uv", 2, VertexFormat::Float32x2); - /// The direction of the vertex tangent. Used for normal mapping + /// The direction of the vertex tangent. Used for normal mapping. + /// Usually generated with [`generate_tangents`](Mesh::generate_tangents). pub const ATTRIBUTE_TANGENT: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_Tangent", 3, VertexFormat::Float32x4); - /// Per vertex coloring. Use in conjunction with [`Mesh::insert_attribute`] + /// Per vertex coloring. Use in conjunction with [`Mesh::insert_attribute`]. pub const ATTRIBUTE_COLOR: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_Color", 4, VertexFormat::Float32x4); - /// Per vertex joint transform matrix weight. Use in conjunction with [`Mesh::insert_attribute`] + /// Per vertex joint transform matrix weight. Use in conjunction with [`Mesh::insert_attribute`]. pub const ATTRIBUTE_JOINT_WEIGHT: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_JointWeight", 5, VertexFormat::Float32x4); - /// Per vertex joint transform matrix index. Use in conjunction with [`Mesh::insert_attribute`] + + /// Per vertex joint transform matrix index. Use in conjunction with [`Mesh::insert_attribute`]. pub const ATTRIBUTE_JOINT_INDEX: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_JointIndex", 6, VertexFormat::Uint16x4);