From 1201480d4a9c7843f8d632103ecd67884d00586b Mon Sep 17 00:00:00 2001 From: Youssef Fellah Date: Fri, 1 May 2026 20:13:11 +0100 Subject: [PATCH] Implement glTF COLOR_0 vertex color support in StandardMaterial and UnlitMaterial --- assets/scene_renderer/shaders/DebugMaterial.hlsl | 4 ++++ .../scene_renderer/shaders/MaterialInterface.hlsli | 1 + assets/scene_renderer/shaders/MaterialVertex.hlsl | 2 ++ .../scene_renderer/shaders/StandardMaterial.hlsl | 2 ++ assets/scene_renderer/shaders/UnlitMaterial.hlsl | 2 ++ src/ppx/scene/scene_gltf_loader.cpp | 14 +++++++++++++- 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/assets/scene_renderer/shaders/DebugMaterial.hlsl b/assets/scene_renderer/shaders/DebugMaterial.hlsl index 6da4ac730..f3e70e803 100644 --- a/assets/scene_renderer/shaders/DebugMaterial.hlsl +++ b/assets/scene_renderer/shaders/DebugMaterial.hlsl @@ -15,6 +15,7 @@ #define ENABLE_VTX_ATTR_TEXCOORD #define ENABLE_VTX_ATTR_NORMAL #define ENABLE_VTX_ATTR_TANGENT +#define ENABLE_VTX_ATTR_COLOR #include "MaterialInterface.hlsli" @@ -35,6 +36,9 @@ float4 psmain(StandardVertexOutput input) : SV_TARGET else if(Draw.dbgVtxAttrIndex == DBG_VTX_ATTR_INDEX_TANGENT) { color = mul(Instances[Draw.instanceIndex].modelMatrix, float4(input.Tangent.xyz, 0)).xyz; } + else if(Draw.dbgVtxAttrIndex == DBG_VTX_ATTR_INDEX_COLOR) { + color = input.Color; + } return float4(normalize(color), 1); } diff --git a/assets/scene_renderer/shaders/MaterialInterface.hlsli b/assets/scene_renderer/shaders/MaterialInterface.hlsli index ec13860aa..ca7ee03de 100644 --- a/assets/scene_renderer/shaders/MaterialInterface.hlsli +++ b/assets/scene_renderer/shaders/MaterialInterface.hlsli @@ -65,6 +65,7 @@ struct DrawParams { #define DBG_VTX_ATTR_INDEX_TEXCOORD 1 #define DBG_VTX_ATTR_INDEX_NORMAL 2 #define DBG_VTX_ATTR_INDEX_TANGENT 3 +#define DBG_VTX_ATTR_INDEX_COLOR 4 #if defined(__spirv__) [[vk::push_constant]] diff --git a/assets/scene_renderer/shaders/MaterialVertex.hlsl b/assets/scene_renderer/shaders/MaterialVertex.hlsl index aa6721fd9..0689d3a54 100644 --- a/assets/scene_renderer/shaders/MaterialVertex.hlsl +++ b/assets/scene_renderer/shaders/MaterialVertex.hlsl @@ -15,6 +15,7 @@ #define ENABLE_VTX_ATTR_TEXCOORD #define ENABLE_VTX_ATTR_NORMAL #define ENABLE_VTX_ATTR_TANGENT +#define ENABLE_VTX_ATTR_COLOR #include "MaterialInterface.hlsli" StandardVertexOutput vsmain(StandardVertexInput input) @@ -29,5 +30,6 @@ StandardVertexOutput vsmain(StandardVertexInput input) output.TexCoord = input.TexCoord; output.Normal = input.Normal; output.Tangent = input.Tangent; + output.Color = input.Color; return output; } diff --git a/assets/scene_renderer/shaders/StandardMaterial.hlsl b/assets/scene_renderer/shaders/StandardMaterial.hlsl index edac55784..ba74f6aaf 100644 --- a/assets/scene_renderer/shaders/StandardMaterial.hlsl +++ b/assets/scene_renderer/shaders/StandardMaterial.hlsl @@ -15,6 +15,7 @@ #define ENABLE_VTX_ATTR_TEXCOORD #define ENABLE_VTX_ATTR_NORMAL #define ENABLE_VTX_ATTR_TANGENT +#define ENABLE_VTX_ATTR_COLOR #include "MaterialInterface.hlsli" #include "ppx/PBR.hlsli" @@ -46,6 +47,7 @@ float4 psmain(StandardVertexOutput input) : SV_TARGET baseColor = baseColor * float4(RemoveGamma(color.rgb, 2.2), color.a); } + baseColor.rgb *= input.Color; // Metal/roughness float metallic = material.metallicFactor; diff --git a/assets/scene_renderer/shaders/UnlitMaterial.hlsl b/assets/scene_renderer/shaders/UnlitMaterial.hlsl index 2bd011f2c..fce849686 100644 --- a/assets/scene_renderer/shaders/UnlitMaterial.hlsl +++ b/assets/scene_renderer/shaders/UnlitMaterial.hlsl @@ -15,6 +15,7 @@ #define ENABLE_VTX_ATTR_TEXCOORD #define ENABLE_VTX_ATTR_NORMAL #define ENABLE_VTX_ATTR_TANGENT +#define ENABLE_VTX_ATTR_COLOR #include "MaterialInterface.hlsli" // ------------------------------------------------------------------------------------------------- @@ -38,6 +39,7 @@ float4 psmain(StandardVertexOutput input) : SV_TARGET float4 value = tex.Sample(sam, uv); color = color * value; } + color.rgb *= input.Color; return color; } diff --git a/src/ppx/scene/scene_gltf_loader.cpp b/src/ppx/scene/scene_gltf_loader.cpp index cae41664c..bb038f4c0 100644 --- a/src/ppx/scene/scene_gltf_loader.cpp +++ b/src/ppx/scene/scene_gltf_loader.cpp @@ -1658,12 +1658,24 @@ ppx::Result GltfLoader::LoadMeshData( std::vector colors; if (loadParams.requiredVertexAttributes.bits.colors && !IsNull(gltflAccessors.pColors)) { PPX_ASSERT_MSG((colorFormat == targetColorFormat), "GLTF: vertex colors format is not supported"); - colors = UnpackFloat3s(*gltflAccessors.pColors); + if (gltflAccessors.pColors->type == cgltf_type_vec3) { + colors = UnpackFloat3s(*gltflAccessors.pColors); + } + else if (gltflAccessors.pColors->type == cgltf_type_vec4) { + auto colors4 = UnpackFloat4s(*gltflAccessors.pColors); + for (auto& c : colors4) { + colors.push_back(glm::float3(c.r, c.g, c.b)); + } + } + else { + PPX_ASSERT_MSG(false, "GLTF: vertex colors format must be VEC3 or VEC4"); + } } // Process vertex data for (cgltf_size i = 0; i < gltflAccessors.pPositions->count; ++i) { TriMeshVertexData vertexData = {}; + vertexData.color = glm::float3(1, 1, 1); vertexData.position = positions[i]; if (loadParams.requiredVertexAttributes.bits.normals && !normals.empty()) {