Skip to content

Commit

Permalink
Apply vertex colors to ColorMaterial and Mesh2D (#4812)
Browse files Browse the repository at this point in the history
# Objective

- Add Vertex Color support to 2D meshes and ColorMaterial. This extends the work from #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.
  • Loading branch information
thebracket committed May 30, 2022
1 parent 1bbd5c2 commit a6eb3fa
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ path = "examples/2d/mesh2d.rs"
name = "mesh2d_manual"
path = "examples/2d/mesh2d_manual.rs"

[[example]]
name = "mesh2d_vertex_color_texture"
path = "examples/2d/mesh2d_vertex_color_texture.rs"

[[example]]
name = "shapes"
path = "examples/2d/shapes.rs"
Expand Down
7 changes: 7 additions & 0 deletions crates/bevy_sprite/src/mesh2d/color_material.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,20 @@ struct FragmentInput {
#ifdef VERTEX_TANGENTS
[[location(3)]] world_tangent: vec4<f32>;
#endif
#ifdef VERTEX_COLORS
[[location(4)]] colors: vec4<f32>;
#endif
};

[[stage(fragment)]]
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
var output_color: vec4<f32> = material.color;
if ((material.flags & COLOR_MATERIAL_FLAGS_TEXTURE_BIT) != 0u) {
#ifdef VERTEX_COLORS
output_color = output_color * textureSample(texture, texture_sampler, in.uv) * in.colors;
#else
output_color = output_color * textureSample(texture, texture_sampler, in.uv);
#endif
}
return output_color;
}
9 changes: 9 additions & 0 deletions crates/bevy_sprite/src/mesh2d/mesh2d.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ struct Vertex {
#ifdef VERTEX_TANGENTS
[[location(3)]] tangent: vec4<f32>;
#endif
#ifdef VERTEX_COLORS
[[location(4)]] colors: vec4<f32>;
#endif
};

struct VertexOutput {
Expand All @@ -18,6 +21,9 @@ struct VertexOutput {
#ifdef VERTEX_TANGENTS
[[location(3)]] world_tangent: vec4<f32>;
#endif
#ifdef VERTEX_COLORS
[[location(4)]] colors: vec4<f32>;
#endif
};

[[group(0), binding(0)]]
Expand Down Expand Up @@ -48,6 +54,9 @@ fn vertex(vertex: Vertex) -> VertexOutput {
) * vertex.tangent.xyz,
vertex.tangent.w
);
#endif
#ifdef VERTEX_COLORS
out.colors = vertex.colors;
#endif
return out;
}
Expand Down
40 changes: 40 additions & 0 deletions examples/2d/mesh2d_vertex_color_texture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! Shows how to render a polygonal [`Mesh`], generated from a [`Quad`] primitive, in a 2D scene.
//! Adds a texture and colored vertices, giving per-vertex tinting.
use bevy::{prelude::*, 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>,
) {
// Load the Bevy logo as a texture
let texture_handle = asset_server.load("branding/banner.png");
// Build a default quad mesh
let mut mesh = Mesh::from(shape::Quad::default());
// Build vertex colors for the quad. One entry per vertex (the corners of the quad)
let vertex_colors: Vec<[f32; 4]> = vec![
Color::RED.as_rgba_f32(),
Color::GREEN.as_rgba_f32(),
Color::BLUE.as_rgba_f32(),
Color::WHITE.as_rgba_f32(),
];
// Insert the vertex colors as an attribute
mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertex_colors);
// Spawn
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(ColorMaterial::from(texture_handle)),
..default()
});
}
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Example | File | Description
`move_sprite` | [`2d/move_sprite.rs`](./2d/move_sprite.rs) | Changes the transform of a sprite.
`mesh2d` | [`2d/mesh2d.rs`](./2d/mesh2d.rs) | Renders a 2d mesh
`mesh2d_manual` | [`2d/mesh2d_manual.rs`](./2d/mesh2d_manual.rs) | Renders a custom mesh "manually" with "mid-level" renderer apis.
`mesh2d_vertex_color_texture` | [`2d/mesh2d_vertex_color_texture.rs`](./2d/mesh2d_vertex_color_texture.rs) | Renders a 2d mesh with vertex color attributes.
`shapes` | [`2d/shapes.rs`](./2d/shapes.rs) | Renders a rectangle, circle, and hexagon
`sprite` | [`2d/sprite.rs`](./2d/sprite.rs) | Renders a sprite
`sprite_sheet` | [`2d/sprite_sheet.rs`](./2d/sprite_sheet.rs) | Renders an animated sprite
Expand Down

0 comments on commit a6eb3fa

Please sign in to comment.