Skip to content

Commit

Permalink
added Vertex_Color support to bevy_pbr2
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Nov 25, 2021
1 parent 0bf90bb commit 5b9e5d3
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 57 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ path = "examples/3d/pbr.rs"
name = "pbr_pipelined"
path = "examples/3d/pbr_pipelined.rs"

[[example]]
name = "pbr_colors_pipelined"
path = "examples/3d/pbr_colors_pipelined.rs"

[[example]]
name = "render_to_texture"
path = "examples/3d/render_to_texture.rs"
Expand Down
83 changes: 83 additions & 0 deletions examples/3d/pbr_colors_pipelined.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use bevy::{
math::Vec3,
pbr2::{PbrBundle, PointLightBundle, StandardMaterial},
prelude::{App, Assets, Commands, ResMut, Transform},
render2::{
camera::PerspectiveCameraBundle,
mesh::{shape, Mesh, VertexAttributeValues},
},
PipelinedDefaultPlugins,
};

/// This example illustrates how to use the vertex colors attribute.
fn main() {
App::new()
.add_plugins(PipelinedDefaultPlugins)
.add_startup_system(setup)
.run();
}

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// create a generic cube
let mut cube_with_colors = Mesh::from(shape::Cube { size: 2.0 });

// set some nice nice colors!
cube_with_colors.set_attribute(
Mesh::ATTRIBUTE_COLOR,
// NOTE: the attribute count has to be consistent across all attributes, otherwise bevy
// will panic.
VertexAttributeValues::from(vec![
// top
[0.79, 0.73, 0.07, 1.],
[0.74, 0.14, 0.29, 1.],
[0.08, 0.55, 0.74, 1.],
[0.20, 0.27, 0.29, 1.],
// bottom
[0.79, 0.73, 0.07, 1.],
[0.74, 0.14, 0.29, 1.],
[0.08, 0.55, 0.74, 1.],
[0.20, 0.27, 0.29, 1.],
// right
[0.79, 0.73, 0.07, 1.],
[0.74, 0.14, 0.29, 1.],
[0.08, 0.55, 0.74, 1.],
[0.20, 0.27, 0.29, 1.],
// left
[0.79, 0.73, 0.07, 1.],
[0.74, 0.14, 0.29, 1.],
[0.08, 0.55, 0.74, 1.],
[0.20, 0.27, 0.29, 1.],
// front
[0.79, 0.73, 0.07, 1.],
[0.74, 0.14, 0.29, 1.],
[0.08, 0.55, 0.74, 1.],
[0.20, 0.27, 0.29, 1.],
// back
[0.79, 0.73, 0.07, 1.],
[0.74, 0.14, 0.29, 1.],
[0.08, 0.55, 0.74, 1.],
[0.20, 0.27, 0.29, 1.],
]),
);
// cube
commands.spawn_bundle(PbrBundle {
mesh: meshes.add(cube_with_colors), // use our cube with vertex colors
material: materials.add(Default::default()),
transform: Transform::from_xyz(0.0, 0.0, 0.0),
..Default::default()
});
// light
commands.spawn_bundle(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..Default::default()
});
// camera
commands.spawn_bundle(PerspectiveCameraBundle {
transform: Transform::from_xyz(3.0, 5.0, -8.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});
}
116 changes: 60 additions & 56 deletions pipelined/bevy_pbr2/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ bitflags::bitflags! {
const NONE = 0;
const VERTEX_TANGENTS = (1 << 0);
const TRANSPARENT_MAIN_PASS = (1 << 1);
const VERTEX_COLORS = (1 << 2);
const MSAA_RESERVED_BITS = MeshPipelineKey::MSAA_MASK_BITS << MeshPipelineKey::MSAA_SHIFT_BITS;
}
}
Expand All @@ -351,66 +352,69 @@ impl SpecializedPipeline for MeshPipeline {
type Key = MeshPipelineKey;

fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
let (vertex_array_stride, vertex_attributes) =
if key.contains(MeshPipelineKey::VERTEX_TANGENTS) {
(
48,
vec![
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 12,
shader_location: 0,
},
// Normal
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 0,
shader_location: 1,
},
// Uv (GOTCHA! uv is no longer third in the buffer due to how Mesh sorts attributes (alphabetically))
VertexAttribute {
format: VertexFormat::Float32x2,
offset: 40,
shader_location: 2,
},
// Tangent
VertexAttribute {
format: VertexFormat::Float32x4,
offset: 24,
shader_location: 3,
},
],
)
} else {
(
32,
vec![
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 12,
shader_location: 0,
},
// Normal
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 0,
shader_location: 1,
},
// Uv
VertexAttribute {
format: VertexFormat::Float32x2,
offset: 24,
shader_location: 2,
},
],
)
};
let mut vertex_attributes: Vec<VertexAttribute> = vec![];
let mut offset = 0;

// Mesh attributes are sorted alphabetically in the buffer, so add them in the correct
// order.

