Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Add support for vertex colors #4528

Closed
wants to merge 1 commit into from

Conversation

HackerFoo
Copy link
Contributor

Objective

Add support for vertex colors

Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose VertexFormat::Float32x4, but I'd prefer 16-bit floats if/when support is added.

Changelog

Added

  • Vertex colors can be specified using the Mesh::ATTRIBUTE_COLOR mesh attribute.

[[location(4)]] joint_indices: vec4<u32>;
[[location(5)]] joint_weights: vec4<f32>;
[[location(5)]] joint_indices: vec4<u32>;
[[location(6)]] joint_weights: vec4<f32>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I shifted the locations to match the ids given in the MeshVertexAttributes in bevy_render/src/mesh/mesh/mod.rs.

@HackerFoo HackerFoo added the A-Rendering Drawing game state to the screen label Apr 18, 2022
@HackerFoo HackerFoo requested a review from cart April 18, 2022 21:15
@HackerFoo HackerFoo requested a review from superdump April 18, 2022 21:15
@alice-i-cecile alice-i-cecile added the C-Feature A new feature, making something new possible label Apr 18, 2022
// This is the default color, but note that vertex colors are
// multiplied by the base color, so you'll likely want this to be
// white if using vertex colors.
material: materials.add(Color::rgb(1., 1., 1.).into()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It defaults to white, as I recall, to allow default to be identity for a material with a texture. That said, I think it's good to comment as it could easily be a source of confusion otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 37 - 40 are really there just to explain why the base_color should probably be white when using vertex colors. It seemed like a good way to document this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it is. And it's an additional flexibility to be able to tint things, if nothing else. :)

@CptPotato
Copy link
Contributor

CptPotato commented Apr 19, 2022

Would u32 (8 bit per channel) be sufficient for vertex colors?

I personally don't think using values greater that 1.0 are very useful, because when multiplying it with the base color it could potentially "break" the PBR visuals (more light gets reflected than received). There might be some unusual use cases, though.

On the other hand, the precision of 8bit would not be that great, but since vertex attributes get interpolated I don't think it would be very visible. (edit: u64 would be another option, which would still be significantly smaller than a full vec4<f32> while being very accurate).


As a side note, would it be possible for users to adjust the shader so that the vertex colors are used differently? i.e. using them as light factor or emissive multiplier. In that case I could see some uses for f16/f32.

@HackerFoo
Copy link
Contributor Author

I'm using linear float colors because it matches the base color format and the format used in the shader, and to avoid color matching problems. At least the way I use vertex colors, they aren't interpolated because all vertices of a triangle share the same color.

16 bit normalized linear color (as VertexFormat::Unorm16x4) might be good enough. Floats give greater precision near zero and generally match the logarithmic perception of light better than fixed precision numbers. So I think 16 bit floats would be ideal.

@CptPotato
Copy link
Contributor

CptPotato commented Apr 19, 2022

SRGB encoded integers would provide the same "perceptive" distribution of values and shouldn't cause matching issues like the one you've linked. In that case u16 would also be much more precise than linear f16 in the [0; 1] range.

