Skip to content

Commit cbe13f3

Browse files
Improve Mesh documentation (#9061)
# Objective This PR continues #8885 It aims to improve the `Mesh` documentation in the following ways: - Put everything at the "top level" instead of the "impl". - Explain better what is a Mesh, how it can be created, and that it can be edited. - Explain it can be used with a `Material`, and mention `StandardMaterial`, `PbrBundle`, `ColorMaterial`, and `ColorMesh2dBundle` since those cover most cases - Mention the glTF/Bevy vocabulary discrepancy for "Mesh" - Add an image for the example - Various nitpicky modifications ## Note - The image I added is 90.3ko which I think is small enough? - Since rustdoc doesn't allow cross-reference not in dependencies of a subcrate [yet](rust-lang/rust#74481), I have a lot of backtick references that are not links :( - Since rustdoc doesn't allow linking to code in the crate (?) I put link to github directly. - Since rustdoc doesn't allow embed images in doc [yet](rust-lang/rust#32104), maybe [soon](rust-lang/rfcs#3397), I had to put only a link to the image. I don't think it's worth adding [embed_doc_image](https://docs.rs/embed-doc-image/latest/embed_doc_image/) as a dependency for this.
1 parent 3c6fad2 commit cbe13f3

File tree

4 files changed

+81
-44
lines changed

4 files changed

+81
-44
lines changed

assets/docs/Mesh.png

88.2 KB
Loading

crates/bevy_asset/src/loader.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use std::path::Path;
1414

1515
/// A loader for an asset source.
1616
///
17-
/// Types implementing this trait are used by the asset server to load assets into their respective
18-
/// asset storages.
17+
/// Types implementing this trait are used by the [`AssetServer`] to load assets
18+
/// into their respective asset storages.
1919
pub trait AssetLoader: Send + Sync + 'static {
2020
/// Processes the asset in an asynchronous closure.
2121
fn load<'a>(

crates/bevy_gltf/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ impl Plugin for GltfPlugin {
6060
}
6161
}
6262