// colors: will be at location 3 or 4 depending on wether Vertex_Tangents are used
if key.contains(MeshPipelineKey::VERTEX_COLORS) {
vertex_attributes.push(VertexAttribute {
format: VertexFormat::Float32x4,
offset,
shader_location: if key.contains(MeshPipelineKey::VERTEX_TANGENTS) {
4
} else {
3
},
});
offset += 16;
}

// normals
vertex_attributes.push(VertexAttribute {
format: VertexFormat::Float32x3,
offset,
shader_location: 1,
});
offset += 12;

// positions
vertex_attributes.push(VertexAttribute {
format: VertexFormat::Float32x3,
offset,
shader_location: 0,
});
offset += 12;

// tangents
if key.contains(MeshPipelineKey::VERTEX_TANGENTS) {
vertex_attributes.push(VertexAttribute {
format: VertexFormat::Float32x4,
offset,
shader_location: 3,
});
offset += 16;
}

// uvs
vertex_attributes.push(VertexAttribute {
format: VertexFormat::Float32x2,
offset,
shader_location: 2,
});
offset += 8;

let vertex_array_stride = offset;

let mut shader_defs = Vec::new();
if key.contains(MeshPipelineKey::VERTEX_TANGENTS) {
shader_defs.push(String::from("VERTEX_TANGENTS"));
}
if key.contains(MeshPipelineKey::VERTEX_COLORS) {
shader_defs.push(String::from("VERTEX_COLORS"));
}

let (label, blend, depth_write_enabled);
if key.contains(MeshPipelineKey::TRANSPARENT_MAIN_PASS) {
Expand Down
29 changes: 28 additions & 1 deletion pipelined/bevy_pbr2/src/render/mesh.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ struct Vertex {
#ifdef VERTEX_TANGENTS
[[location(3)]] tangent: vec4<f32>;
#endif
#ifdef VERTEX_COLORS
#ifdef VERTEX_TANGENTS
[[location(4)]] color: vec4<f32>;
#endif
#ifndef VERTEX_TANGENTS
[[location(3)]] color: vec4<f32>;
#endif
#endif
};

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

[[group(2), binding(0)]]
Expand Down Expand Up @@ -45,6 +61,9 @@ fn vertex(vertex: Vertex) -> VertexOutput {
) * vertex.tangent.xyz,
vertex.tangent.w
);
#endif
#ifdef VERTEX_COLORS
out.world_color = vertex.color;
#endif
return out;
}
Expand All @@ -57,9 +76,17 @@ struct FragmentInput {
#ifdef VERTEX_TANGENTS
[[location(3)]] world_tangent: vec4<f32>;
#endif
#ifdef VERTEX_COLORS
#ifdef VERTEX_TANGENTS
[[location(4)]] world_color: vec4<f32>;
#endif
#ifndef VERTEX_TANGENTS
[[location(3)]] world_color: vec4<f32>;
#endif
#endif
};

[[stage(fragment)]]
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
}
}
3 changes: 3 additions & 0 deletions pipelined/bevy_pbr2/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ pub fn queue_meshes(
if mesh.has_tangents {
pbr_key.mesh_key |= MeshPipelineKey::VERTEX_TANGENTS;
}
if mesh.has_colors {
pbr_key.mesh_key |= MeshPipelineKey::VERTEX_COLORS;
}
}

if let AlphaMode::Blend = material.alpha_mode {
Expand Down
12 changes: 12 additions & 0 deletions pipelined/bevy_pbr2/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,23 @@ struct FragmentInput {
#ifdef VERTEX_TANGENTS
[[location(3)]] world_tangent: vec4<f32>;
#endif
#ifdef VERTEX_COLORS
#ifdef VERTEX_TANGENTS
[[location(4)]] world_color: vec4<f32>;
#endif
#ifndef VERTEX_TANGENTS
[[location(3)]] world_color: vec4<f32>;
#endif
#endif
};

[[stage(fragment)]]
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
var output_color: vec4<f32> = material.base_color;

#ifdef VERTEX_COLORS
output_color = in.world_color;
#endif
if ((material.flags & STANDARD_MATERIAL_FLAGS_BASE_COLOR_TEXTURE_BIT) != 0u) {
output_color = output_color * textureSample(base_color_texture, base_color_sampler, in.uv);
}
Expand Down
2 changes: 2 additions & 0 deletions pipelined/bevy_render2/src/mesh/mesh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ pub struct GpuMesh {
pub vertex_buffer: Buffer,
pub index_info: Option<GpuIndexInfo>,
pub has_tangents: bool,
pub has_colors: bool,
}

/// The index info of a [`GpuMesh`].
Expand Down Expand Up @@ -640,6 +641,7 @@ impl RenderAsset for Mesh {
vertex_buffer,
index_info,
has_tangents: mesh.attributes.contains_key(Mesh::ATTRIBUTE_TANGENT),
has_colors: mesh.attributes.contains_key(Mesh::ATTRIBUTE_COLOR),
})
}
}

0 comments on commit 5b9e5d3

Please sign in to comment.