But I do get your point. I'm not trying to block this PR or force you to change the implementation, just trying to provide some thought on possible alternatives.
As you already mentioned, f16 (once it's available) would be a good compromise for "general purpose" vertex colors ("unlimited" range, no conversion required in the shader, relatively small and precise enough).

@superdump
Copy link
Contributor

bors r+

bors bot pushed a commit that referenced this pull request May 5, 2022
# Objective

Add support for vertex colors

## Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose `VertexFormat::Float32x4`, but I'd prefer 16-bit floats if/when support is added.

## Changelog

### Added
- Vertex colors can be specified using the `Mesh::ATTRIBUTE_COLOR` mesh attribute.
@bors bors bot changed the title Add support for vertex colors [Merged by Bors] - Add support for vertex colors May 5, 2022
@bors bors bot closed this May 5, 2022
robtfm pushed a commit to robtfm/bevy that referenced this pull request May 10, 2022
# Objective

Add support for vertex colors

## Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose `VertexFormat::Float32x4`, but I'd prefer 16-bit floats if/when support is added.

## Changelog

### Added
- Vertex colors can be specified using the `Mesh::ATTRIBUTE_COLOR` mesh attribute.
@SalfordShane
Copy link

SalfordShane commented May 13, 2022

@HackerFoo Cheers for pushing this, it's a huge help.

A couple of thoughts:

  • At the moment, the vertex_colors.rs example is using materials.add(Color::rgb(1., 1., 1.).into()) to set the default material colour which each vertex colour will be multiplied by.
  • It makes sense, therefor, for users to simply default this to 1.0, 1.0, 1.0 most of the time, however, this produces an RGBA colour with an alpha of 1.0 by default
  • When the alpha is set to 1.0, alpha blending is disabled in the StandardMaterial being used in the example.
  • As a result, when changing the code in the example to use rgba values for the vertex colours, the transparency isn't working, which feels somewhat incongruous with the current expectations of how the default material colour multiplication works.

As a result, you end up having to do something like this for the material creation:

// The vertex colour channels will be multiplied by 1.0 (so will remain the same) but we explicitly enable AlphaMode blending
let mut material: StandardMaterial = Color::rgba(1., 1., 1., 1.).into();
material.alpha_mode = AlphaMode::Blend;

commands.spawn_bundle(PbrBundle {
        // ... mesh data
        material: materials.add(material),
        // ... defaults and transforms
});

There's probably no way around this for now and it's a relatively simple fix, but should we update the docs / example to mention this? It feels like a bit of a pitfall which took me a good chunk of time to debug tonight.

exjam pushed a commit to exjam/bevy that referenced this pull request May 22, 2022
# Objective

Add support for vertex colors

## Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose `VertexFormat::Float32x4`, but I'd prefer 16-bit floats if/when support is added.

## Changelog

### Added
- Vertex colors can be specified using the `Mesh::ATTRIBUTE_COLOR` mesh attribute.
bors bot pushed a commit that referenced this pull request May 30, 2022
# 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.
james7132 pushed a commit to james7132/bevy that referenced this pull request Jun 7, 2022
# 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.
komadori pushed a commit to komadori/bevy that referenced this pull request Jun 30, 2022
# Objective

Add support for vertex colors

## Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose `VertexFormat::Float32x4`, but I'd prefer 16-bit floats if/when support is added.

## Changelog

### Added
- Vertex colors can be specified using the `Mesh::ATTRIBUTE_COLOR` mesh attribute.
bors bot pushed a commit that referenced this pull request Jul 8, 2022
# Objective

Bevy requires meshes to include UV coordinates, even if the material does not use any textures, and will fail with an error `ERROR bevy_pbr::material: Mesh is missing requested attribute: Vertex_Uv (MeshVertexAttributeId(2), pipeline type: Some("bevy_pbr::material::MaterialPipeline<bevy_pbr::pbr_material::StandardMaterial>"))` otherwise. The objective of this PR is to permit this.

## Solution

This PR follows the design of #4528, which added support for per-vertex colours. It adds a shader define called VERTEX_UVS which indicates the presence of UV coordinates to the shader.
inodentry pushed a commit to IyesGames/bevy that referenced this pull request Aug 8, 2022
# Objective

Bevy requires meshes to include UV coordinates, even if the material does not use any textures, and will fail with an error `ERROR bevy_pbr::material: Mesh is missing requested attribute: Vertex_Uv (MeshVertexAttributeId(2), pipeline type: Some("bevy_pbr::material::MaterialPipeline<bevy_pbr::pbr_material::StandardMaterial>"))` otherwise. The objective of this PR is to permit this.

## Solution

This PR follows the design of bevyengine#4528, which added support for per-vertex colours. It adds a shader define called VERTEX_UVS which indicates the presence of UV coordinates to the shader.
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
# Objective

Bevy requires meshes to include UV coordinates, even if the material does not use any textures, and will fail with an error `ERROR bevy_pbr::material: Mesh is missing requested attribute: Vertex_Uv (MeshVertexAttributeId(2), pipeline type: Some("bevy_pbr::material::MaterialPipeline<bevy_pbr::pbr_material::StandardMaterial>"))` otherwise. The objective of this PR is to permit this.

## Solution

This PR follows the design of bevyengine#4528, which added support for per-vertex colours. It adds a shader define called VERTEX_UVS which indicates the presence of UV coordinates to the shader.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

Bevy requires meshes to include UV coordinates, even if the material does not use any textures, and will fail with an error `ERROR bevy_pbr::material: Mesh is missing requested attribute: Vertex_Uv (MeshVertexAttributeId(2), pipeline type: Some("bevy_pbr::material::MaterialPipeline<bevy_pbr::pbr_material::StandardMaterial>"))` otherwise. The objective of this PR is to permit this.

## Solution

This PR follows the design of bevyengine#4528, which added support for per-vertex colours. It adds a shader define called VERTEX_UVS which indicates the presence of UV coordinates to the shader.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

Add support for vertex colors

## Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose `VertexFormat::Float32x4`, but I'd prefer 16-bit floats if/when support is added.

## Changelog

### Added
- Vertex colors can be specified using the `Mesh::ATTRIBUTE_COLOR` mesh attribute.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

6 participants