如何在 Bevy 中将纹理分配给 2D 网格?
How do I assign textures to 2D meshes in Bevy?
我想创建类似于 Civilization 的六角形图块,我可以单击这些图块并使用拖放系统将东西移入和移出它们。我编写的代码在 运行 程序后抛出错误:
Mesh is missing requested attribute: Vertex_Normal (MeshVertexAttributeId(1), pipeline type: Some("bevy_sprite::mesh2d::material::Material2dPipeline<bevy_sprite::mesh2d::color_material::ColorMaterial>"))
我不确定为什么这会引发错误,因为当我从四边形 (meshes.add(Mesh::from(shape::Quad::default())).into()
) 创建基本网格时程序 运行 没问题,但我想要一个 2D 六边形。
这是我的设置代码:
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
asset_server: Res<AssetServer>
) {
let vertices = vec![
[-0.8660, 0.5000],
[ 0.8660, 0.5000],
[-1.0000, 0.0000],
[ 1.0000, 0.0000],
[-0.8660,-0.5000],
[ 0.8660,-0.5000]];
let indeces = Indices::U16(vec![
0, 1, 2,
1, 3, 2,
2, 3, 4,
3, 5, 4
]);
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
mesh.set_indices(Some(indeces));
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(MaterialMesh2dBundle {
mesh: meshes.add(mesh).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(asset_server.load(TILE_SPRITE).into()),
..default()
});
}
这是我的主要内容:
const TILE_SPRITE: &str = "tile.png";
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}
使用 bevy
中的默认着色器,您的网格还必须为每个顶点设置 法线 和 uvs。
您可以提供自己的着色器或添加所需的属性,类似于 中显示的方法。
除此之外,您提供的 positions 和 indices 似乎不正确。即使您在 2D 模式下使用 bevy,您仍然必须使用三个坐标提供位置(z
beeing 设置为零)。您可以在下面的 RenderDoc 屏幕截图中看到其他情况:
这是一个小示例,其中包含更正的索引和位置,以及 UV 和法线的占位符值,应该可以帮助您入门:
use bevy::{
prelude::*,
render::mesh::{Indices, PrimitiveTopology},
sprite::MaterialMesh2dBundle,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
_asset_server: Res<AssetServer>,
) {
let vertices = vec![
[-0.8660, 0.5000, 0f32],
[0.8660, 0.5000, 0f32],
[-1.0000, 0.0000, 0f32],
[1.0000, 0.0000, 0f32],
[-0.8660, -0.5000, 0f32],
[0.8660, -0.5000, 0f32],
];
let normals = vec![
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
];
let uvs = vec![
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
];
let indices = Indices::U16(vec![1, 0, 2, 3, 1, 2, 3, 2, 4, 3, 4, 5]);
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
mesh.set_indices(Some(indices));
let mut camera = OrthographicCameraBundle::new_2d();
camera.orthographic_projection.scale = 1f32;
commands.spawn_bundle(camera);
commands.spawn_bundle(MaterialMesh2dBundle {
mesh: meshes.add(mesh).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
}
请注意,为了让您的 Sprite 显示出来,您必须更改 UV 坐标(我确实将它们留在了 0, 0
,因为我不知道您想如何映射您的精灵/纹理到六边形)。
我想创建类似于 Civilization 的六角形图块,我可以单击这些图块并使用拖放系统将东西移入和移出它们。我编写的代码在 运行 程序后抛出错误:
Mesh is missing requested attribute: Vertex_Normal (MeshVertexAttributeId(1), pipeline type: Some("bevy_sprite::mesh2d::material::Material2dPipeline<bevy_sprite::mesh2d::color_material::ColorMaterial>"))
我不确定为什么这会引发错误,因为当我从四边形 (meshes.add(Mesh::from(shape::Quad::default())).into()
) 创建基本网格时程序 运行 没问题,但我想要一个 2D 六边形。
这是我的设置代码:
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
asset_server: Res<AssetServer>
) {
let vertices = vec![
[-0.8660, 0.5000],
[ 0.8660, 0.5000],
[-1.0000, 0.0000],
[ 1.0000, 0.0000],
[-0.8660,-0.5000],
[ 0.8660,-0.5000]];
let indeces = Indices::U16(vec![
0, 1, 2,
1, 3, 2,
2, 3, 4,
3, 5, 4
]);
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
mesh.set_indices(Some(indeces));
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
commands.spawn_bundle(MaterialMesh2dBundle {
mesh: meshes.add(mesh).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(asset_server.load(TILE_SPRITE).into()),
..default()
});
}
这是我的主要内容:
const TILE_SPRITE: &str = "tile.png";
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}
使用 bevy
中的默认着色器,您的网格还必须为每个顶点设置 法线 和 uvs。
您可以提供自己的着色器或添加所需的属性,类似于
除此之外,您提供的 positions 和 indices 似乎不正确。即使您在 2D 模式下使用 bevy,您仍然必须使用三个坐标提供位置(z
beeing 设置为零)。您可以在下面的 RenderDoc 屏幕截图中看到其他情况:
这是一个小示例,其中包含更正的索引和位置,以及 UV 和法线的占位符值,应该可以帮助您入门:
use bevy::{
prelude::*,
render::mesh::{Indices, PrimitiveTopology},
sprite::MaterialMesh2dBundle,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
_asset_server: Res<AssetServer>,
) {
let vertices = vec![
[-0.8660, 0.5000, 0f32],
[0.8660, 0.5000, 0f32],
[-1.0000, 0.0000, 0f32],
[1.0000, 0.0000, 0f32],
[-0.8660, -0.5000, 0f32],
[0.8660, -0.5000, 0f32],
];
let normals = vec![
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
[0f32, 0f32, 1f32],
];
let uvs = vec![
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
[0.0000, 0.0000],
];
let indices = Indices::U16(vec![1, 0, 2, 3, 1, 2, 3, 2, 4, 3, 4, 5]);
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
mesh.set_indices(Some(indices));
let mut camera = OrthographicCameraBundle::new_2d();
camera.orthographic_projection.scale = 1f32;
commands.spawn_bundle(camera);
commands.spawn_bundle(MaterialMesh2dBundle {
mesh: meshes.add(mesh).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
}
请注意,为了让您的 Sprite 显示出来,您必须更改 UV 坐标(我确实将它们留在了 0, 0
,因为我不知道您想如何映射您的精灵/纹理到六边形)。