63-
/// Representation of a loaded glTF file.
63+
/// Representation of a loaded glTF file
64+
/// (file loaded via the `AssetServer` with the extension `.glb` or `.gltf`).
6465
#[derive(Debug, TypeUuid, TypePath)]
6566
#[uuid = "5c7d5f8a-f7b0-4e45-a09e-406c0372fea2"]
6667
pub struct Gltf {

crates/bevy_render/src/mesh/mesh/mod.rs

+77-41
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,24 @@ use wgpu::{
2626
pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
2727
pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
2828

29-
// TODO: allow values to be unloaded after been submitting to the GPU to conserve memory
30-
#[derive(Debug, TypeUuid, TypePath, Clone)]
31-
#[uuid = "8ecbac0f-f545-4473-ad43-e1f4243af51e"]
32-
pub struct Mesh {
33-
primitive_topology: PrimitiveTopology,
34-
/// `std::collections::BTreeMap` with all defined vertex attributes (Positions, Normals, ...)
35-
/// for this mesh. Attribute ids to attribute values.
36-
/// Uses a BTreeMap because, unlike HashMap, it has a defined iteration order,
37-
/// which allows easy stable VertexBuffers (i.e. same buffer order)
38-
attributes: BTreeMap<MeshVertexAttributeId, MeshAttributeData>,
39-
indices: Option<Indices>,
40-
morph_targets: Option<Handle<Image>>,
41-
morph_target_names: Option<Vec<String>>,
42-
}
43-
44-
/// Contains geometry in the form of a mesh.
29+
/// A 3D object made out of vertices representing triangles, lines, or points,
30+
/// with "attribute" values for each vertex.
31+
///
32+
/// Meshes can be automatically generated by a bevy `AssetLoader` (generally by loading a `Gltf` file),
33+
/// or by converting a primitive [`shape`](crate::mesh::shape) using [`into`](std::convert::Into).
34+
/// It is also possible to create one manually.
35+
/// They can be edited after creation.
4536
///
46-
/// Often meshes are automatically generated by bevy's asset loaders or primitives, such as
47-
/// [`shape::Cube`](crate::mesh::shape::Cube) or [`shape::Box`](crate::mesh::shape::Box), but you can also construct
48-
/// one yourself.
37+
/// Meshes can be rendered with a `Material`, like `StandardMaterial` in `PbrBundle`
38+
/// or `ColorMaterial` in `ColorMesh2dBundle`.
4939
///
50-
/// Example of constructing a mesh (to be rendered with a `StandardMaterial`):
40+
/// A [`Mesh`] in Bevy is equivalent to a "primitive" in the glTF format, for a
41+
/// glTF Mesh representation, see `GltfMesh`.
42+
///
43+
/// ## Manual creation
44+
///
45+
/// The following function will construct a flat mesh, to be rendered with a
46+
/// `StandardMaterial` or `ColorMaterial`:
5147
/// ```
5248
/// # use bevy_render::mesh::{Mesh, Indices};
5349
/// # use bevy_render::render_resource::PrimitiveTopology;
@@ -78,50 +74,90 @@ pub struct Mesh {
7874
/// 1, 3, 2
7975
/// ])));
8076
/// mesh
81-
/// // For further visualization, explanation, and examples see the built-in Bevy examples
82-
/// // and the implementation of the built-in shapes.
8377
/// }
8478
/// ```
85-
/// Common points of confusion:
86-
/// - UV maps in Bevy are "flipped", (0.0, 0.0) = Top-Left (not Bot-Left like `OpenGL`)
87-
/// - It is normal for multiple vertices to have the same position
88-
/// attribute - it's a common technique in 3D modelling for complex UV mapping or other calculations.
8979
///
90-
/// To render correctly with `StandardMaterial` a mesh needs to have properly defined:
91-
/// - [`UVs`](Mesh::ATTRIBUTE_UV_0): Bevy needs to know how to map a texture onto the mesh.
92-
/// - [`Normals`](Mesh::ATTRIBUTE_NORMAL): Bevy needs to know how light interacts with your mesh. ([0.0, 0.0, 1.0] is very
93-
/// common for simple meshes because simple meshes are smooth, and they don't require complex light calculations.)
94-
/// - Vertex winding order -
95-
/// the default behavior is with `StandardMaterial.cull_mode` = Some([`Face::Front`](crate::render_resource::Face::Front)) which means
96-
/// that by default Bevy would *only* render the front of each triangle, and the front
97-
/// is the side of the triangle in which the vertices appear in a *counter-clockwise* order.
80+
/// You can see how it looks like [here](https://github.com/bevyengine/bevy/blob/main/assets/dovs/Mesh.png),
81+
/// used in a `PbrBundle` with a square bevy logo texture, with added axis, points,
82+
/// lines and text for clarity.
83+
///
84+
/// ## Other examples
85+
///
86+
/// For further visualization, explanation, and examples, see the built-in Bevy examples,
87+
/// and the [implementation of the built-in shapes](https://github.com/bevyengine/bevy/tree/main/crates/bevy_render/src/mesh/shape).
88+
/// In particular, [generate_custom_mesh](https://github.com/bevyengine/bevy/blob/main/examples/3d/generate_custom_mesh.rs)
89+
/// teaches you to access modify a Mesh's attributes after creating it.
90+
///
91+
/// ## Common points of confusion
9892
///
93+
/// - UV maps in Bevy start at the top-left, see [`ATTRIBUTE_UV_0`](Mesh::ATTRIBUTE_UV_0),
94+
/// other APIs can have other conventions, `OpenGL` starts at bottom-left.
95+
/// - It is possible and sometimes useful for multiple vertices to have the same
96+
/// [position attribute](Mesh::ATTRIBUTE_POSITION) value,
97+
/// it's a common technique in 3D modelling for complex UV mapping or other calculations.
98+
///
99+
/// ## Use with `StandardMaterial`
100+
///
101+
/// To render correctly with `StandardMaterial`, a mesh needs to have properly defined:
102+
/// - [`UVs`](Mesh::ATTRIBUTE_UV_0): Bevy needs to know how to map a texture onto the mesh
103+
/// (also true for `ColorMaterial`).
104+
/// - [`Normals`](Mesh::ATTRIBUTE_NORMAL): Bevy needs to know how light interacts with your mesh.
105+
/// [0.0, 0.0, 1.0] is very common for simple flat meshes on the XY plane,
106+
/// because simple meshes are smooth and they don't require complex light calculations.
107+
/// - Vertex winding order: by default, `StandardMaterial.cull_mode` is [`Some(Face::Back)`](crate::render_resource::Face),
108+
/// which means that Bevy would *only* render the "front" of each triangle, which
109+
/// is the side of the triangle from where the vertices appear in a *counter-clockwise* order.
110+
///
111+
// TODO: allow values to be unloaded after been submitting to the GPU to conserve memory
112+
#[derive(Debug, TypeUuid, TypePath, Clone)]
113+
#[uuid = "8ecbac0f-f545-4473-ad43-e1f4243af51e"]
114+
pub struct Mesh {
115+
primitive_topology: PrimitiveTopology,
116+
/// `std::collections::BTreeMap` with all defined vertex attributes (Positions, Normals, ...)
117+
/// for this mesh. Attribute ids to attribute values.
118+
/// Uses a BTreeMap because, unlike HashMap, it has a defined iteration order,
119+
/// which allows easy stable VertexBuffers (i.e. same buffer order)
120+
attributes: BTreeMap<MeshVertexAttributeId, MeshAttributeData>,
121+
indices: Option<Indices>,
122+
morph_targets: Option<Handle<Image>>,
123+
morph_target_names: Option<Vec<String>>,
124+
}
125+
99126
impl Mesh {
100-
/// Where the vertex is located in space. Use in conjunction with [`Mesh::insert_attribute`]
127+
/// Where the vertex is located in space. Use in conjunction with [`Mesh::insert_attribute`].
101128
pub const ATTRIBUTE_POSITION: MeshVertexAttribute =
102129
MeshVertexAttribute::new("Vertex_Position", 0, VertexFormat::Float32x3);
103130

104131
/// The direction the vertex normal is facing in.
105-
/// Use in conjunction with [`Mesh::insert_attribute`]
132+
/// Use in conjunction with [`Mesh::insert_attribute`].
106133
pub const ATTRIBUTE_NORMAL: MeshVertexAttribute =
107134
MeshVertexAttribute::new("Vertex_Normal", 1, VertexFormat::Float32x3);
108135

109-
/// Texture coordinates for the vertex. Use in conjunction with [`Mesh::insert_attribute`]
136+
/// Texture coordinates for the vertex. Use in conjunction with [`Mesh::insert_attribute`].
137+
///
138+
/// Values are generally between 0. and 1., with `StandardMaterial` and `ColorMaterial`
139+
/// `[0.,0.]` is the top left of the texture, and [1.,1.] the bottom-right.
140+
/// You usually want to only use values in that range, values outside will be
141+
/// clamped per pixel not for the vertex, "stretching" the borders of the texture.
142+
/// This behavior can be useful in some cases, usually when the borders have only
143+
/// one color, for example a logo, and you want to "extend" those borders.
110144
pub const ATTRIBUTE_UV_0: MeshVertexAttribute =
111145
MeshVertexAttribute::new("Vertex_Uv", 2, VertexFormat::Float32x2);
112146

113-
/// The direction of the vertex tangent. Used for normal mapping
147+
/// The direction of the vertex tangent. Used for normal mapping.
148+
/// Usually generated with [`generate_tangents`](Mesh::generate_tangents).
114149
pub const ATTRIBUTE_TANGENT: MeshVertexAttribute =
115150
MeshVertexAttribute::new("Vertex_Tangent", 3, VertexFormat::Float32x4);
116151

117-
/// Per vertex coloring. Use in conjunction with [`Mesh::insert_attribute`]
152+
/// Per vertex coloring. Use in conjunction with [`Mesh::insert_attribute`].
118153
pub const ATTRIBUTE_COLOR: MeshVertexAttribute =
119154
MeshVertexAttribute::new("Vertex_Color", 4, VertexFormat::Float32x4);
120155

121-
/// Per vertex joint transform matrix weight. Use in conjunction with [`Mesh::insert_attribute`]
156+
/// Per vertex joint transform matrix weight. Use in conjunction with [`Mesh::insert_attribute`].
122157
pub const ATTRIBUTE_JOINT_WEIGHT: MeshVertexAttribute =
123158
MeshVertexAttribute::new("Vertex_JointWeight", 5, VertexFormat::Float32x4);
124-
/// Per vertex joint transform matrix index. Use in conjunction with [`Mesh::insert_attribute`]
159+
160+
/// Per vertex joint transform matrix index. Use in conjunction with [`Mesh::insert_attribute`].
125161
pub const ATTRIBUTE_JOINT_INDEX: MeshVertexAttribute =
126162
MeshVertexAttribute::new("Vertex_JointIndex", 6, VertexFormat::Uint16x4);
127163

0 commit comments

Comments
 (0)