From 5d9f5c54ef567770ecdd65cb33503281c9c9f477 Mon Sep 17 00:00:00 2001 From: Manuel Maceira Date: Fri, 12 Dec 2025 16:34:36 -0300 Subject: [PATCH] GLTF: Fix emissive texture import when emissiveFactor is absent --- modules/gltf/gltf_document.cpp | 6 +- .../emissive_no_factor.gltf | 36 ++++++++++ .../data/gltf_emissive_no_factor/texture.png | Bin 0 -> 92 bytes modules/gltf/tests/test_gltf_emissive.h | 68 ++++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 modules/gltf/tests/data/gltf_emissive_no_factor/emissive_no_factor.gltf create mode 100644 modules/gltf/tests/data/gltf_emissive_no_factor/texture.png create mode 100644 modules/gltf/tests/test_gltf_emissive.h diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 6a675fe279f..71d4163d210 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -3105,7 +3105,11 @@ Error GLTFDocument::_parse_materials(Ref p_state) { if (bct.has("index")) { material->set_texture(BaseMaterial3D::TEXTURE_EMISSION, _get_texture(p_state, bct["index"], TEXTURE_TYPE_GENERIC)); material->set_feature(BaseMaterial3D::FEATURE_EMISSION, true); - material->set_emission(Color(0, 0, 0)); + material->set_emission_operator(BaseMaterial3D::EMISSION_OP_MULTIPLY); + // glTF spec: emissiveFactor × emissiveTexture. Use WHITE if no factor specified. + if (!material_dict.has("emissiveFactor")) { + material->set_emission(Color(1, 1, 1)); + } } } diff --git a/modules/gltf/tests/data/gltf_emissive_no_factor/emissive_no_factor.gltf b/modules/gltf/tests/data/gltf_emissive_no_factor/emissive_no_factor.gltf new file mode 100644 index 00000000000..deef16c2b82 --- /dev/null +++ b/modules/gltf/tests/data/gltf_emissive_no_factor/emissive_no_factor.gltf @@ -0,0 +1,36 @@ +{ + "asset": { "version": "2.0", "generator": "Test for emissiveTexture without emissiveFactor" }, + "scene": 0, + "scenes": [{ "name": "Scene", "nodes": [0] }], + "nodes": [{ "name": "Cube", "mesh": 0 }], + "meshes": [{ + "name": "Cube", + "primitives": [{ + "attributes": { "POSITION": 0 }, + "material": 0 + }] + }], + "materials": [{ + "name": "EmissiveNoFactor", + "emissiveTexture": { "index": 0 }, + "pbrMetallicRoughness": {} + }], + "textures": [{ "source": 0 }], + "images": [{ "uri": "texture.png" }], + "accessors": [{ + "bufferView": 0, + "componentType": 5126, + "count": 3, + "type": "VEC3", + "max": [1, 1, 0], + "min": [-1, -1, 0] + }], + "bufferViews": [{ + "buffer": 0, + "byteLength": 36 + }], + "buffers": [{ + "uri": "data:application/octet-stream;base64,AAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AACAvwAAgD8AAAAA", + "byteLength": 36 + }] +} diff --git a/modules/gltf/tests/data/gltf_emissive_no_factor/texture.png b/modules/gltf/tests/data/gltf_emissive_no_factor/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..cb872e7419b7904df8cc02fa9fb7f84a8885bb0a GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^Od!m`1|*BN@u~nR#^NA%Cx&(BWL^R}VxBIJAsjQ4 nQxXz>{GZ?0*vRT+Xu!arp}@j4(|hkJpb7?0S3j3^P6(loaded->find_child("Cube", true, true)); + CHECK_MESSAGE(mesh != nullptr, "Mesh not found."); + + Ref mat = mesh->get_active_material(0); + CHECK_MESSAGE(mat.is_valid(), "Material not found."); + + // Emission should be enabled. + CHECK(mat->get_feature(BaseMaterial3D::FEATURE_EMISSION)); + + // Emission operator should be MULTIPLY per glTF spec. + CHECK(mat->get_emission_operator() == BaseMaterial3D::EMISSION_OP_MULTIPLY); + + // Without emissiveFactor, emission color should be WHITE, not BLACK. + Color c = mat->get_emission(); + CHECK_MESSAGE(c.r > 0.9f, "Emission red should be ~1.0 when emissiveFactor is absent."); + CHECK_MESSAGE(c.g > 0.9f, "Emission green should be ~1.0 when emissiveFactor is absent."); + CHECK_MESSAGE(c.b > 0.9f, "Emission blue should be ~1.0 when emissiveFactor is absent."); + + memdelete(loaded); +} + +} // namespace TestGltf + +#endif // TOOLS_ENABLED