From 13da8abd6a5e4da998ec5718bc53a5f9acaa24be Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Tue, 8 Mar 2022 17:50:44 +0000 Subject: [PATCH] Fix mesh2d_manual example (#4037) # Objective Fixes #4036 ## Solution - Use `VertexBufferLayout::from_vertex_formats` - Actually put a u32 into `ATTRIBUTE_COLOR` and convert it in the shader I'm not 100% sure about the color stuff. It seems like `ATTRIBUTE_COLOR` has been `Uint32` this whole time, but this example previously worked with `[f32; 4]` somehow, perhaps because the vertex layout was manually specified. Let me know if that can be improved, or feel free to close for an alternative fix. --- examples/2d/mesh2d_manual.rs | 42 +++++++++++++----------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/examples/2d/mesh2d_manual.rs b/examples/2d/mesh2d_manual.rs index 21f9d34219bb85..b09a487a73d47a 100644 --- a/examples/2d/mesh2d_manual.rs +++ b/examples/2d/mesh2d_manual.rs @@ -11,7 +11,7 @@ use bevy::{ BlendState, ColorTargetState, ColorWrites, Face, FragmentState, FrontFace, MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipelineCache, RenderPipelineDescriptor, SpecializedPipeline, SpecializedPipelines, TextureFormat, - VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, + VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, }, texture::BevyDefault, view::VisibleEntities, @@ -70,8 +70,8 @@ fn star( // Set the position attribute star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos); // And a RGB color attribute as well - let mut v_color = vec![[0.0, 0.0, 0.0, 1.0]]; - v_color.extend_from_slice(&[[1.0, 1.0, 0.0, 1.0]; 10]); + let mut v_color: Vec = vec![Color::BLACK.as_linear_rgba_u32()]; + v_color.extend_from_slice(&[Color::YELLOW.as_linear_rgba_u32(); 10]); star.insert_attribute(Mesh::ATTRIBUTE_COLOR, v_color); // Now, we specify the indices of the vertex that are going to compose the @@ -131,24 +131,15 @@ impl SpecializedPipeline for ColoredMesh2dPipeline { fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { // Customize how to store the meshes' vertex attributes in the vertex buffer // Our meshes only have position and color - let vertex_attributes = vec![ - // Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically)) - VertexAttribute { - format: VertexFormat::Float32x3, - // this offset is the size of the color attribute, which is stored first - offset: 16, - // position is available at location 0 in the shader - shader_location: 0, - }, + let formats = vec![ + // Position + VertexFormat::Float32x3, // Color - VertexAttribute { - format: VertexFormat::Float32x4, - offset: 0, - shader_location: 1, - }, + VertexFormat::Uint32, ]; - // This is the sum of the size of position and color attributes (12 + 16 = 28) - let vertex_array_stride = 28; + + let vertex_layout = + VertexBufferLayout::from_vertex_formats(VertexStepMode::Vertex, formats); RenderPipelineDescriptor { vertex: VertexState { @@ -157,11 +148,7 @@ impl SpecializedPipeline for ColoredMesh2dPipeline { entry_point: "vertex".into(), shader_defs: Vec::new(), // Use our custom vertex buffer - buffers: vec![VertexBufferLayout { - array_stride: vertex_array_stride, - step_mode: VertexStepMode::Vertex, - attributes: vertex_attributes, - }], + buffers: vec![vertex_layout], }, fragment: Some(FragmentState { // Use our custom shader @@ -227,13 +214,13 @@ var mesh: Mesh2d; // The structure of the vertex buffer is as specified in `specialize()` struct Vertex { [[location(0)]] position: vec3; - [[location(1)]] color: vec4; + [[location(1)]] color: u32; }; struct VertexOutput { // The vertex shader must set the on-screen position of the vertex [[builtin(position)]] clip_position: vec4; - // We pass the vertex color to the framgent shader in location 0 + // We pass the vertex color to the fragment shader in location 0 [[location(0)]] color: vec4; }; @@ -243,7 +230,8 @@ fn vertex(vertex: Vertex) -> VertexOutput { var out: VertexOutput; // Project the world position of the mesh into screen position out.clip_position = view.view_proj * mesh.model * vec4(vertex.position, 1.0); - out.color = vertex.color; + // Unpack the `u32` from the vertex buffer into the `vec4` used by the fragment shader + out.color = vec4((vec4(vertex.color) >> vec4(0u, 8u, 16u, 24u)) & vec4(255u)) / 255.0; return out; }