如何手动创建带有顶点的网格?

Bru*_*ner 18 rust bevy

我需要做什么才能创建具有以下顶点的网格:

let mut vertices : Vec<[f32; 3]> = Vec::new();

    vertices.push([0.0, 0.0, 0.0]);
    vertices.push([1.0, 2.0, 1.0]);
    vertices.push([2.0, 0.0, 0.0]);

Run Code Online (Sandbox Code Playgroud)

然后我想像这样生成一个 MeshBundle

commands
    .spawn(MeshBundle {
        mesh: mesh,
        transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)),
        ..Default::default()
    });
Run Code Online (Sandbox Code Playgroud)

fra*_*pps 20

该答案已更新为最新版本bevy = "0.11"并使用默认着色器。

下面的代码演示了如何:

  1. 定义顶点位置bevy::render::pipeline::PrimitiveTopology::TriangleList
  2. 顶点法线uv 坐标指定给顶点
  3. 使用我们定义的 3 个顶点创建一个三角形

它基于 bevy 中的内置形状,可以在此处找到。

use bevy::prelude::*;
use bevy::render::mesh::{self, PrimitiveTopology};

fn main() {
    App::new()
        .insert_resource(Msaa::Sample4)
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);

    // Positions of the vertices
    // See https://bevy-cheatbook.github.io/features/coords.html
    mesh.insert_attribute(
        Mesh::ATTRIBUTE_POSITION,
        vec![[0., 0., 0.], [1., 2., 1.], [2., 0., 0.]],
    );

    // In this example, normals and UVs don't matter,
    // so we just use the same value for all of them
    mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, vec![[0., 1., 0.]; 3]);
    mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, vec![[0., 0.]; 3]);

    // A triangle using vertices 0, 2, and 1.
    // Note: order matters. [0, 1, 2] will be flipped upside down, and you won't see it from behind!
    mesh.set_indices(Some(mesh::Indices::U32(vec![0, 2, 1])));

    commands.spawn(PbrBundle {
        mesh: meshes.add(mesh),
        material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
        ..default()
    });

    commands.spawn(PointLightBundle {
        point_light: PointLight {
            intensity: 1500.0,
            shadows_enabled: true,
            ..default()
        },
        transform: Transform::from_xyz(4.0, 8.0, 4.0),
        ..default()
    });

    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}
Run Code Online (Sandbox Code Playgroud)

您必须根据您的用例定义自己的位置uvs法线。某些着色器不需要所有这些网格属性。

  • @PhilippeParé这是因为默认情况下法线是插值的。您可以在 WGSL 中选择使用“平面”[插值](https://www.w3.org/TR/WGSL/#interpolation) 禁用此功能,但是使用该着色器渲染的所有网格都会丢失插值法线,如下所示[此处](/sf/ask/4201582941/)进行了讨论。因此,如果您想使用相同的着色器混合平坦和平滑的着色网格,复制顶点是您唯一的选择。 (2认同)