/// <summary> /// Add the KHR_texture_transform to the glTF file /// </summary> /// <param name="gltf"></param> /// <param name="babylonMaterial"></param> private void AddTextureTransformExtension(ref GLTF gltf, ref GLTFTextureInfo gltfTextureInfo, BabylonTexture babylonTexture) { if (!gltf.extensionsUsed.Contains(KHR_texture_transform)) { gltf.extensionsUsed.Add(KHR_texture_transform); } if (!gltf.extensionsRequired.Contains(KHR_texture_transform)) { gltf.extensionsRequired.Add(KHR_texture_transform); } float angle = babylonTexture.wAng; float angleDirect = -babylonTexture.wAng; KHR_texture_transform textureTransform = new KHR_texture_transform { offset = new float[] { babylonTexture.uOffset, -babylonTexture.vOffset }, rotation = angle, scale = new float[] { babylonTexture.uScale, -babylonTexture.vScale }, texCoord = babylonTexture.coordinatesIndex }; if (gltfTextureInfo.extensions == null) { gltfTextureInfo.extensions = new GLTFExtensions(); } gltfTextureInfo.extensions[KHR_texture_transform] = textureTransform; }
/// <summary> /// Add the KHR_texture_transform to the glTF file /// </summary> /// <param name="gltf"></param> /// <param name="babylonMaterial"></param> private void AddTextureTransformExtension(ref GLTF gltf, ref GLTFTextureInfo gltfTextureInfo, BabylonTexture babylonTexture) { if (gltf.extensionsUsed.Contains(KHR_texture_transform) == false) { gltf.extensionsUsed.Add(KHR_texture_transform); } float angle = babylonTexture.wAng; float angleDirect = -babylonTexture.wAng; KHR_texture_transform textureTransform = new KHR_texture_transform { offset = new float[] { babylonTexture.uOffset, -babylonTexture.vOffset }, rotation = angle, scale = new float[] { babylonTexture.uScale, babylonTexture.vScale }, texCoord = babylonTexture.coordinatesIndex }; textureTransform.offset[1] += 1 - babylonTexture.vScale; // update vOffset according to the vScale textureTransform.offset[0] += (float)(0.5 * (1 - (Math.Cos(angleDirect) - Math.Sin(angleDirect)))); // update uOffset according to the rotation textureTransform.offset[1] += (float)(0.5 * (1 - (Math.Sin(angleDirect) + Math.Cos(angleDirect)))); // update vOffset according to the rotation if (gltfTextureInfo.extensions == null) { gltfTextureInfo.extensions = new GLTFExtensions(); } gltfTextureInfo.extensions[KHR_texture_transform] = textureTransform; }
public void RegisterEmissive(GLTFTextureInfo TextureInfo, BabylonStandardMaterial babylonMaterial, float[] diffuse, float[] emissive) { string pathDiffuse; string pathEmissive; if (babylonMaterial.diffuseTexture != null) { pathDiffuse = babylonMaterial.diffuseTexture.originalPath; } else { pathDiffuse = "none"; } if (babylonMaterial.emissiveTexture != null) { pathEmissive = babylonMaterial.emissiveTexture.originalPath; } else { pathEmissive = "none"; } var _pair = CreatePair(pathDiffuse, pathEmissive, diffuse, emissive); _DicoEmissiveTextureComponent.Add(_pair, TextureInfo); }
public void AddStandText(TexturesPaths key, GLTFTextureInfo finalTextBC, GLTFTextureInfo finalTextMR) { var _valuePair = new PairBaseColorMetallicRoughness(); _valuePair.baseColor = finalTextBC; _valuePair.metallicRoughness = finalTextMR; _DicoMatTextureGLTF.Add(key, _valuePair); }
private string TextureTransformID(GLTFTextureInfo gltfTextureInfo) { if (gltfTextureInfo.extensions == null || !gltfTextureInfo.extensions.ContainsKey(KHR_texture_transform)) { return(""); } else { // Set an id for the texture transform and append to the name KHR_texture_transform textureTransform = gltfTextureInfo.extensions[GLTFExporter.KHR_texture_transform] as KHR_texture_transform; var offsetID = textureTransform.offset[0] + "_" + textureTransform.offset[1]; var rotationID = textureTransform.rotation.ToString(); var scaleID = textureTransform.scale[0] + "_" + textureTransform.scale[1]; var textureTransformID = offsetID + "_" + rotationID + "_" + scaleID; return(textureTransformID); } }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf, string name, Func <string> writeImageFunc) { if (babylonTexture == null) { return(null); } if (name == null) { name = babylonTexture.name; } logger.RaiseMessage("GLTFExporter.Texture | Export texture named: " + name, 2); if (glTFTextureInfoMap.ContainsKey(babylonTexture.Id)) { return(glTFTextureInfoMap[babylonTexture.Id]); } else { string validImageFormat = writeImageFunc.Invoke(); if (validImageFormat == null) { return(null); } name = Path.ChangeExtension(name, validImageFormat); // -------------------------- // -------- Sampler --------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create sampler", 3); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; // --- Retrieve info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); var matchingSampler = gltf.SamplersList.FirstOrDefault(sampler => sampler.wrapS == gltfSampler.wrapS && sampler.wrapT == gltfSampler.wrapT && sampler.magFilter == gltfSampler.magFilter && sampler.minFilter == gltfSampler.minFilter); if (matchingSampler != null) { gltfSampler = matchingSampler; } else { gltf.SamplersList.Add(gltfSampler); } // -------------------------- // --------- Image ---------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create image", 3); GLTFImage gltfImage = null; if (glTFImageMap.ContainsKey(name)) { gltfImage = glTFImageMap[name]; } else { string textureUri = name; if (!string.IsNullOrWhiteSpace(exportParameters.textureFolder)) { textureUri = PathUtilities.GetRelativePath(exportParameters.outputPath, exportParameters.textureFolder) + "/" + name; } gltfImage = new GLTFImage { uri = textureUri }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); glTFImageMap.Add(name, gltfImage); switch (validImageFormat) { case "jpg": gltfImage.FileExtension = "jpeg"; break; case "png": gltfImage.FileExtension = "png"; break; } } // -------------------------- // -------- Texture --------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create texture", 3); var gltfTexture = new GLTFTexture { name = name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; gltf.TexturesList.Add(gltfTexture); // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index, texCoord = babylonTexture.coordinatesIndex }; if (!(babylonTexture.uOffset == 0) || !(babylonTexture.vOffset == 0) || !(babylonTexture.uScale == 1) || !(babylonTexture.vScale == -1) || !(babylonTexture.wAng == 0)) { // Add texture extension if enabled in the export settings if (exportParameters.enableKHRTextureTransform) { AddTextureTransformExtension(ref gltf, ref gltfTextureInfo, babylonTexture); } else { logger.RaiseWarning("GLTFExporter.Texture | KHR_texture_transform is not enabled, so the texture may look incorrect at runtime!", 3); logger.RaiseWarning("GLTFExporter.Texture | KHR_texture_transform is not enabled, so the texture may look incorrect at runtime!", 3); } } var textureID = name + TextureTransformID(gltfTextureInfo); // Check for texture optimization. This is done here after the texture transform has been potentially applied to the texture extension if (CheckIfImageIsRegistered(textureID)) { var textureComponent = GetRegisteredTexture(textureID); return(textureComponent); } // Add the texture in the dictionary RegisterTexture(gltfTextureInfo, textureID); glTFTextureInfoMap[babylonTexture.Id] = gltfTextureInfo; return(gltfTextureInfo); } }
private void ExportMaterial(BabylonMaterial babylonMaterial, GLTF gltf) { var name = babylonMaterial.name; var id = babylonMaterial.id; logger.RaiseMessage("GLTFExporter.Material | Export material named: " + name, 1); GLTFMaterial gltfMaterial = null; string message = null; IGLTFMaterialExporter customMaterialExporter = exportParameters.customGLTFMaterialExporter; if (customMaterialExporter != null && customMaterialExporter.GetGltfMaterial(babylonMaterial, gltf, logger, out gltfMaterial)) { gltfMaterial.index = gltf.MaterialsList.Count; gltf.MaterialsList.Add(gltfMaterial); } else if (babylonMaterial.GetType() == typeof(BabylonStandardMaterial)) { var babylonStandardMaterial = babylonMaterial as BabylonStandardMaterial; // --- prints --- #region prints logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial data", 2); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.alphaMode=" + babylonMaterial.alphaMode, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3); // Ambient for (int i = 0; i < babylonStandardMaterial.ambient.Length; i++) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambient[" + i + "]=" + babylonStandardMaterial.ambient[i], 3); } // Diffuse logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuse.Length=" + babylonStandardMaterial.diffuse.Length, 3); for (int i = 0; i < babylonStandardMaterial.diffuse.Length; i++) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuse[" + i + "]=" + babylonStandardMaterial.diffuse[i], 3); } if (babylonStandardMaterial.diffuseTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture=null", 3); } else { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture.name=" + babylonStandardMaterial.diffuseTexture.name, 3); } // Normal / bump if (babylonStandardMaterial.bumpTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.bumpTexture=null", 3); } else { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.bumpTexture.name=" + babylonStandardMaterial.bumpTexture.name, 3); } // Opacity if (babylonStandardMaterial.opacityTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.opacityTexture=null", 3); } else { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.opacityTexture.name=" + babylonStandardMaterial.opacityTexture.name, 3); } // Specular for (int i = 0; i < babylonStandardMaterial.specular.Length; i++) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specular[" + i + "]=" + babylonStandardMaterial.specular[i], 3); } logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularPower=" + babylonStandardMaterial.specularPower, 3); if (babylonStandardMaterial.specularTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularTexture=null", 3); } else { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularTexture.name=" + babylonStandardMaterial.specularTexture.name, 3); } // Occlusion if (babylonStandardMaterial.ambientTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambientTexture=null", 3); } else { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambientTexture.name=" + babylonStandardMaterial.ambientTexture.name, 3); } // Emissive for (int i = 0; i < babylonStandardMaterial.emissive.Length; i++) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissive[" + i + "]=" + babylonStandardMaterial.emissive[i], 3); } if (babylonStandardMaterial.emissiveTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture=null", 3); } else { logger.RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture.name=" + babylonStandardMaterial.emissiveTexture.name, 3); } #endregion // -------------------------------- // --------- gltfMaterial --------- // -------------------------------- logger.RaiseMessage("GLTFExporter.Material | create gltfMaterial", 2); gltfMaterial = new GLTFMaterial { name = name }; gltfMaterial.id = babylonMaterial.id; gltfMaterial.index = gltf.MaterialsList.Count; gltf.MaterialsList.Add(gltfMaterial); // Alpha string alphaMode; float? alphaCutoff; getAlphaMode(babylonStandardMaterial, out alphaMode, out alphaCutoff); gltfMaterial.alphaMode = alphaMode; gltfMaterial.alphaCutoff = alphaCutoff; // DoubleSided gltfMaterial.doubleSided = !babylonMaterial.backFaceCulling; // Normal gltfMaterial.normalTexture = ExportTexture(babylonStandardMaterial.bumpTexture, gltf); // Occulison gltfMaterial.occlusionTexture = ExportTexture(babylonStandardMaterial.ambientTexture, gltf); // Emissive gltfMaterial.emissiveFactor = babylonStandardMaterial.emissive; // linkEmissiveWithDiffuse attribute doesn't have an equivalent in gltf format // When true, the emissive texture needs to be manually multiplied with diffuse texture // Otherwise, the emissive texture is assumed to be already pre-multiplied if (babylonStandardMaterial.linkEmissiveWithDiffuse) { // Even when no emissive texture is provided, the self illumination value needs to be multiplied to the diffuse texture in order to get the pre-multiplied emissive (texture) if (babylonStandardMaterial.emissiveTexture != null || babylonStandardMaterial.selfIllum > 0) { // Default emissive is the raw value of the self illumination // It is not the babylon emissive value which is already pre-multiplied with diffuse color float[] defaultEmissive = new float[] { 1, 1, 1 }.Multiply(babylonStandardMaterial.selfIllum); gltfMaterial.emissiveTexture = ExportEmissiveTexture(babylonStandardMaterial, gltf, defaultEmissive, babylonStandardMaterial.diffuse); } } else { gltfMaterial.emissiveTexture = ExportTexture(babylonStandardMaterial.emissiveTexture, gltf); } // Constraints if (gltfMaterial.emissiveTexture != null) { gltfMaterial.emissiveFactor = new[] { 1.0f, 1.0f, 1.0f }; } // -------------------------------- // --- gltfPbrMetallicRoughness --- // -------------------------------- logger.RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2); var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness(); gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness; // --- Global --- // Eye Ball correction to limit overall brightness from std to PBR. // This only impacts the factors. var correctedDiffuse = new BabylonColor3(babylonStandardMaterial.diffuse).scale(0.5f); SpecularGlossiness _specularGlossiness = new SpecularGlossiness { diffuse = correctedDiffuse, opacity = babylonMaterial.alpha, specular = new BabylonColor3(babylonStandardMaterial.specular), glossiness = babylonStandardMaterial.specularPower / 256 }; MetallicRoughness _metallicRoughness = ConvertToMetallicRoughness(_specularGlossiness, true); // Base color gltfPbrMetallicRoughness.baseColorFactor = new float[4] { _metallicRoughness.baseColor.r, _metallicRoughness.baseColor.g, _metallicRoughness.baseColor.b, _metallicRoughness.opacity }; // Metallic roughness gltfPbrMetallicRoughness.metallicFactor = _metallicRoughness.metallic; gltfPbrMetallicRoughness.roughnessFactor = _metallicRoughness.roughness; // --- Textures --- var babylonTexture = babylonStandardMaterial.diffuseTexture != null ? babylonStandardMaterial.diffuseTexture : babylonStandardMaterial.specularTexture != null ? babylonStandardMaterial.specularTexture : babylonStandardMaterial.opacityTexture != null ? babylonStandardMaterial.opacityTexture : null; if (babylonTexture != null) { //Check if the texture already exist var _key = SetStandText(babylonStandardMaterial); if (GetStandTextInfo(_key) != null) { var _pairBCMR = GetStandTextInfo(_key); gltfPbrMetallicRoughness.baseColorTexture = _pairBCMR.baseColor; gltfPbrMetallicRoughness.metallicRoughnessTexture = _pairBCMR.metallicRoughness; } else { bool isAlphaInTexture = (isTextureOk(babylonStandardMaterial.diffuseTexture) && babylonStandardMaterial.diffuseTexture.hasAlpha) || isTextureOk(babylonStandardMaterial.opacityTexture); Bitmap baseColorBitmap = null; Bitmap metallicRoughnessBitmap = null; GLTFTextureInfo textureInfoBC = new GLTFTextureInfo(); GLTFTextureInfo textureInfoMR = new GLTFTextureInfo(); if (exportParameters.writeTextures) { // Diffuse Bitmap diffuseBitmap = null; if (babylonStandardMaterial.diffuseTexture != null) { diffuseBitmap = TextureUtilities.LoadTexture(babylonStandardMaterial.diffuseTexture.originalPath, logger); } // Specular Bitmap specularBitmap = null; if (babylonStandardMaterial.specularTexture != null) { if (babylonStandardMaterial.specularTexture.bitmap != null) { // Specular color map has been computed by the exporter specularBitmap = babylonStandardMaterial.specularTexture.bitmap; } else { // Specular color map is straight input specularBitmap = TextureUtilities.LoadTexture(babylonStandardMaterial.specularTexture.originalPath, logger); } } // Opacity / Alpha / Transparency Bitmap opacityBitmap = null; if ((babylonStandardMaterial.diffuseTexture == null || babylonStandardMaterial.diffuseTexture.hasAlpha == false) && babylonStandardMaterial.opacityTexture != null) { opacityBitmap = TextureUtilities.LoadTexture(babylonStandardMaterial.opacityTexture.originalPath, logger); } if (diffuseBitmap != null || specularBitmap != null || opacityBitmap != null) { // Retreive dimensions int width = 0; int height = 0; var haveSameDimensions = TextureUtilities.GetMinimalBitmapDimensions(out width, out height, diffuseBitmap, specularBitmap, opacityBitmap); if (!haveSameDimensions) { logger.RaiseError("Diffuse, specular and opacity maps should have same dimensions", 2); } // Create baseColor+alpha and metallic+roughness maps baseColorBitmap = new Bitmap(width, height); metallicRoughnessBitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { SpecularGlossiness specularGlossinessTexture = new SpecularGlossiness { diffuse = diffuseBitmap != null ? new BabylonColor3(diffuseBitmap.GetPixel(x, y)) : _specularGlossiness.diffuse, opacity = diffuseBitmap != null && babylonStandardMaterial.diffuseTexture.hasAlpha ? diffuseBitmap.GetPixel(x, y).A / 255.0f : opacityBitmap != null && babylonStandardMaterial.opacityTexture.getAlphaFromRGB ? opacityBitmap.GetPixel(x, y).R / 255.0f : opacityBitmap != null && babylonStandardMaterial.opacityTexture.getAlphaFromRGB == false?opacityBitmap.GetPixel(x, y).A / 255.0f : _specularGlossiness.opacity, specular = specularBitmap != null ? new BabylonColor3(specularBitmap.GetPixel(x, y)) : _specularGlossiness.specular, glossiness = babylonStandardMaterial.useGlossinessFromSpecularMapAlpha && specularBitmap != null?specularBitmap.GetPixel(x, y).A / 255.0f : _specularGlossiness.glossiness }; var displayPrints = x == width / 2 && y == height / 2; MetallicRoughness metallicRoughnessTexture = ConvertToMetallicRoughness(specularGlossinessTexture, displayPrints); Color colorBase = Color.FromArgb( (int)(metallicRoughnessTexture.opacity * 255), (int)(metallicRoughnessTexture.baseColor.r * 255), (int)(metallicRoughnessTexture.baseColor.g * 255), (int)(metallicRoughnessTexture.baseColor.b * 255) ); baseColorBitmap.SetPixel(x, y, colorBase); // The metalness values are sampled from the B channel. // The roughness values are sampled from the G channel. // These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. Color colorMetallicRoughness = Color.FromArgb( 0, (int)(metallicRoughnessTexture.roughness * 255), (int)(metallicRoughnessTexture.metallic * 255) ); metallicRoughnessBitmap.SetPixel(x, y, colorMetallicRoughness); } } } } //export textures if (baseColorBitmap != null || babylonTexture.bitmap != null) { textureInfoBC = ExportBitmapTexture(gltf, babylonTexture, baseColorBitmap); gltfPbrMetallicRoughness.baseColorTexture = textureInfoBC; } if (isTextureOk(babylonStandardMaterial.specularTexture)) { textureInfoMR = ExportBitmapTexture(gltf, babylonTexture, metallicRoughnessBitmap); gltfPbrMetallicRoughness.metallicRoughnessTexture = textureInfoMR; } //register the texture AddStandText(_key, textureInfoBC, textureInfoMR); } // Constraints if (gltfPbrMetallicRoughness.baseColorTexture != null) { gltfPbrMetallicRoughness.baseColorFactor = new[] { 1.0f, 1.0f, 1.0f, 1.0f }; } if (gltfPbrMetallicRoughness.metallicRoughnessTexture != null) { gltfPbrMetallicRoughness.metallicFactor = 1.0f; gltfPbrMetallicRoughness.roughnessFactor = 1.0f; } } } else if (babylonMaterial.GetType() == typeof(BabylonPBRMetallicRoughnessMaterial)) { var babylonPBRMetallicRoughnessMaterial = babylonMaterial as BabylonPBRMetallicRoughnessMaterial; // --- prints --- #region prints logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial data", 2); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.alphaMode=" + babylonMaterial.alphaMode, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3); // Global logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.maxSimultaneousLights=" + babylonPBRMetallicRoughnessMaterial.maxSimultaneousLights, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.disableLighting=" + babylonPBRMetallicRoughnessMaterial.disableLighting, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.alphaCutOff=" + babylonPBRMetallicRoughnessMaterial.alphaCutOff, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.transparencyMode=" + babylonPBRMetallicRoughnessMaterial.transparencyMode, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.doubleSided=" + babylonPBRMetallicRoughnessMaterial.doubleSided, 3); // Base color logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseColor.Length=" + babylonPBRMetallicRoughnessMaterial.baseColor.Length, 3); for (int i = 0; i < babylonPBRMetallicRoughnessMaterial.baseColor.Length; i++) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseColor[" + i + "]=" + babylonPBRMetallicRoughnessMaterial.baseColor[i], 3); } if (babylonPBRMetallicRoughnessMaterial.baseTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseTexture=null", 3); } // Metallic+roughness logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.metallic=" + babylonPBRMetallicRoughnessMaterial.metallic, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.roughness=" + babylonPBRMetallicRoughnessMaterial.roughness, 3); if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture=null", 3); } // Normal / bump if (babylonPBRMetallicRoughnessMaterial.normalTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.normalTexture=null", 3); } logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.invertNormalMapX=" + babylonPBRMetallicRoughnessMaterial.invertNormalMapX, 3); logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.invertNormalMapY=" + babylonPBRMetallicRoughnessMaterial.invertNormalMapY, 3); // Emissive for (int i = 0; i < babylonPBRMetallicRoughnessMaterial.emissive.Length; i++) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.emissiveColor[" + i + "]=" + babylonPBRMetallicRoughnessMaterial.emissive[i], 3); } if (babylonPBRMetallicRoughnessMaterial.emissiveTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.emissiveTexture=null", 3); } // Ambient occlusion logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.occlusionStrength=" + babylonPBRMetallicRoughnessMaterial.occlusionStrength, 3); if (babylonPBRMetallicRoughnessMaterial.occlusionTexture == null) { logger.RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.occlusionTexture=null", 3); } #endregion // -------------------------------- // --------- gltfMaterial --------- // -------------------------------- logger.RaiseMessage("GLTFExporter.Material | create gltfMaterial", 2); gltfMaterial = new GLTFMaterial { name = name }; gltfMaterial.id = babylonMaterial.id; gltfMaterial.index = gltf.MaterialsList.Count; gltf.MaterialsList.Add(gltfMaterial); // Alpha string alphaMode; float? alphaCutoff; getAlphaMode(babylonPBRMetallicRoughnessMaterial, out alphaMode, out alphaCutoff); gltfMaterial.alphaMode = alphaMode; gltfMaterial.alphaCutoff = alphaCutoff; // DoubleSided gltfMaterial.doubleSided = babylonPBRMetallicRoughnessMaterial.doubleSided; // Normal gltfMaterial.normalTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.normalTexture, gltf); // Occlusion if (babylonPBRMetallicRoughnessMaterial.occlusionTexture != null) { if (babylonPBRMetallicRoughnessMaterial.occlusionTexture.bitmap != null) { // ORM texture has been merged manually by the exporter // Occlusion is defined as well as metallic and/or roughness logger.RaiseVerbose("Occlusion is defined as well as metallic and/or roughness", 2); gltfMaterial.occlusionTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.occlusionTexture); } else { // ORM texture was already merged or only occlusion is defined logger.RaiseVerbose("ORM texture was already merged or only occlusion is defined", 2); gltfMaterial.occlusionTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.occlusionTexture, gltf); } } // Emissive gltfMaterial.emissiveFactor = babylonPBRMetallicRoughnessMaterial.emissive; gltfMaterial.emissiveTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.emissiveTexture, gltf); // -------------------------------- // --- gltfPbrMetallicRoughness --- // -------------------------------- logger.RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2); var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness(); gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness; // --- Global --- // Base color gltfPbrMetallicRoughness.baseColorFactor = new float[4] { babylonPBRMetallicRoughnessMaterial.baseColor[0], babylonPBRMetallicRoughnessMaterial.baseColor[1], babylonPBRMetallicRoughnessMaterial.baseColor[2], babylonPBRMetallicRoughnessMaterial.alpha }; if (babylonPBRMetallicRoughnessMaterial.baseTexture != null) { if (babylonPBRMetallicRoughnessMaterial.baseTexture.bitmap != null) { gltfPbrMetallicRoughness.baseColorTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.baseTexture); } else { gltfPbrMetallicRoughness.baseColorTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.baseTexture, gltf); } } // Metallic roughness gltfPbrMetallicRoughness.metallicFactor = babylonPBRMetallicRoughnessMaterial.metallic; gltfPbrMetallicRoughness.roughnessFactor = babylonPBRMetallicRoughnessMaterial.roughness; if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture != null) { if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture == babylonPBRMetallicRoughnessMaterial.occlusionTexture) { // Occlusion is defined as well as metallic and/or roughness // Use same texture logger.RaiseVerbose("Occlusion is defined as well as metallic and/or roughness", 2); gltfPbrMetallicRoughness.metallicRoughnessTexture = gltfMaterial.occlusionTexture; } else { // Occlusion is not defined, only metallic and/or roughness logger.RaiseVerbose("Occlusion is not defined, only metallic and/or roughness", 2); if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture.bitmap != null) { // Metallic & roughness texture has been merged manually by the exporter // Write bitmap file logger.RaiseVerbose("Metallic & roughness texture has been merged manually by the exporter", 2); gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture); } else { // Metallic & roughness texture was already merged // Copy file logger.RaiseVerbose("Metallic & roughness texture was already merged", 2); gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture, gltf); } } } } else { logger.RaiseWarning("GLTFExporter.Material | Unsupported material type: " + babylonMaterial.GetType(), 2); } if (gltfMaterial != null && babylonMaterial.isUnlit) { // Add Unlit extension if (!exportParameters.enableKHRMaterialsUnlit) { logger.RaiseWarning("GLTFExporter.Material | KHR_materials_unlit has not been enabled for export!", 2); } else { if (gltfMaterial.extensions == null) { gltfMaterial.extensions = new GLTFExtensions(); } if (gltf.extensionsUsed == null) { gltf.extensionsUsed = new System.Collections.Generic.List <string>(); } if (!gltf.extensionsUsed.Contains("KHR_materials_unlit")) { gltf.extensionsUsed.Add("KHR_materials_unlit"); } gltfMaterial.extensions["KHR_materials_unlit"] = new object(); } } ExportGLTFExtension(babylonMaterial, ref gltfMaterial, gltf); }
public void RegisterTexture(GLTFTextureInfo TextureInfo, string name) { _DicoTextNameTextureComponent.Add(name, TextureInfo); }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf, string name, Func <string> writeImageFunc) { if (babylonTexture == null) { return(null); } if (name == null) { name = babylonTexture.name; } //Check for texture optimisation if (CheckIfImageIsRegistered(name)) { var TextureComponent = GetRegisteredTexture(name); return(TextureComponent); } RaiseMessage("GLTFExporter.Texture | Export texture named: " + name, 2); string validImageFormat = writeImageFunc.Invoke(); if (validImageFormat == null) { return(null); } name = Path.ChangeExtension(name, validImageFormat); // -------------------------- // -------- Sampler --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create sampler", 3); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; gltf.SamplersList.Add(gltfSampler); // --- Retreive info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); // -------------------------- // --------- Image ---------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create image", 3); GLTFImage gltfImage = new GLTFImage { uri = name }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); switch (validImageFormat) { case "jpg": gltfImage.FileExtension = "jpeg"; break; case "png": gltfImage.FileExtension = "png"; break; } // -------------------------- // -------- Texture --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create texture", 3); var gltfTexture = new GLTFTexture { name = name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; gltf.TexturesList.Add(gltfTexture); // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index, texCoord = babylonTexture.coordinatesIndex }; // Add texture extension if (babylonTexture.uOffset != 0f || babylonTexture.vOffset != 0f || babylonTexture.uScale != 1f || babylonTexture.vScale != 1f || babylonTexture.wAng != 0f) { AddTextureTransformExtension(ref gltf, ref gltfTextureInfo, babylonTexture); } // Add the texture in the dictionary RegisterTexture(gltfTextureInfo, name); return(gltfTextureInfo); }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf, string name, Func <string> writeImageFunc) { if (babylonTexture == null) { return(null); } if (name == null) { name = babylonTexture.name; } RaiseMessage("GLTFExporter.Texture | Export texture named: " + name, 2); string validImageFormat = writeImageFunc.Invoke(); if (validImageFormat == null) { return(null); } name = Path.ChangeExtension(name, validImageFormat); // -------------------------- // -------- Sampler --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create sampler", 3); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; gltf.SamplersList.Add(gltfSampler); // --- Retreive info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); // -------------------------- // --------- Image ---------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create image", 3); GLTFImage gltfImage = new GLTFImage { uri = name }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); switch (validImageFormat) { case "jpg": gltfImage.FileExtension = "jpeg"; break; case "png": gltfImage.FileExtension = "png"; break; } // -------------------------- // -------- Texture --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create texture", 3); var gltfTexture = new GLTFTexture { name = name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; gltf.TexturesList.Add(gltfTexture); // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index }; return(gltfTextureInfo); }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf, string name = null) { if (babylonTexture == null) { return(null); } if (name == null) { name = babylonTexture.name; } RaiseMessage("GLTFExporter.Texture | Export texture named: " + name, 1); // -------------------------- // -------- Sampler --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create sampler", 2); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; gltf.SamplersList.Add(gltfSampler); // --- Retreive info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); // -------------------------- // --------- Image ---------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create image", 2); GLTFImage gltfImage = new GLTFImage { uri = name }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); // -------------------------- // -------- Texture --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create texture", 2); var gltfTexture = new GLTFTexture { name = name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; gltf.TexturesList.Add(gltfTexture); // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index }; // TODO - Animations return(gltfTextureInfo); }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf, string name) { if (babylonTexture == null) { return(null); } if (name == null) { name = babylonTexture.name; } logger.RaiseMessage("GLTFExporter.Texture | Export texture named: " + name, 2); if (glTFTextureInfoMap.ContainsKey(babylonTexture.Id)) { return(glTFTextureInfoMap[babylonTexture.Id]); } else { var sourcePath = babylonTexture.originalPath; if (babylonTexture.bitmap != null) { sourcePath = Path.Combine(gltf.OutputFolder, name); } if (sourcePath == null || sourcePath == "") { logger.RaiseWarning("Texture path is missing.", 3); return(null); } var validImageFormat = TextureUtilities.GetValidImageFormat(Path.GetExtension(sourcePath)); if (validImageFormat == null) { // Image format is not supported by the exporter logger.RaiseWarning(string.Format("Format of texture {0} is not supported by the exporter. Consider using a standard image format like jpg or png.", Path.GetFileName(sourcePath)), 3); return(null); } var destPath = Path.Combine(gltf.OutputFolder, name); destPath = Path.ChangeExtension(destPath, validImageFormat); name = Path.ChangeExtension(name, validImageFormat); // -------------------------- // -------- Sampler --------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create sampler", 3); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; // --- Retrieve info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); var matchingSampler = gltf.SamplersList.FirstOrDefault(sampler => sampler.wrapS == gltfSampler.wrapS && sampler.wrapT == gltfSampler.wrapT && sampler.magFilter == gltfSampler.magFilter && sampler.minFilter == gltfSampler.minFilter); if (matchingSampler != null) { gltfSampler = matchingSampler; } else { gltf.SamplersList.Add(gltfSampler); } // -------------------------- // --------- Image ---------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create image", 3); GLTFImage gltfImage = null; if (glTFImageMap.ContainsKey(name)) { gltfImage = glTFImageMap[name]; } else { string textureUri = name; if (!string.IsNullOrWhiteSpace(exportParameters.textureFolder)) { textureUri = PathUtilities.GetRelativePath(exportParameters.outputPath, exportParameters.textureFolder); textureUri = Path.Combine(textureUri, name); } gltfImage = new GLTFImage { uri = textureUri }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); switch (validImageFormat) { case "jpg": gltfImage.FileExtension = "jpeg"; break; case "png": gltfImage.FileExtension = "png"; break; } if (exportParameters.outputFormat == "glb") { var imageBufferView = WriteImageToGltfBuffer(gltf, gltfImage, sourcePath, babylonTexture.bitmap); gltfImage.uri = null; gltfImage.bufferView = imageBufferView.index; gltfImage.mimeType = "image/" + gltfImage.FileExtension; } else { if (exportParameters.writeTextures) { if (babylonTexture.bitmap != null) { // We may have modified this texture image, copy the buffer contents to disk var extension = Path.GetExtension(name).ToLower(); var imageFormat = extension == ".jpg" ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Png; logger.RaiseMessage($"GLTFExporter.Texture | write image '{name}' to '{destPath}'", 3); TextureUtilities.SaveBitmap(babylonTexture.bitmap, destPath, imageFormat, exportParameters.txtQuality, logger); } else { // Copy texture from source to output TextureUtilities.CopyTexture(sourcePath, destPath, exportParameters.txtQuality, logger); } } } glTFImageMap.Add(name, gltfImage); } // -------------------------- // -------- Texture --------- // -------------------------- logger.RaiseMessage("GLTFExporter.Texture | create texture", 3); var gltfTexture = new GLTFTexture { name = name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; if (!CheckIfImageIsRegistered(name)) { gltf.TexturesList.Add(gltfTexture); } else { gltfTexture = gltf.TexturesList[GetRegisteredTexture(gltfTexture.name).index]; } // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index, texCoord = babylonTexture.coordinatesIndex }; if (!(babylonTexture.uOffset == 0) || !(babylonTexture.vOffset == 0) || !(babylonTexture.uScale == 1) || !(babylonTexture.vScale == 1) || !(babylonTexture.wAng == 0)) { // Add texture extension if enabled in the export settings if (exportParameters.enableKHRTextureTransform) { AddTextureTransformExtension(ref gltf, ref gltfTextureInfo, babylonTexture); } else { logger.RaiseWarning("GLTFExporter.Texture | KHR_texture_transform is not enabled, so the texture may look incorrect at runtime!", 3); logger.RaiseWarning("GLTFExporter.Texture | KHR_texture_transform is not enabled, so the texture may look incorrect at runtime!", 3); } } var textureID = name + TextureTransformID(gltfTextureInfo); // Check for texture optimization. This is done here after the texture transform has been potentially applied to the texture extension if (CheckIfImageIsRegistered(textureID)) { var textureComponent = GetRegisteredTexture(textureID); return(textureComponent); } // Add the texture in the dictionary RegisterTexture(gltfTextureInfo, textureID); glTFTextureInfoMap[babylonTexture.Id] = gltfTextureInfo; return(gltfTextureInfo); } }
private void ExportMaterial(BabylonMaterial babylonMaterial, GLTF gltf) { var name = babylonMaterial.name; var id = babylonMaterial.id; RaiseMessage("GLTFExporter.Material | Export material named: " + name, 1); if (babylonMaterial.GetType() == typeof(BabylonStandardMaterial)) { var babylonStandardMaterial = babylonMaterial as BabylonStandardMaterial; // --- prints --- #region prints RaiseVerbose("GLTFExporter.Material | babylonMaterial data", 2); RaiseVerbose("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3); RaiseVerbose("GLTFExporter.Material | babylonMaterial.alphaMode=" + babylonMaterial.alphaMode, 3); RaiseVerbose("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3); RaiseVerbose("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3); // Ambient for (int i = 0; i < babylonStandardMaterial.ambient.Length; i++) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambient[" + i + "]=" + babylonStandardMaterial.ambient[i], 3); } // Diffuse RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuse.Length=" + babylonStandardMaterial.diffuse.Length, 3); for (int i = 0; i < babylonStandardMaterial.diffuse.Length; i++) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuse[" + i + "]=" + babylonStandardMaterial.diffuse[i], 3); } if (babylonStandardMaterial.diffuseTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture=null", 3); } else { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture.name=" + babylonStandardMaterial.diffuseTexture.name, 3); } // Normal / bump if (babylonStandardMaterial.bumpTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.bumpTexture=null", 3); } else { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.bumpTexture.name=" + babylonStandardMaterial.bumpTexture.name, 3); } // Opacity if (babylonStandardMaterial.opacityTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.opacityTexture=null", 3); } else { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.opacityTexture.name=" + babylonStandardMaterial.opacityTexture.name, 3); } // Specular for (int i = 0; i < babylonStandardMaterial.specular.Length; i++) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specular[" + i + "]=" + babylonStandardMaterial.specular[i], 3); } RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularPower=" + babylonStandardMaterial.specularPower, 3); if (babylonStandardMaterial.specularTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularTexture=null", 3); } else { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.specularTexture.name=" + babylonStandardMaterial.specularTexture.name, 3); } // Occlusion if (babylonStandardMaterial.ambientTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambientTexture=null", 3); } else { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.ambientTexture.name=" + babylonStandardMaterial.ambientTexture.name, 3); } // Emissive for (int i = 0; i < babylonStandardMaterial.emissive.Length; i++) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissive[" + i + "]=" + babylonStandardMaterial.emissive[i], 3); } if (babylonStandardMaterial.emissiveTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture=null", 3); } else { RaiseVerbose("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture.name=" + babylonStandardMaterial.emissiveTexture.name, 3); } #endregion // -------------------------------- // --------- gltfMaterial --------- // -------------------------------- RaiseMessage("GLTFExporter.Material | create gltfMaterial", 2); var gltfMaterial = new GLTFMaterial { name = name }; gltfMaterial.id = babylonMaterial.id; gltfMaterial.index = gltf.MaterialsList.Count; gltf.MaterialsList.Add(gltfMaterial); // Alpha string alphaMode; float? alphaCutoff; getAlphaMode(babylonStandardMaterial, out alphaMode, out alphaCutoff); gltfMaterial.alphaMode = alphaMode; gltfMaterial.alphaCutoff = alphaCutoff; // DoubleSided gltfMaterial.doubleSided = !babylonMaterial.backFaceCulling; // Normal gltfMaterial.normalTexture = ExportTexture(babylonStandardMaterial.bumpTexture, gltf); // Occulison gltfMaterial.occlusionTexture = ExportTexture(babylonStandardMaterial.ambientTexture, gltf); // Emissive gltfMaterial.emissiveFactor = babylonStandardMaterial.emissive.Multiply(babylonStandardMaterial.diffuse); gltfMaterial.emissiveTexture = ExportEmissiveTexture(babylonStandardMaterial, gltf, babylonStandardMaterial.emissive, babylonStandardMaterial.diffuse); // Constraints if (gltfMaterial.emissiveTexture != null) { gltfMaterial.emissiveFactor = new[] { 1.0f, 1.0f, 1.0f }; } // -------------------------------- // --- gltfPbrMetallicRoughness --- // -------------------------------- RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2); var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness(); gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness; // --- Global --- // Eye Ball correction to limit overall brightness from std to PBR. // This only impacts the factors. var correctedDiffuse = new BabylonColor3(babylonStandardMaterial.diffuse).scale(0.5f); SpecularGlossiness _specularGlossiness = new SpecularGlossiness { diffuse = correctedDiffuse, opacity = babylonMaterial.alpha, specular = new BabylonColor3(babylonStandardMaterial.specular), glossiness = babylonStandardMaterial.specularPower / 256 }; MetallicRoughness _metallicRoughness = ConvertToMetallicRoughness(_specularGlossiness, true); // Base color gltfPbrMetallicRoughness.baseColorFactor = new float[4] { _metallicRoughness.baseColor.r, _metallicRoughness.baseColor.g, _metallicRoughness.baseColor.b, _metallicRoughness.opacity }; // Metallic roughness gltfPbrMetallicRoughness.metallicFactor = _metallicRoughness.metallic; gltfPbrMetallicRoughness.roughnessFactor = _metallicRoughness.roughness; // --- Textures --- var babylonTexture = babylonStandardMaterial.diffuseTexture != null ? babylonStandardMaterial.diffuseTexture : babylonStandardMaterial.specularTexture != null ? babylonStandardMaterial.specularTexture : babylonStandardMaterial.opacityTexture != null ? babylonStandardMaterial.opacityTexture : null; if (babylonTexture != null) { //Check if the texture already exist var _key = SetStandText(babylonStandardMaterial); if (GetStandTextInfo(_key) != null) { var _pairBCMR = GetStandTextInfo(_key); gltfPbrMetallicRoughness.baseColorTexture = _pairBCMR.baseColor; gltfPbrMetallicRoughness.metallicRoughnessTexture = _pairBCMR.metallicRoughness; } else { bool isAlphaInTexture = (isTextureOk(babylonStandardMaterial.diffuseTexture) && babylonStandardMaterial.diffuseTexture.hasAlpha) || isTextureOk(babylonStandardMaterial.opacityTexture); Bitmap baseColorBitmap = null; Bitmap metallicRoughnessBitmap = null; GLTFTextureInfo textureInfoBC = new GLTFTextureInfo(); GLTFTextureInfo textureInfoMR = new GLTFTextureInfo(); if (CopyTexturesToOutput) { // Diffuse Bitmap diffuseBitmap = null; if (babylonStandardMaterial.diffuseTexture != null) { diffuseBitmap = LoadTexture(babylonStandardMaterial.diffuseTexture.originalPath); } // Specular Bitmap specularBitmap = null; if (babylonStandardMaterial.specularTexture != null) { specularBitmap = LoadTexture(babylonStandardMaterial.specularTexture.originalPath); } // Opacity / Alpha / Transparency Bitmap opacityBitmap = null; if ((babylonStandardMaterial.diffuseTexture == null || babylonStandardMaterial.diffuseTexture.hasAlpha == false) && babylonStandardMaterial.opacityTexture != null) { opacityBitmap = LoadTexture(babylonStandardMaterial.opacityTexture.originalPath); } if (diffuseBitmap != null || specularBitmap != null || opacityBitmap != null) { // Retrieve dimensions int width = 0; int height = 0; var haveSameDimensions = _getMinimalBitmapDimensions(out width, out height, diffuseBitmap, specularBitmap, opacityBitmap); if (!haveSameDimensions) { RaiseError("Diffuse, specular and opacity maps should have same dimensions", 2); } // Create baseColor+alpha and metallic+roughness maps baseColorBitmap = new Bitmap(width, height); metallicRoughnessBitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { SpecularGlossiness specularGlossinessTexture = new SpecularGlossiness { diffuse = diffuseBitmap != null ? new BabylonColor3(diffuseBitmap.GetPixel(x, y)) : _specularGlossiness.diffuse, opacity = diffuseBitmap != null && babylonStandardMaterial.diffuseTexture.hasAlpha ? diffuseBitmap.GetPixel(x, y).A / 255.0f : opacityBitmap != null && babylonStandardMaterial.opacityTexture.getAlphaFromRGB ? opacityBitmap.GetPixel(x, y).R / 255.0f : opacityBitmap != null && babylonStandardMaterial.opacityTexture.getAlphaFromRGB == false?opacityBitmap.GetPixel(x, y).A / 255.0f : _specularGlossiness.opacity, specular = specularBitmap != null ? new BabylonColor3(specularBitmap.GetPixel(x, y)) : _specularGlossiness.specular, glossiness = babylonStandardMaterial.useGlossinessFromSpecularMapAlpha && specularBitmap != null?specularBitmap.GetPixel(x, y).A / 255.0f : _specularGlossiness.glossiness }; var displayPrints = x == width / 2 && y == height / 2; MetallicRoughness metallicRoughnessTexture = ConvertToMetallicRoughness(specularGlossinessTexture, displayPrints); Color colorBase = Color.FromArgb( (int)(metallicRoughnessTexture.opacity * 255), (int)(metallicRoughnessTexture.baseColor.r * 255), (int)(metallicRoughnessTexture.baseColor.g * 255), (int)(metallicRoughnessTexture.baseColor.b * 255) ); baseColorBitmap.SetPixel(x, y, colorBase); // The metalness values are sampled from the B channel. // The roughness values are sampled from the G channel. // These values are linear. If other channels are present (R or A), they are ignored for metallic-roughness calculations. Color colorMetallicRoughness = Color.FromArgb( 0, (int)(metallicRoughnessTexture.roughness * 255), (int)(metallicRoughnessTexture.metallic * 255) ); metallicRoughnessBitmap.SetPixel(x, y, colorMetallicRoughness); } } } } if (baseColorBitmap != null || babylonTexture.bitmap != null) { var baseColorFileName = babylonMaterial.name + "_baseColor" + (isAlphaInTexture ? ".png" : ".jpg"); textureInfoBC = ExportBitmapTexture(gltf, babylonTexture, baseColorBitmap, baseColorFileName); gltfPbrMetallicRoughness.baseColorTexture = textureInfoBC; } if (isTextureOk(babylonStandardMaterial.specularTexture)) { textureInfoMR = ExportBitmapTexture(gltf, babylonTexture, metallicRoughnessBitmap, babylonMaterial.name + "_metallicRoughness" + ".jpg"); gltfPbrMetallicRoughness.metallicRoughnessTexture = textureInfoMR; } //register the texture AddStandText(_key, textureInfoBC, textureInfoMR); } // Constraints if (gltfPbrMetallicRoughness.baseColorTexture != null) { gltfPbrMetallicRoughness.baseColorFactor = new[] { 1.0f, 1.0f, 1.0f, 1.0f }; } if (gltfPbrMetallicRoughness.metallicRoughnessTexture != null) { gltfPbrMetallicRoughness.metallicFactor = 1.0f; gltfPbrMetallicRoughness.roughnessFactor = 1.0f; } } } else if (babylonMaterial.GetType() == typeof(BabylonPBRMetallicRoughnessMaterial)) { var babylonPBRMetallicRoughnessMaterial = babylonMaterial as BabylonPBRMetallicRoughnessMaterial; // --- prints --- #region prints RaiseVerbose("GLTFExporter.Material | babylonMaterial data", 2); RaiseVerbose("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3); RaiseVerbose("GLTFExporter.Material | babylonMaterial.alphaMode=" + babylonMaterial.alphaMode, 3); RaiseVerbose("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3); RaiseVerbose("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3); // Global RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.maxSimultaneousLights=" + babylonPBRMetallicRoughnessMaterial.maxSimultaneousLights, 3); RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.disableLighting=" + babylonPBRMetallicRoughnessMaterial.disableLighting, 3); RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.alphaCutOff=" + babylonPBRMetallicRoughnessMaterial.alphaCutOff, 3); RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.transparencyMode=" + babylonPBRMetallicRoughnessMaterial.transparencyMode, 3); RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.doubleSided=" + babylonPBRMetallicRoughnessMaterial.doubleSided, 3); // Base color RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseColor.Length=" + babylonPBRMetallicRoughnessMaterial.baseColor.Length, 3); for (int i = 0; i < babylonPBRMetallicRoughnessMaterial.baseColor.Length; i++) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseColor[" + i + "]=" + babylonPBRMetallicRoughnessMaterial.baseColor[i], 3); } if (babylonPBRMetallicRoughnessMaterial.baseTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.baseTexture=null", 3); } // Metallic+roughness RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.metallic=" + babylonPBRMetallicRoughnessMaterial.metallic, 3); RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.roughness=" + babylonPBRMetallicRoughnessMaterial.roughness, 3); if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture=null", 3); } // Normal / bump if (babylonPBRMetallicRoughnessMaterial.normalTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.normalTexture=null", 3); } RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.invertNormalMapX=" + babylonPBRMetallicRoughnessMaterial.invertNormalMapX, 3); RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.invertNormalMapY=" + babylonPBRMetallicRoughnessMaterial.invertNormalMapY, 3); // Emissive for (int i = 0; i < babylonPBRMetallicRoughnessMaterial.emissive.Length; i++) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.emissiveColor[" + i + "]=" + babylonPBRMetallicRoughnessMaterial.emissive[i], 3); } if (babylonPBRMetallicRoughnessMaterial.emissiveTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.emissiveTexture=null", 3); } // Ambient occlusion RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.occlusionStrength=" + babylonPBRMetallicRoughnessMaterial.occlusionStrength, 3); if (babylonPBRMetallicRoughnessMaterial.occlusionTexture == null) { RaiseVerbose("GLTFExporter.Material | babylonPBRMetallicRoughnessMaterial.occlusionTexture=null", 3); } #endregion // -------------------------------- // --------- gltfMaterial --------- // -------------------------------- RaiseMessage("GLTFExporter.Material | create gltfMaterial", 2); var gltfMaterial = new GLTFMaterial { name = name }; gltfMaterial.id = babylonMaterial.id; gltfMaterial.index = gltf.MaterialsList.Count; gltf.MaterialsList.Add(gltfMaterial); // Alpha string alphaMode; float? alphaCutoff; getAlphaMode(babylonPBRMetallicRoughnessMaterial, out alphaMode, out alphaCutoff); gltfMaterial.alphaMode = alphaMode; gltfMaterial.alphaCutoff = alphaCutoff; // DoubleSided gltfMaterial.doubleSided = babylonPBRMetallicRoughnessMaterial.doubleSided; // Normal gltfMaterial.normalTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.normalTexture, gltf); // Occlusion if (babylonPBRMetallicRoughnessMaterial.occlusionTexture != null) { if (babylonPBRMetallicRoughnessMaterial.occlusionTexture.bitmap != null) { // ORM texture has been merged manually by the exporter // Occlusion is defined as well as metallic and/or roughness RaiseVerbose("Occlusion is defined as well as metallic and/or roughness", 2); gltfMaterial.occlusionTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.occlusionTexture); } else { // ORM texture was already merged or only occlusion is defined RaiseVerbose("ORM texture was already merged or only occlusion is defined", 2); gltfMaterial.occlusionTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.occlusionTexture, gltf); } } // Emissive gltfMaterial.emissiveFactor = babylonPBRMetallicRoughnessMaterial.emissive; gltfMaterial.emissiveTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.emissiveTexture, gltf); // -------------------------------- // --- gltfPbrMetallicRoughness --- // -------------------------------- RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2); var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness(); gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness; // --- Global --- // Base color gltfPbrMetallicRoughness.baseColorFactor = new float[4] { babylonPBRMetallicRoughnessMaterial.baseColor[0], babylonPBRMetallicRoughnessMaterial.baseColor[1], babylonPBRMetallicRoughnessMaterial.baseColor[2], babylonPBRMetallicRoughnessMaterial.alpha }; if (babylonPBRMetallicRoughnessMaterial.baseTexture != null) { if (babylonPBRMetallicRoughnessMaterial.baseTexture.bitmap != null) { // Base color & Alpha texture has been merged manually by the exporter // Write bitmap file gltfPbrMetallicRoughness.baseColorTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.baseTexture); } else { // Base color & Alpha texture was already merged // Copy file gltfPbrMetallicRoughness.baseColorTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.baseTexture, gltf); } } // Metallic roughness gltfPbrMetallicRoughness.metallicFactor = babylonPBRMetallicRoughnessMaterial.metallic; gltfPbrMetallicRoughness.roughnessFactor = babylonPBRMetallicRoughnessMaterial.roughness; if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture != null) { if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture == babylonPBRMetallicRoughnessMaterial.occlusionTexture) { // Occlusion is defined as well as metallic and/or roughness // Use same texture RaiseVerbose("Occlusion is defined as well as metallic and/or roughness", 2); gltfPbrMetallicRoughness.metallicRoughnessTexture = gltfMaterial.occlusionTexture; } else { // Occlusion is not defined, only metallic and/or roughness RaiseVerbose("Occlusion is not defined, only metallic and/or roughness", 2); if (babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture.bitmap != null) { // Metallic & roughness texture has been merged manually by the exporter // Write bitmap file RaiseVerbose("Metallic & roughness texture has been merged manually by the exporter", 2); gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture); } else { // Metallic & roughness texture was already merged // Copy file RaiseVerbose("Metallic & roughness texture was already merged", 2); gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture, gltf); } } } } else { RaiseWarning("GLTFExporter.Material | Unsupported material type: " + babylonMaterial.GetType(), 2); } }
private static int[] DeconstructMaterials(PokemonModel pokemonModel, GLTFRoot gltfRoot) { var materials = new int[pokemonModel.MaterialsLength]; for (var i = 0; i < pokemonModel.MaterialsLength; ++i) { var material = pokemonModel.Materials(i).GetValueOrDefault(); var gltfMaterial = new GLTFMaterial { PbrMetallicRoughness = new GLTFPBRMetallicRoughness(), Name = material.Name, AlphaMode = GLTFAlphaMode.BLEND }; for (var j = 0; j < material.TexturesLength; ++j) { var texture = material.Textures(j).GetValueOrDefault(); var textureName = $"{pokemonModel.Textures(texture.Id)}.png"; var mapping = texture.Mapping.GetValueOrDefault(); var textureInfo = new GLTFTextureInfo { Index = FindOrCreateTexture(gltfRoot, textureName, mapping) }; switch (texture.Channel) { case "Col0Tex": gltfMaterial.PbrMetallicRoughness.BaseColorTexture = textureInfo; break; case "EmissionMaskTex": gltfMaterial.EmissiveTexture = textureInfo; gltfMaterial.EmissiveFactor = new Vector3(1, 1, 1); ; break; case "AmbientTex": gltfMaterial.OcclusionTexture = textureInfo; break; case "NormalMapTex": gltfMaterial.NormalTexture = textureInfo; break; } } var colorUVScale = new Vector2(1, 1); var colorUVTransation = new Vector2(); var normalUVScale = new Vector2(); for (var j = 0; j < material.ValuesLength; ++j) { var value = material.Values(j).GetValueOrDefault(); if (string.IsNullOrWhiteSpace(value.Name)) { continue; } switch (value.Name) { case "ColorUVScaleU": colorUVScale.X = value.Value; break; case "ColorUVScaleV": colorUVScale.Y = value.Value; break; case "ColorUVTranslateU": colorUVTransation.X += value.Value; break; case "ColorUVTranslateV": colorUVTransation.Y += value.Value; break; case "ColorBaseU": colorUVTransation.X += value.Value; break; case "ColorBaseY": colorUVTransation.Y += value.Value; break; case "NormalMapUVScaleU": normalUVScale.X += value.Value; break; case "NormalMapUVScaleV": normalUVScale.Y += value.Value; break; } } var colorTransform = new KHRTextureTransform { Offset = colorUVTransation, Scale = colorUVScale }; var normalTransform = new KHRTextureTransform { Offset = normalUVScale }; //colorTransform.Insert(gltfMaterial.OcclusionTexture, gltfRoot); colorTransform.Insert(gltfMaterial.PbrMetallicRoughness.MetallicRoughnessTexture, gltfRoot); //colorTransform.Insert(gltfMaterial.EmissiveTexture, gltfRoot); normalTransform.Insert(gltfMaterial.NormalTexture, gltfRoot); materials[i] = gltfRoot.Materials.Count; gltfRoot.Materials.Add(gltfMaterial); } return(materials); }
private GLTFTextureInfo ExportTexture(BabylonTexture babylonTexture, GLTF gltf) { if (babylonTexture == null) { return(null); } RaiseMessage("GLTFExporter.Texture | ExportTexture babylonTexture.name=" + babylonTexture.name, 1); // -------------------------- // -------- Sampler --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create sampler", 1); GLTFSampler gltfSampler = new GLTFSampler(); gltfSampler.index = gltf.SamplersList.Count; gltf.SamplersList.Add(gltfSampler); // --- Retreive info from babylon texture --- // Mag and min filters GLTFSampler.TextureMagFilter?magFilter; GLTFSampler.TextureMinFilter?minFilter; getSamplingParameters(babylonTexture.samplingMode, out magFilter, out minFilter); gltfSampler.magFilter = magFilter; gltfSampler.minFilter = minFilter; // WrapS and wrapT gltfSampler.wrapS = getWrapMode(babylonTexture.wrapU); gltfSampler.wrapT = getWrapMode(babylonTexture.wrapV); // -------------------------- // --------- Image ---------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create image", 1); GLTFImage gltfImage = new GLTFImage { uri = babylonTexture.name }; gltfImage.index = gltf.ImagesList.Count; gltf.ImagesList.Add(gltfImage); // -------------------------- // -------- Texture --------- // -------------------------- RaiseMessage("GLTFExporter.Texture | create texture", 1); var gltfTexture = new GLTFTexture { name = babylonTexture.name, sampler = gltfSampler.index, source = gltfImage.index }; gltfTexture.index = gltf.TexturesList.Count; gltf.TexturesList.Add(gltfTexture); // -------------------------- // ------ TextureInfo ------- // -------------------------- var gltfTextureInfo = new GLTFTextureInfo { index = gltfTexture.index }; // TODO - Animations //// Copy image to output //var absolutePath = texture.Map.FullFilePath; //try //{ // if (File.Exists(absolutePath)) // { // if (CopyTexturesToOutput) // { // RaiseMessage("GLTFExporter.Texture | copy image src path = "+ absolutePath + " and dest path = "+ Path.Combine(gltf.OutputPath, gltfTexture.name)); // File.Copy(absolutePath, Path.Combine(gltf.OutputPath, gltfTexture.name), true); // } // } // else // { // RaiseWarning(string.Format("Texture {0} not found.", gltfTexture.name), 2); // } //} //catch //{ // // silently fails //} return(gltfTextureInfo); }