@@ -230,6 +230,120 @@ bool ModelLoader::ParseGLTF(const std::string& filename, Model* model) {
230230 material->emissiveStrength = 1 .0f * light_scale;
231231 }
232232
233+ // Alpha mode / cutoff
234+ material->alphaMode = gltfMaterial.alphaMode .empty () ? std::string (" OPAQUE" ) : gltfMaterial.alphaMode ;
235+ material->alphaCutoff = static_cast <float >(gltfMaterial.alphaCutoff );
236+
237+ // Transmission (KHR_materials_transmission)
238+ auto transIt = gltfMaterial.extensions .find (" KHR_materials_transmission" );
239+ if (transIt != gltfMaterial.extensions .end ()) {
240+ const tinygltf::Value& ext = transIt->second ;
241+ if (ext.Has (" transmissionFactor" ) && ext.Get (" transmissionFactor" ).IsNumber ()) {
242+ material->transmissionFactor = static_cast <float >(ext.Get (" transmissionFactor" ).Get <double >());
243+ }
244+ }
245+
246+ // Specular-Glossiness (KHR_materials_pbrSpecularGlossiness)
247+ auto sgIt = gltfMaterial.extensions .find (" KHR_materials_pbrSpecularGlossiness" );
248+ if (sgIt != gltfMaterial.extensions .end ()) {
249+ const tinygltf::Value& ext = sgIt->second ;
250+ material->useSpecularGlossiness = true ;
251+ // diffuseFactor -> albedo and alpha
252+ if (ext.Has (" diffuseFactor" ) && ext.Get (" diffuseFactor" ).IsArray ()) {
253+ const auto & arr = ext.Get (" diffuseFactor" ).Get <tinygltf::Value::Array>();
254+ if (arr.size () >= 3 ) {
255+ material->albedo = glm::vec3 (
256+ arr[0 ].IsNumber () ? static_cast <float >(arr[0 ].Get <double >()) : material->albedo .r ,
257+ arr[1 ].IsNumber () ? static_cast <float >(arr[1 ].Get <double >()) : material->albedo .g ,
258+ arr[2 ].IsNumber () ? static_cast <float >(arr[2 ].Get <double >()) : material->albedo .b
259+ );
260+ if (arr.size () >= 4 && arr[3 ].IsNumber ()) {
261+ material->alpha = static_cast <float >(arr[3 ].Get <double >());
262+ }
263+ }
264+ }
265+ // specularFactor (vec3)
266+ if (ext.Has (" specularFactor" ) && ext.Get (" specularFactor" ).IsArray ()) {
267+ const auto & arr = ext.Get (" specularFactor" ).Get <tinygltf::Value::Array>();
268+ if (arr.size () >= 3 ) {
269+ material->specularFactor = glm::vec3 (
270+ arr[0 ].IsNumber () ? static_cast <float >(arr[0 ].Get <double >()) : material->specularFactor .r ,
271+ arr[1 ].IsNumber () ? static_cast <float >(arr[1 ].Get <double >()) : material->specularFactor .g ,
272+ arr[2 ].IsNumber () ? static_cast <float >(arr[2 ].Get <double >()) : material->specularFactor .b
273+ );
274+ }
275+ }
276+ // glossinessFactor (float)
277+ if (ext.Has (" glossinessFactor" ) && ext.Get (" glossinessFactor" ).IsNumber ()) {
278+ material->glossinessFactor = static_cast <float >(ext.Get (" glossinessFactor" ).Get <double >());
279+ }
280+
281+ // Load diffuseTexture into albedoTexturePath if present
282+ if (ext.Has (" diffuseTexture" ) && ext.Get (" diffuseTexture" ).IsObject ()) {
283+ const auto & diffObj = ext.Get (" diffuseTexture" );
284+ if (diffObj.Has (" index" ) && diffObj.Get (" index" ).IsInt ()) {
285+ int texIndex = diffObj.Get (" index" ).Get <int >();
286+ if (texIndex >= 0 && texIndex < static_cast <int >(gltfModel.textures .size ())) {
287+ const auto & texture = gltfModel.textures [texIndex];
288+ int imageIndex = -1 ;
289+ if (texture.source >= 0 && texture.source < static_cast <int >(gltfModel.images .size ())) {
290+ imageIndex = texture.source ;
291+ } else {
292+ auto extBasis = texture.extensions .find (" KHR_texture_basisu" );
293+ if (extBasis != texture.extensions .end ()) {
294+ const tinygltf::Value &e = extBasis->second ;
295+ if (e.Has (" source" ) && e.Get (" source" ).IsInt ()) {
296+ int src = e.Get (" source" ).Get <int >();
297+ if (src >= 0 && src < static_cast <int >(gltfModel.images .size ())) imageIndex = src;
298+ }
299+ }
300+ }
301+ if (imageIndex >= 0 ) {
302+ const auto & image = gltfModel.images [imageIndex];
303+ std::string textureId = " gltf_baseColor_" + std::to_string (texIndex);
304+ if (!image.image .empty ()) {
305+ if (renderer->LoadTextureFromMemory (textureId, image.image .data (), image.width , image.height , image.component )) {
306+ material->albedoTexturePath = textureId;
307+ }
308+ } else if (!image.uri .empty ()) {
309+ std::vector<uint8_t > data; int w=0 ,h=0 ,c=0 ;
310+ std::string filePath = baseTexturePath + image.uri ;
311+ if (LoadKTX2FileToRGBA (filePath, data, w, h, c) && renderer->LoadTextureFromMemory (textureId, data.data (), w, h, c)) {
312+ material->albedoTexturePath = textureId;
313+ }
314+ }
315+ }
316+ }
317+ }
318+ }
319+ // Load specularGlossinessTexture into specGlossTexturePath and mirror to metallicRoughnessTexturePath (binding 2)
320+ if (ext.Has (" specularGlossinessTexture" ) && ext.Get (" specularGlossinessTexture" ).IsObject ()) {
321+ const auto & sgObj = ext.Get (" specularGlossinessTexture" );
322+ if (sgObj.Has (" index" ) && sgObj.Get (" index" ).IsInt ()) {
323+ int texIndex = sgObj.Get (" index" ).Get <int >();
324+ if (texIndex >= 0 && texIndex < static_cast <int >(gltfModel.textures .size ())) {
325+ const auto & texture = gltfModel.textures [texIndex];
326+ if (texture.source >= 0 && texture.source < static_cast <int >(gltfModel.images .size ())) {
327+ std::string textureId = " gltf_specGloss_" + std::to_string (texIndex);
328+ const auto & image = gltfModel.images [texture.source ];
329+ if (!image.image .empty ()) {
330+ if (renderer->LoadTextureFromMemory (textureId, image.image .data (), image.width , image.height , image.component )) {
331+ material->specGlossTexturePath = textureId;
332+ material->metallicRoughnessTexturePath = textureId; // reuse binding 2
333+ }
334+ } else if (!image.uri .empty ()) {
335+ std::vector<uint8_t > data; int w=0 ,h=0 ,c=0 ;
336+ std::string filePath = baseTexturePath + image.uri ;
337+ if (LoadKTX2FileToRGBA (filePath, data, w, h, c) && renderer->LoadTextureFromMemory (textureId, data.data (), w, h, c)) {
338+ material->specGlossTexturePath = textureId;
339+ material->metallicRoughnessTexturePath = textureId; // reuse binding 2
340+ }
341+ }
342+ }
343+ }
344+ }
345+ }
346+ }
233347
234348 // Extract texture information and load embedded texture data
235349 if (gltfMaterial.pbrMetallicRoughness .baseColorTexture .index >= 0 ) {
0 commit comments