Skip to content

Implement glTF COLOR_0 vertex color support in StandardMaterial and UnlitMaterial#618

Open
yss-ef wants to merge 2 commits into
google:mainfrom
yss-ef:main
Open

Implement glTF COLOR_0 vertex color support in StandardMaterial and UnlitMaterial#618
yss-ef wants to merge 2 commits into
google:mainfrom
yss-ef:main

Conversation

@yss-ef

@yss-ef yss-ef commented May 1, 2026

Copy link
Copy Markdown

Description

Implement glTF COLOR_0 vertex color support in the scene renderer.

According to the glTF 2.0 specification (Section 3.9.2):

In addition to the material properties, if a primitive specifies a vertex color using the attribute
semantic property COLOR_0, then this value acts as an additional linear multiplier to base color.

Previously, while GltfLoader would load the COLOR_0 accessor, the data was not being utilized by the
StandardMaterial or UnlitMaterial shaders. This PR enables the vertex color attribute across the scene
renderer's shader pipeline and applies it as a linear multiplier to the base color.

Problem

Vertex colors provided in glTF assets were being ignored during shading, resulting in incorrect
rendering for models that rely on COLOR_0 for tinting, baked effects, or specific material tests.

Solution

  1. Shader Pipeline Updates:
    • Modified MaterialVertex.hlsl to define ENABLE_VTX_ATTR_COLOR and pass the color attribute from
      vertex input to the pixel shader.
    • Updated StandardMaterial.hlsl and UnlitMaterial.hlsl to multiply the calculated baseColor by
      input.Color.
  2. GltfLoader Enhancements:
    • Updated GltfLoader::LoadMeshData in scene_gltf_loader.cpp to correctly handle both VEC3 and VEC4
      glTF vertex color formats.
    • Ensured the default vertex color is set to white (1, 1, 1) when the attribute is missing,
      preventing unintended darkening.
  3. Debug Support:
    • Added DBG_VTX_ATTR_INDEX_COLOR to MaterialInterface.hlsli.
    • Updated DebugMaterial.hlsl to allow visualizing vertex colors for debugging purposes.

Verification Results

These changes enable correct rendering for several glTF-Sample-Assets, including:

  • BoxVertexColor
  • CompareBaseColor
  • IridescentDishWithOlives
  • PrimitiveModeNormalsTest
  • RecursiveSkeleton
  • SheenWoodLeatherSofa
  • VertexColorTest

@google-cla

google-cla Bot commented May 1, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@yss-ef yss-ef closed this May 1, 2026
@yss-ef yss-ef reopened this May 1, 2026
@yss-ef yss-ef closed this May 1, 2026
@yss-ef yss-ef reopened this May 1, 2026
@footballhead
footballhead self-requested a review May 20, 2026 14:33

@footballhead footballhead left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution!

However, I'm encountering a validation layer error on Linux. When I run vk_gltf_basic_materials with the validation layers enabled, I ecounter the following assertion:

*** VULKAN VALIDATION ERROR MESSAGE ***
Severity : ERROR
Type     : [VALIDATION]
Objects  : [0]: <UNNAMED OBJECT>
Message  : vkCreateGraphicsPipelines(): pCreateInfos[0].pVertexInputState->pVertexAttributeDescriptions does not have a Location 4 but vertex shader has an input variable at that Location. (This can be valid if either the vertexAttributeRobustness or maintenance9 feature is enabled).
The Vulkan spec states: If the vertexAttributeRobustness feature is not enabled, and the maintenance9 feature is not enabled, and the pipeline is being created with vertex input state and pVertexInputState is not dynamic, then all variables with the Input storage class decorated with Location in the Vertex Execution Model OpEntryPoint must contain a location in VkVertexInputAttributeDescription::location (https://vulkan.lunarg.com/doc/view/1.4.335.0/linux/antora/spec/latest/chapters/pipelines.html#VUID-VkGraphicsPipelineCreateInfo-Input-07904)

The primary consumer of the scene loader is the gltf_basic_materials sample; I've added instructions for running it in #621. What results are you seeing?

// Process vertex data
for (cgltf_size i = 0; i < gltflAccessors.pPositions->count; ++i) {
TriMeshVertexData vertexData = {};
vertexData.color = glm::float3(1, 1, 1);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This file needs to be formatted with clang-format-16. Alternatively, the clang-format GitHub action includes a diff in its log that can be applied in order to format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants