Skip to content

Commit e230004

Browse files
thebracketjames7132
authored andcommitted
Apply vertex colors to ColorMaterial and Mesh2D (bevyengine#4812)
# Objective - Add Vertex Color support to 2D meshes and ColorMaterial. This extends the work from bevyengine#4528 (which in turn builds on the excellent tangent handling). ## Solution - Added `#ifdef` wrapped support for vertex colors in the 2D mesh shader and `ColorMaterial` shader. - Added an example, `mesh2d_vertex_color_texture` to demonstrate it in action. ![image](https://user-images.githubusercontent.com/14896751/169530930-6ae0c6be-2f69-40e3-a600-ba91d7178bc3.png) --- ## Changelog - Added optional (ifdef wrapped) vertex color support to the 2dmesh and color material systems.
1 parent 82375b2 commit e230004

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ path = "examples/2d/mesh2d.rs"
143143
name = "mesh2d_manual"
144144
path = "examples/2d/mesh2d_manual.rs"
145145

146+
[[example]]
147+
name = "mesh2d_vertex_color_texture"
148+
path = "examples/2d/mesh2d_vertex_color_texture.rs"
149+
146150
[[example]]
147151
name = "shapes"
148152
path = "examples/2d/shapes.rs"

crates/bevy_sprite/src/mesh2d/color_material.wgsl

+7
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,20 @@ struct FragmentInput {
2929
#ifdef VERTEX_TANGENTS
3030
[[location(3)]] world_tangent: vec4<f32>;
3131
#endif
32+
#ifdef VERTEX_COLORS
33+
[[location(4)]] colors: vec4<f32>;
34+
#endif
3235
};
3336

3437
[[stage(fragment)]]
3538
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
3639
var output_color: vec4<f32> = material.color;
3740
if ((material.flags & COLOR_MATERIAL_FLAGS_TEXTURE_BIT) != 0u) {
41+
#ifdef VERTEX_COLORS
42+
output_color = output_color * textureSample(texture, texture_sampler, in.uv) * in.colors;
43+
#else
3844
output_color = output_color * textureSample(texture, texture_sampler, in.uv);
45+
#endif
3946
}
4047
return output_color;
4148
}

crates/bevy_sprite/src/mesh2d/mesh2d.wgsl

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ struct Vertex {
88
#ifdef VERTEX_TANGENTS
99
[[location(3)]] tangent: vec4<f32>;
1010
#endif
11+
#ifdef VERTEX_COLORS
12+
[[location(4)]] colors: vec4<f32>;
13+
#endif
1114
};
1215

1316
struct VertexOutput {
@@ -18,6 +21,9 @@ struct VertexOutput {
1821
#ifdef VERTEX_TANGENTS
1922
[[location(3)]] world_tangent: vec4<f32>;
2023
#endif
24+
#ifdef VERTEX_COLORS
25+
[[location(4)]] colors: vec4<f32>;
26+
#endif
2127
};
2228

2329
[[group(0), binding(0)]]
@@ -48,6 +54,9 @@ fn vertex(vertex: Vertex) -> VertexOutput {
4854
) * vertex.tangent.xyz,
4955
vertex.tangent.w
5056
);
57+
#endif
58+
#ifdef VERTEX_COLORS
59+
out.colors = vertex.colors;
5160
#endif
5261
return out;
5362
}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//! Shows how to render a polygonal [`Mesh`], generated from a [`Quad`] primitive, in a 2D scene.
2+
//! Adds a texture and colored vertices, giving per-vertex tinting.
3+
4+
use bevy::{prelude::*, sprite::MaterialMesh2dBundle};
5+
6+
fn main() {
7+
App::new()
8+
.add_plugins(DefaultPlugins)
9+
.add_startup_system(setup)
10+
.run();
11+
}
12+
13+
fn setup(
14+
mut commands: Commands,
15+
mut meshes: ResMut<Assets<Mesh>>,
16+
mut materials: ResMut<Assets<ColorMaterial>>,
17+
asset_server: Res<AssetServer>,
18+
) {
19+
// Load the Bevy logo as a texture
20+
let texture_handle = asset_server.load("branding/banner.png");
21+
// Build a default quad mesh
22+
let mut mesh = Mesh::from(shape::Quad::default());
23+
// Build vertex colors for the quad. One entry per vertex (the corners of the quad)
24+
let vertex_colors: Vec<[f32; 4]> = vec![
25+
Color::RED.as_rgba_f32(),
26+
Color::GREEN.as_rgba_f32(),
27+
Color::BLUE.as_rgba_f32(),
28+
Color::WHITE.as_rgba_f32(),
29+
];
30+
// Insert the vertex colors as an attribute
31+
mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertex_colors);
32+
// Spawn
33+
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
34+
commands.spawn_bundle(MaterialMesh2dBundle {
35+
mesh: meshes.add(mesh).into(),
36+
transform: Transform::default().with_scale(Vec3::splat(128.)),
37+
material: materials.add(ColorMaterial::from(texture_handle)),
38+
..default()
39+
});
40+
}

examples/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Example | File | Description
8989
`move_sprite` | [`2d/move_sprite.rs`](./2d/move_sprite.rs) | Changes the transform of a sprite.
9090
`mesh2d` | [`2d/mesh2d.rs`](./2d/mesh2d.rs) | Renders a 2d mesh
9191
`mesh2d_manual` | [`2d/mesh2d_manual.rs`](./2d/mesh2d_manual.rs) | Renders a custom mesh "manually" with "mid-level" renderer apis.
92+
`mesh2d_vertex_color_texture` | [`2d/mesh2d_vertex_color_texture.rs`](./2d/mesh2d_vertex_color_texture.rs) | Renders a 2d mesh with vertex color attributes.
9293
`shapes` | [`2d/shapes.rs`](./2d/shapes.rs) | Renders a rectangle, circle, and hexagon
9394
`sprite` | [`2d/sprite.rs`](./2d/sprite.rs) | Renders a sprite
9495
`sprite_sheet` | [`2d/sprite_sheet.rs`](./2d/sprite_sheet.rs) | Renders an animated sprite

0 commit comments

Comments
 (0)