private void ExportMaterial(BabylonMaterial babylonMaterial, GLTF gltf) { var name = babylonMaterial.name; var id = babylonMaterial.id; RaiseMessage("GLTFExporter.Material | Export material named: " + name, 1); GLTFMaterial gltfMaterial = null; 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); 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 --- // -------------------------------- RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2); var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness(); gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness; // --- Global --- SpecularGlossiness _specularGlossiness = new SpecularGlossiness { diffuse = new BabylonColor3(babylonStandardMaterial.diffuse), 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 = LoadTexture(babylonStandardMaterial.diffuseTexture.originalPath); } // 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 = 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) { // Retreive 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); } } } } //export textures var baseColorFileName = babylonMaterial.name + "_baseColor" + (isAlphaInTexture ? ".png" : ".jpg"); textureInfoBC = ExportBitmapTexture(gltf, babylonTexture, baseColorBitmap, baseColorFileName); gltfPbrMetallicRoughness.baseColorTexture = textureInfoBC; // If no specular map is defined, the metallic and roughness values are be driven by the global parameters if (babylonStandardMaterial.specularTexture != null) { 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); 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); // Occulison 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) { 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 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); } if (gltfMaterial != null && babylonMaterial.isUnlit) { // Add Unlit extension if (!exportParameters.enableKHRMaterialsUnlit) { 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(); } } }
private BabylonMaterial ExportMaterialAnimations(BabylonMaterial babylonMaterial, IIGameMaterial material, BabylonExporter exporter) { var animations = new List <BabylonAnimation>(); int numProps = material.IPropertyContainer.NumberOfProperties; for (int i = 0; i < numProps; ++i) { IIGameProperty property = material.IPropertyContainer.GetProperty(i); if (property == null) { continue; } if (!property.IsPropAnimated) { continue; } IParamDef paramDef = property.MaxParamBlock2?.GetParamDef(property.ParamID); string propertyName = property.Name.ToUpperInvariant(); switch (propertyName) { case "BASECOLOR": { if (property.IGameControl.GetMaxControl(IGameControlType.Point4).NumKeys > 0) { exporter.ExportColor4Animation(property.Name, animations, key => material.IPropertyContainer.GetPoint4Property(property.Name, key).ToArray()); } break; } case "EMISSIVE": { if (property.IGameControl.GetMaxControl(IGameControlType.Point3).NumKeys > 0) { exporter.ExportColor3Animation(property.Name, animations, key => material.IPropertyContainer.GetPoint3Property(property.Name, key).ToArray()); } break; } case "WIPERANIMSTATE1": case "WIPERANIMSTATE2": case "WIPERANIMSTATE3": case "WIPERANIMSTATE4": case "METALLIC": case "ROUGHNESS": case "UVOFFSETU": case "UVOFFSETV": case "UVTILINGU": case "UVTILINGV": case "UVROTATION": { if (property.IGameControl.GetMaxControl(IGameControlType.Float).NumKeys > 0) { exporter.ExportFloatAnimation(property.Name, animations, key => new[] { material.IPropertyContainer.GetFloatProperty(property.Name, key, 0) }); } break; } default: break; } } babylonMaterial.animations = animations.ToArray(); return(babylonMaterial); }
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; gltfMaterial.emissiveTexture = ExportTexture(babylonStandardMaterial.emissiveTexture, gltf); // 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 --- SpecularGlossiness _specularGlossiness = new SpecularGlossiness { diffuse = new BabylonColor3(babylonStandardMaterial.diffuse), 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) { bool isAlphaInTexture = (isTextureOk(babylonStandardMaterial.diffuseTexture) && babylonStandardMaterial.diffuseTexture.hasAlpha) || isTextureOk(babylonStandardMaterial.opacityTexture); Bitmap baseColorBitmap = null; Bitmap metallicRoughnessBitmap = null; 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) { // Retreive dimensions int width = 0; int height = 0; var haveSameDimensions = _getMinimalBitmapDimensions(out width, out height, diffuseBitmap, specularBitmap, opacityBitmap); if (!haveSameDimensions) { RaiseWarning("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 maps and textures var baseColorFileName = babylonMaterial.name + "_baseColor" + (isAlphaInTexture ? ".png" : ".jpg"); gltfPbrMetallicRoughness.baseColorTexture = ExportBitmapTexture(gltf, babylonTexture, baseColorBitmap, baseColorFileName); if (isTextureOk(babylonStandardMaterial.specularTexture)) { gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportBitmapTexture(gltf, babylonTexture, metallicRoughnessBitmap, babylonMaterial.name + "_metallicRoughness" + ".jpg"); } // 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); // Occulison 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 }; gltfPbrMetallicRoughness.baseColorTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.baseTexture); // Metallic roughness gltfPbrMetallicRoughness.metallicFactor = babylonPBRMetallicRoughnessMaterial.metallic; gltfPbrMetallicRoughness.roughnessFactor = babylonPBRMetallicRoughnessMaterial.roughness; gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportBitmapTexture(gltf, babylonPBRMetallicRoughnessMaterial.metallicRoughnessTexture); } else { RaiseWarning("GLTFExporter.Material | Unsupported material type: " + babylonMaterial.GetType(), 2); } }
private void ExportMaterial(IIGameMaterial materialNode, BabylonScene babylonScene) { var name = materialNode.MaterialName; var id = materialNode.MaxMaterial.GetGuid().ToString(); // Check if the material was already exported. The material id is unique. if (babylonScene.MaterialsList.FirstOrDefault(m => m.id == id) != null) { return; } RaiseMessage(name, 1); // --- prints --- #region prints { RaiseVerbose("materialNode.MaterialClass=" + materialNode.MaterialClass, 2); RaiseVerbose("materialNode.NumberOfTextureMaps=" + materialNode.NumberOfTextureMaps, 2); var propertyContainer = materialNode.IPropertyContainer; RaiseVerbose("propertyContainer=" + propertyContainer, 2); if (propertyContainer != null) { RaiseVerbose("propertyContainer.NumberOfProperties=" + propertyContainer.NumberOfProperties, 3); for (int i = 0; i < propertyContainer.NumberOfProperties; i++) { var prop = propertyContainer.GetProperty(i); if (prop != null) { RaiseVerbose("propertyContainer.GetProperty(" + i + ")=" + prop.Name, 3); switch (prop.GetType_) { case PropType.StringProp: string propertyString = ""; RaiseVerbose("prop.GetPropertyValue(ref propertyString, 0)=" + prop.GetPropertyValue(ref propertyString, 0), 4); RaiseVerbose("propertyString=" + propertyString, 4); break; case PropType.IntProp: int propertyInt = 0; RaiseVerbose("prop.GetPropertyValue(ref propertyInt, 0)=" + prop.GetPropertyValue(ref propertyInt, 0), 4); RaiseVerbose("propertyInt=" + propertyInt, 4); break; case PropType.FloatProp: float propertyFloat = 0; RaiseVerbose("prop.GetPropertyValue(ref propertyFloat, 0, true)=" + prop.GetPropertyValue(ref propertyFloat, 0, true), 4); RaiseVerbose("propertyFloat=" + propertyFloat, 4); RaiseVerbose("prop.GetPropertyValue(ref propertyFloat, 0, false)=" + prop.GetPropertyValue(ref propertyFloat, 0, false), 4); RaiseVerbose("propertyFloat=" + propertyFloat, 4); break; case PropType.Point3Prop: IPoint3 propertyPoint3 = Loader.Global.Point3.Create(0, 0, 0); RaiseVerbose("prop.GetPropertyValue(ref propertyPoint3, 0)=" + prop.GetPropertyValue(propertyPoint3, 0), 4); RaiseVerbose("propertyPoint3=" + Point3ToString(propertyPoint3), 4); break; case PropType.Point4Prop: IPoint4 propertyPoint4 = Loader.Global.Point4.Create(0, 0, 0, 0); RaiseVerbose("prop.GetPropertyValue(ref propertyPoint4, 0)=" + prop.GetPropertyValue(propertyPoint4, 0), 4); RaiseVerbose("propertyPoint4=" + Point4ToString(propertyPoint4), 4); break; case PropType.UnknownProp: default: RaiseVerbose("Unknown property type", 4); break; } } else { RaiseVerbose("propertyContainer.GetProperty(" + i + ") IS NULL", 3); } } } } #endregion if (materialNode.SubMaterialCount > 0) { var babylonMultimaterial = new BabylonMultiMaterial { name = name, id = id }; var guids = new List <string>(); for (var index = 0; index < materialNode.SubMaterialCount; index++) { var subMat = materialNode.GetSubMaterial(index); if (subMat != null) { if (subMat.SubMaterialCount > 0) { RaiseError("MultiMaterials as inputs to other MultiMaterials are not supported!"); } else { guids.Add(subMat.MaxMaterial.GetGuid().ToString()); if (!referencedMaterials.Contains(subMat)) { referencedMaterials.Add(subMat); ExportMaterial(subMat, babylonScene); } } } else { guids.Add(Guid.Empty.ToString()); } } babylonMultimaterial.materials = guids.ToArray(); babylonScene.MultiMaterialsList.Add(babylonMultimaterial); return; } var unlitProperty = materialNode.IPropertyContainer.QueryProperty("BabylonUnlit"); bool isUnlit = unlitProperty != null?unlitProperty.GetBoolValue() : false; // check custom exporters first, to allow custom exporters of supported material classes materialExporters.TryGetValue(new ClassIDWrapper(materialNode.MaxMaterial.ClassID), out IMaterialExporter materialExporter); var stdMat = materialNode.MaxMaterial.NumParamBlocks > 0 ? materialNode.MaxMaterial.GetParamBlock(0).Owner as IStdMat2 : null; if (isBabylonExported && materialExporter != null && materialExporter is IBabylonMaterialExporter) { IBabylonMaterialExporter babylonMaterialExporter = materialExporter as IBabylonMaterialExporter; BabylonMaterial babylonMaterial = babylonMaterialExporter.ExportBabylonMaterial(materialNode); if (babylonMaterial == null) { string message = string.Format("Custom Babylon material exporter failed to export | Exporter: '{0}' | Material Name: '{1}' | Material Class: '{2}'", babylonMaterialExporter.GetType().ToString(), materialNode.MaterialName, materialNode.MaterialClass); RaiseWarning(message, 2); } else { babylonScene.MaterialsList.Add(babylonMaterial); } } else if (isGltfExported && materialExporter != null && materialExporter is IGLTFMaterialExporter) { // add a basic babylon material to the list to forward the max material reference var babylonMaterial = new BabylonMaterial(id) { maxGameMaterial = materialNode, name = name }; babylonScene.MaterialsList.Add(babylonMaterial); } else if (stdMat != null) { var babylonMaterial = new BabylonStandardMaterial(id) { maxGameMaterial = materialNode, name = name, isUnlit = isUnlit, diffuse = materialNode.MaxMaterial.GetDiffuse(0, false).ToArray(), alpha = 1.0f - materialNode.MaxMaterial.GetXParency(0, false) }; babylonMaterial.backFaceCulling = !stdMat.TwoSided; babylonMaterial.wireframe = stdMat.Wire; var isSelfIllumColor = materialNode.MaxMaterial.GetSelfIllumColorOn(0, false); var maxSpecularColor = materialNode.MaxMaterial.GetSpecular(0, false).ToArray(); if (isUnlit == false) { babylonMaterial.ambient = materialNode.MaxMaterial.GetAmbient(0, false).ToArray(); babylonMaterial.specular = maxSpecularColor.Multiply(materialNode.MaxMaterial.GetShinStr(0, false)); babylonMaterial.specularPower = materialNode.MaxMaterial.GetShininess(0, false) * 256; babylonMaterial.emissive = isSelfIllumColor ? materialNode.MaxMaterial.GetSelfIllumColor(0, false).ToArray() : materialNode.MaxMaterial.GetDiffuse(0, false).Scale(materialNode.MaxMaterial.GetSelfIllum(0, false)); // compute the pre-multiplied emissive color // If Self-Illumination color checkbox is checked // Then self-illumination is assumed to be pre-multiplied // Otherwise self-illumination needs to be multiplied with diffuse // linkEmissiveWithDiffuse attribute tells the Babylon engine to perform such multiplication babylonMaterial.linkEmissiveWithDiffuse = !isSelfIllumColor; // useEmissiveAsIllumination attribute tells the Babylon engine to use pre-multiplied emissive as illumination babylonMaterial.useEmissiveAsIllumination = isSelfIllumColor; // Store the emissive value (before multiplication) for gltf babylonMaterial.selfIllum = materialNode.MaxMaterial.GetSelfIllum(0, false); } // Textures BabylonFresnelParameters fresnelParameters; babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, out fresnelParameters, babylonScene); // Diffuse if (fresnelParameters != null) { babylonMaterial.diffuseFresnelParameters = fresnelParameters; } if ((babylonMaterial.alpha == 1.0f && babylonMaterial.opacityTexture == null) && babylonMaterial.diffuseTexture != null && (babylonMaterial.diffuseTexture.originalPath.EndsWith(".tif") || babylonMaterial.diffuseTexture.originalPath.EndsWith(".tiff")) && babylonMaterial.diffuseTexture.hasAlpha) { RaiseWarning($"Diffuse texture named {babylonMaterial.diffuseTexture.originalPath} is a .tif file and its Alpha Source is 'Image Alpha' by default.", 2); RaiseWarning($"If you don't want material to be in BLEND mode, set diffuse texture Alpha Source to 'None (Opaque)'", 2); } babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, out fresnelParameters, babylonScene, false, true); // Opacity if (fresnelParameters != null) { babylonMaterial.opacityFresnelParameters = fresnelParameters; if (babylonMaterial.alpha == 1 && babylonMaterial.opacityTexture == null) { babylonMaterial.alpha = 0; } } if (isUnlit == false) { babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, out fresnelParameters, babylonScene); // Ambient babylonMaterial.specularTexture = ExportSpecularTexture(materialNode, maxSpecularColor, babylonScene); babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, out fresnelParameters, babylonScene); // Emissive if (fresnelParameters != null) { babylonMaterial.emissiveFresnelParameters = fresnelParameters; if (babylonMaterial.emissive[0] == 0 && babylonMaterial.emissive[1] == 0 && babylonMaterial.emissive[2] == 0 && babylonMaterial.emissiveTexture == null) { babylonMaterial.emissive = new float[] { 1, 1, 1 }; } } babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, out fresnelParameters, babylonScene); // Bump babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, out fresnelParameters, babylonScene, true); // Reflection if (fresnelParameters != null) { if (babylonMaterial.reflectionTexture == null) { RaiseWarning("Fallout cannot be used with reflection channel without a texture", 2); } else { babylonMaterial.reflectionFresnelParameters = fresnelParameters; } } } // Constraints if (babylonMaterial.diffuseTexture != null) { babylonMaterial.diffuse = new[] { 1.0f, 1.0f, 1.0f }; } if (babylonMaterial.emissiveTexture != null) { babylonMaterial.emissive = new float[] { 0, 0, 0 }; } if (babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture != null && babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name && babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB) { // This is a alpha testing purpose babylonMaterial.opacityTexture = null; babylonMaterial.diffuseTexture.hasAlpha = true; RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", 2); RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", 2); } babylonScene.MaterialsList.Add(babylonMaterial); } else if (isPhysicalMaterial(materialNode)) { var propertyContainer = materialNode.IPropertyContainer; var babylonMaterial = new BabylonPBRMetallicRoughnessMaterial(id) { maxGameMaterial = materialNode, name = name, isUnlit = isUnlit }; // --- Global --- // Alpha //var alphaFromXParency = 1.0f - materialNode.MaxMaterial.GetXParency(0, false); var alphaFromPropertyContainer = 1.0f - propertyContainer.GetFloatProperty(17); //RaiseMessage("alphaFromXParency=" + alphaFromXParency, 2); //RaiseMessage("alphaFromPropertyContainer=" + alphaFromPropertyContainer, 2); babylonMaterial.alpha = alphaFromPropertyContainer; babylonMaterial.baseColor = materialNode.MaxMaterial.GetDiffuse(0, false).ToArray(); var invertRoughness = propertyContainer.GetBoolProperty(5); if (isUnlit == false) { babylonMaterial.metallic = propertyContainer.GetFloatProperty(6); babylonMaterial.roughness = propertyContainer.GetFloatProperty(4); if (invertRoughness) { // Inverse roughness babylonMaterial.roughness = 1 - babylonMaterial.roughness; } // Self illumination is computed from emission color, luminance, temperature and weight babylonMaterial.emissive = materialNode.MaxMaterial.GetSelfIllumColorOn(0, false) ? materialNode.MaxMaterial.GetSelfIllumColor(0, false).ToArray() : materialNode.MaxMaterial.GetDiffuse(0, false).Scale(materialNode.MaxMaterial.GetSelfIllum(0, false)); } else { // Ignore specified roughness and metallic values babylonMaterial.metallic = 0; babylonMaterial.roughness = 0.9f; } // --- Textures --- // 1 - base color ; 9 - transparancy weight ITexmap colorTexmap = _getTexMap(materialNode, 1); ITexmap alphaTexmap = _getTexMap(materialNode, 9); babylonMaterial.baseTexture = ExportBaseColorAlphaTexture(colorTexmap, alphaTexmap, babylonMaterial.baseColor, babylonMaterial.alpha, babylonScene, name); if (isUnlit == false) { // Metallic, roughness, ambient occlusion ITexmap metallicTexmap = _getTexMap(materialNode, 5); ITexmap roughnessTexmap = _getTexMap(materialNode, 4); ITexmap ambientOcclusionTexmap = _getTexMap(materialNode, 6); // Use diffuse roughness map as ambient occlusion // Check if MR or ORM textures are already merged bool areTexturesAlreadyMerged = false; if (metallicTexmap != null && roughnessTexmap != null) { string sourcePathMetallic = getSourcePath(metallicTexmap); string sourcePathRoughness = getSourcePath(roughnessTexmap); if (sourcePathMetallic == sourcePathRoughness) { if (ambientOcclusionTexmap != null && exportParameters.mergeAOwithMR) { string sourcePathAmbientOcclusion = getSourcePath(ambientOcclusionTexmap); if (sourcePathMetallic == sourcePathAmbientOcclusion) { // Metallic, roughness and ambient occlusion are already merged RaiseVerbose("Metallic, roughness and ambient occlusion are already merged", 2); BabylonTexture ormTexture = ExportTexture(metallicTexmap, babylonScene); babylonMaterial.metallicRoughnessTexture = ormTexture; babylonMaterial.occlusionTexture = ormTexture; areTexturesAlreadyMerged = true; } } else { // Metallic and roughness are already merged RaiseVerbose("Metallic and roughness are already merged", 2); BabylonTexture ormTexture = ExportTexture(metallicTexmap, babylonScene); babylonMaterial.metallicRoughnessTexture = ormTexture; areTexturesAlreadyMerged = true; } } } if (areTexturesAlreadyMerged == false) { if (metallicTexmap != null || roughnessTexmap != null) { // Merge metallic, roughness and ambient occlusion RaiseVerbose("Merge metallic and roughness (and ambient occlusion if `mergeAOwithMR` is enabled)", 2); BabylonTexture ormTexture = ExportORMTexture(exportParameters.mergeAOwithMR ? ambientOcclusionTexmap : null, roughnessTexmap, metallicTexmap, babylonMaterial.metallic, babylonMaterial.roughness, babylonScene, invertRoughness); babylonMaterial.metallicRoughnessTexture = ormTexture; if (ambientOcclusionTexmap != null) { if (exportParameters.mergeAOwithMR) { // if the ambient occlusion texture map uses a different set of texture coordinates than // metallic roughness, create a new instance of the ORM BabylonTexture with the different texture // coordinate indices var ambientOcclusionTexture = _getBitmapTex(ambientOcclusionTexmap); var texCoordIndex = ambientOcclusionTexture.UVGen.MapChannel - 1; if (texCoordIndex != ormTexture.coordinatesIndex) { babylonMaterial.occlusionTexture = new BabylonTexture(ormTexture); babylonMaterial.occlusionTexture.coordinatesIndex = texCoordIndex; // Set UVs/texture transform for the ambient occlusion texture var uvGen = _exportUV(ambientOcclusionTexture.UVGen, babylonMaterial.occlusionTexture); } else { babylonMaterial.occlusionTexture = ormTexture; } } else { babylonMaterial.occlusionTexture = ExportPBRTexture(materialNode, 6, babylonScene); } } } else if (ambientOcclusionTexmap != null) { // Simply export occlusion texture RaiseVerbose("Simply export occlusion texture", 2); babylonMaterial.occlusionTexture = ExportTexture(ambientOcclusionTexmap, babylonScene); } } if (ambientOcclusionTexmap != null && !exportParameters.mergeAOwithMR && babylonMaterial.occlusionTexture == null) { RaiseVerbose("Exporting occlusion texture without merging with metallic roughness", 2); babylonMaterial.occlusionTexture = ExportTexture(ambientOcclusionTexmap, babylonScene); } var normalMapAmount = propertyContainer.GetFloatProperty(91); babylonMaterial.normalTexture = ExportPBRTexture(materialNode, 30, babylonScene, normalMapAmount); babylonMaterial.emissiveTexture = ExportPBRTexture(materialNode, 17, babylonScene); } if (babylonMaterial.alpha != 1.0f || (babylonMaterial.baseTexture != null && babylonMaterial.baseTexture.hasAlpha)) { var alphaTestProperty = materialNode.IPropertyContainer.QueryProperty("BabylonAlphaTest"); bool isAlphaTest = alphaTestProperty != null?alphaTestProperty.GetBoolValue() : false; babylonMaterial.transparencyMode = isAlphaTest ? (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST : (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND; } if (babylonMaterial.emissiveTexture != null) { babylonMaterial.emissive = new[] { 1.0f, 1.0f, 1.0f }; } if (babylonMaterial.metallicRoughnessTexture != null) { babylonMaterial.metallic = 1.0f; babylonMaterial.roughness = 1.0f; } babylonScene.MaterialsList.Add(babylonMaterial); } else if (isArnoldMaterial(materialNode)) { var propertyContainer = materialNode.IPropertyContainer; var babylonMaterial = new BabylonPBRMetallicRoughnessMaterial(id) { name = name, isUnlit = isUnlit }; // Alpha babylonMaterial.alpha = 1.0f - propertyContainer.GetFloatProperty(32); // Color: base * weight float[] baseColor = propertyContainer.GetPoint3Property(5).ToArray(); float baseWeight = propertyContainer.GetFloatProperty(2); babylonMaterial.baseColor = baseColor.Multiply(baseWeight); // Metallic & roughness bool invertRoughness = false; babylonMaterial.roughness = propertyContainer.GetFloatProperty(17); // specular_roughness babylonMaterial.metallic = propertyContainer.GetFloatProperty(29); // Emissive: emission_color * emission float[] emissionColor = propertyContainer.QueryProperty("emission_color").GetPoint3Property().ToArray(); float emissionWeight = propertyContainer.QueryProperty("emission").GetFloatValue(); if (emissionColor != null && emissionWeight > 0f) { babylonMaterial.emissive = emissionColor.Multiply(emissionWeight); } // --- Textures --- // 1 - base_color ; 5 - specular_roughness ; 9 - metalness ; 10 - transparent ITexmap colorTexmap = _getTexMap(materialNode, 1); ITexmap alphaTexmap = _getTexMap(materialNode, 10); babylonMaterial.baseTexture = ExportBaseColorAlphaTexture(colorTexmap, alphaTexmap, babylonMaterial.baseColor, babylonMaterial.alpha, babylonScene, name); if (isUnlit == false) { // Metallic, roughness ITexmap metallicTexmap = _getTexMap(materialNode, 9); ITexmap roughnessTexmap = _getTexMap(materialNode, 5); ITexmap ambientOcclusionTexmap = _getTexMap(materialNode, 6); // Use diffuse roughness map as ambient occlusion // Check if MR textures are already merged bool areTexturesAlreadyMerged = false; if (metallicTexmap != null && roughnessTexmap != null) { string sourcePathMetallic = getSourcePath(metallicTexmap); string sourcePathRoughness = getSourcePath(roughnessTexmap); if (sourcePathMetallic == sourcePathRoughness) { // Metallic and roughness are already merged RaiseVerbose("Metallic and roughness are already merged", 2); BabylonTexture ormTexture = ExportTexture(metallicTexmap, babylonScene); babylonMaterial.metallicRoughnessTexture = ormTexture; // The already merged map is assumed to contain Ambient Occlusion in R channel if (ambientOcclusionTexmap != null) { // if the ambient occlusion texture map uses a different set of texture coordinates than // metallic roughness, create a new instance of the ORM BabylonTexture with the different texture // coordinate indices var ambientOcclusionTexture = _getBitmapTex(ambientOcclusionTexmap); var texCoordIndex = ambientOcclusionTexture.UVGen.MapChannel - 1; if (texCoordIndex != ormTexture.coordinatesIndex) { babylonMaterial.occlusionTexture = new BabylonTexture(ormTexture); babylonMaterial.occlusionTexture.coordinatesIndex = texCoordIndex; // Set UVs/texture transform for the ambient occlusion texture var uvGen = _exportUV(ambientOcclusionTexture.UVGen, babylonMaterial.occlusionTexture); } else { babylonMaterial.occlusionTexture = ormTexture; } } else { babylonMaterial.occlusionTexture = ormTexture; } areTexturesAlreadyMerged = true; } } if (areTexturesAlreadyMerged == false) { if (metallicTexmap != null || roughnessTexmap != null) { // Merge metallic, roughness RaiseVerbose("Merge metallic and roughness", 2); BabylonTexture ormTexture = ExportORMTexture(null, roughnessTexmap, metallicTexmap, babylonMaterial.metallic, babylonMaterial.roughness, babylonScene, invertRoughness); babylonMaterial.metallicRoughnessTexture = ormTexture; } } var numOfTexMapSlots = materialNode.MaxMaterial.NumSubTexmaps; for (int i = 0; i < numOfTexMapSlots; i++) { if (materialNode.MaxMaterial.GetSubTexmapSlotName(i) == "normal") { babylonMaterial.normalTexture = ExportPBRTexture(materialNode, i, babylonScene); } else if (materialNode.MaxMaterial.GetSubTexmapSlotName(i) == "emission") { babylonMaterial.emissiveTexture = ExportPBRTexture(materialNode, i, babylonScene); } } } // Constraints if (babylonMaterial.baseTexture != null) { babylonMaterial.baseColor = new[] { 1.0f, 1.0f, 1.0f }; babylonMaterial.alpha = 1.0f; } if (babylonMaterial.alpha != 1.0f || (babylonMaterial.baseTexture != null && babylonMaterial.baseTexture.hasAlpha)) { babylonMaterial.transparencyMode = (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND; } if (babylonMaterial.metallicRoughnessTexture != null) { babylonMaterial.metallic = 1.0f; babylonMaterial.roughness = 1.0f; } // Add the material to the scene babylonScene.MaterialsList.Add(babylonMaterial); } else { // isMaterialExportable check should prevent this to happen RaiseError("Unsupported material type: " + materialNode.MaterialClass, 2); } }
private void AddParameterSamplerAnimation(BabylonMaterial babylonMaterial, GLTFAnimation gltfAnimation, GLTFExporter exporter, GLTF gltf, int startFrame, int endFrame) { var samplerList = gltfAnimation.SamplerList; // Combine babylon animations from .babylon file and cached ones var babylonAnimations = new List <BabylonAnimation>(); if (babylonMaterial.animations != null) { babylonAnimations.AddRange(babylonMaterial.animations); } if (babylonAnimations.Count > 0) { if (babylonAnimations.Count > 0) { exporter.logger.RaiseMessage("GLTFExporter.Animation | Export animations of node named: " + babylonMaterial.name, 2); } foreach (BabylonAnimation babylonAnimation in babylonAnimations) { var babylonAnimationKeysInRange = babylonAnimation.keys.Where(key => key.frame >= startFrame && key.frame <= endFrame); if (babylonAnimationKeysInRange.Count() <= 0) { continue; } string target_path = babylonAnimation.property; // --- Input --- var accessorInput = exporter._createAndPopulateInput(gltf, babylonAnimation, startFrame, endFrame); if (accessorInput == null) { continue; } // --- Output --- GLTFAccessor accessorOutput = FlightSimAsoboPropertyAnimationExtension._createAccessorOfProperty(target_path, gltf); if (accessorOutput == null) { continue; } // Populate accessor int numKeys = 0; foreach (var babylonAnimationKey in babylonAnimationKeysInRange) { numKeys++; // copy data before changing it in case animation groups overlap float[] outputValues = new float[babylonAnimationKey.values.Length]; babylonAnimationKey.values.CopyTo(outputValues, 0); // Store values as bytes foreach (var outputValue in outputValues) { accessorOutput.bytesList.AddRange(BitConverter.GetBytes(outputValue)); } } ; accessorOutput.count = numKeys; if (accessorOutput.count == 0) { exporter.logger.RaiseWarning(String.Format("GLTFExporter.Animation | No frames to export in material animation \"{1}\" of node named \"{0}\". This will cause an error in the output gltf.", babylonMaterial.name, babylonAnimation.name)); } // Animation sampler var gltfAnimationSampler = new GLTFAnimationSampler { input = accessorInput.index, output = accessorOutput.index }; gltfAnimationSampler.index = samplerList.Count; samplerList.Add(gltfAnimationSampler); } } }
private void ExportCommonBabylonAttributes0(MFnDependencyNode babylonAttributesDependencyNode, BabylonMaterial babylonMaterial) { // Backface Culling if (babylonAttributesDependencyNode.hasAttribute("babylonBackfaceCulling")) { bool v = babylonAttributesDependencyNode.findPlug("babylonBackfaceCulling").asBool(); RaiseVerbose($"backfaceCulling={v}", 3); babylonMaterial.backFaceCulling = v; } // unlit if (babylonAttributesDependencyNode.hasAttribute("babylonUnlit")) { bool v = babylonAttributesDependencyNode.findPlug("babylonUnlit").asBool(); RaiseVerbose($"isUnlit={v}", 3); babylonMaterial.isUnlit = v; } // max light if (babylonAttributesDependencyNode.hasAttribute("babylonMaxSimultaneousLights")) { int v = babylonAttributesDependencyNode.findPlug("babylonMaxSimultaneousLights").asInt(); RaiseVerbose($"maxSimultaneousLights={v}", 3); babylonMaterial.maxSimultaneousLights = v; } }
protected static void Init(MFnDependencyNode babylonAttributesDependencyNode, BabylonMaterial babylonMaterial = null) { // Ensure all attributes are setup if (babylonAttributesDependencyNode.hasAttribute("babylonBackfaceCulling") == false) { MGlobal.executeCommand($"addAttr -ln \"babylonBackfaceCulling\" -nn \"Backface Culling\" -at bool {babylonAttributesDependencyNode.name};"); } if (babylonAttributesDependencyNode.hasAttribute("babylonUnlit") == false) { MGlobal.executeCommand($"addAttr -ln \"babylonUnlit\" -nn \"Unlit\" -at bool {babylonAttributesDependencyNode.name};"); } if (babylonAttributesDependencyNode.hasAttribute("babylonMaxSimultaneousLights") == false) { MGlobal.executeCommand($"addAttr -ln \"babylonMaxSimultaneousLights\" -nn \"Max Simultaneous Lights\" -at long -min 1 -dv 4 {babylonAttributesDependencyNode.name};"); } // Initialise attributes according to babylon material if (babylonMaterial != null) { setAttributeValue(babylonAttributesDependencyNode.name + ".babylonBackfaceCulling", Convert.ToInt32(babylonMaterial.backFaceCulling)); setAttributeValue(babylonAttributesDependencyNode.name + ".babylonUnlit", Convert.ToInt32(babylonMaterial.isUnlit)); setAttributeValue(babylonAttributesDependencyNode.name + ".babylonMaxSimultaneousLights", babylonMaterial.maxSimultaneousLights); } }
private void ExportMainCameraSkyboxToBabylon() { if (RenderSettings.sun != null) { var direction = new Vector3(0, 0, 1); var transformedDirection = RenderSettings.sun.transform.TransformDirection(direction); SceneBuilder.SunlightDirection = transformedDirection.ToFloat(); SceneBuilder.SunlightIndentifier = GetID(RenderSettings.sun.gameObject); } if (Camera.main != null) { babylonScene.clearColor = Camera.main.backgroundColor.ToFloat(1.0f); if ((Camera.main.clearFlags & CameraClearFlags.Skybox) == CameraClearFlags.Skybox) { if (RenderSettings.skybox != null) { bool dds = false; BabylonTexture skytex = null; if (RenderSettings.skybox.shader.name == "Skybox/Cubemap") { skytex = new BabylonCubeTexture(); skytex.name = String.Format("{0}_Skybox", SceneName); skytex.coordinatesMode = 5; Cubemap cubeMap = RenderSettings.skybox.GetTexture("_Tex") as Cubemap; if (cubeMap != null) { var srcTexturePath = AssetDatabase.GetAssetPath(cubeMap); var srcTextureExt = Path.GetExtension(srcTexturePath); if (srcTextureExt.Equals(".dds", StringComparison.OrdinalIgnoreCase)) { ExporterWindow.ReportProgress(1, "Exporting skybox direct draw surface... This may take a while."); // .. // Export Draw Surface Skybox Textures // .. dds = true; skytex.name += ".dds"; skytex.extensions = null; ((BabylonCubeTexture)skytex).prefiltered = true; CopyCubemapTexture(skytex.name, cubeMap, skytex); } else { ExporterWindow.ReportProgress(1, "Baking skybox environment textures... This may take a while."); var imageFormat = (BabylonImageFormat)ExporterWindow.exportationOptions.ImageEncodingOptions; // .. // Export Tone Mapped Cubemap To 6-Sided Skybox Textures // .. bool jpeg = (imageFormat == BabylonImageFormat.JPG); string faceTextureExt = (jpeg) ? ".jpg" : ".png"; string frontTextureExt = "_pz" + faceTextureExt; string backTextureExt = "_nz" + faceTextureExt; string leftTextureExt = "_px" + faceTextureExt; string rightTextureExt = "_nx" + faceTextureExt; string upTextureExt = "_py" + faceTextureExt; string downTextureExt = "_ny" + faceTextureExt; skytex.extensions = new string[] { leftTextureExt, upTextureExt, frontTextureExt, rightTextureExt, downTextureExt, backTextureExt }; Tools.SetTextureWrapMode(skytex, cubeMap); var outputFile = Path.Combine(babylonScene.OutputPath, skytex.name + faceTextureExt); var splitterOpts = new BabylonSplitterOptions(); Tools.ExportSkybox(cubeMap, outputFile, splitterOpts, imageFormat); } } } else if (RenderSettings.skybox.shader.name == "Skybox/6 Sided" || RenderSettings.skybox.shader.name == "Mobile/Skybox") { skytex = new BabylonCubeTexture(); skytex.name = String.Format("{0}_Skybox", SceneName); skytex.coordinatesMode = 5; // .. // 6-Sided Skybox Textures (Tone Mapped Image Formats Only) // .. var frontTexture = RenderSettings.skybox.GetTexture("_FrontTex") as Texture2D; var backTexture = RenderSettings.skybox.GetTexture("_BackTex") as Texture2D; var leftTexture = RenderSettings.skybox.GetTexture("_LeftTex") as Texture2D; var rightTexture = RenderSettings.skybox.GetTexture("_RightTex") as Texture2D; var upTexture = RenderSettings.skybox.GetTexture("_UpTex") as Texture2D; var downTexture = RenderSettings.skybox.GetTexture("_DownTex") as Texture2D; DumpSkyboxTextures(ref skytex, ref frontTexture, ref backTexture, ref leftTexture, ref rightTexture, ref upTexture, ref downTexture); } else if (RenderSettings.skybox.name.Equals("Default-Skybox")) { skytex = new BabylonCubeTexture(); skytex.name = String.Format("{0}_Skybox", SceneName); skytex.coordinatesMode = 5; // .. // 6-Sided Skybox Textures (Toolkit Skybox Template Images) // .. string skyboxPath = "Assets/Babylon/Template/Skybox/"; var frontTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(skyboxPath + "DefaultSkybox_pz.png"); var backTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(skyboxPath + "DefaultSkybox_nz.png"); var leftTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(skyboxPath + "DefaultSkybox_px.png"); var rightTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(skyboxPath + "DefaultSkybox_nx.png"); var upTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(skyboxPath + "DefaultSkybox_py.png"); var downTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(skyboxPath + "DefaultSkybox_ny.png"); DumpSkyboxTextures(ref skytex, ref frontTexture, ref backTexture, ref leftTexture, ref rightTexture, ref upTexture, ref downTexture); } else { UnityEngine.Debug.LogWarning("SKYBOX: " + RenderSettings.skybox.shader.name + " shader type is unsupported. Skybox and reflections will be disabled."); } if (skytex != null) { float size = (SceneController != null) ? SceneController.skyboxOptions.skyboxMeshSize : 1000; string tags = (SceneController != null) ? SceneController.skyboxOptions.skyboxMeshTags : String.Empty; // .. // PBR Skybox Material Support // .. bool pbr = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.physicalBased : false; float pbr_ms = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.microSurface : 1.0f; float pbr_cc = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.cameraContrast : 1.0f; float pbr_ce = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.cameraExposure : 1.0f; float pbr_di = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.directIntensity : 1.0f; float pbr_ei = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.emissiveIntensity : 1.0f; float pbr_si = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.specularIntensity : 1.0f; float pbr_ri = (SceneController != null) ? SceneController.skyboxOptions.directDrawSurface.environmentIntensity : 1.0f; var skybox = new BabylonMesh(); skybox.id = Guid.NewGuid().ToString(); skybox.infiniteDistance = true; skybox.numBoneInfluencers = Tools.GetMaxBoneInfluencers(); if (!String.IsNullOrEmpty(tags)) { skybox.tags = tags; } skybox.name = "SceneSkyboxMesh"; Mesh boxMesh = Tools.CreateBoxMesh(size, size, size); Tools.GenerateBabylonMeshData(boxMesh, skybox); BabylonMaterial skyboxMaterial = null; if (dds == true && pbr == true) { var skyboxMaterialPbr = new BabylonSystemMaterial { name = "SceneSkyboxMaterial", id = Guid.NewGuid().ToString(), backFaceCulling = false, disableLighting = true, albedo = Color.white.ToFloat(), ambient = Color.black.ToFloat(), emissive = Color.black.ToFloat(), metallic = null, roughness = null, sideOrientation = 1, reflectivity = Color.white.ToFloat(), reflection = Color.white.ToFloat(), microSurface = pbr_ms, cameraContrast = pbr_cc, cameraExposure = pbr_ce, directIntensity = pbr_di, emissiveIntensity = pbr_ei, specularIntensity = pbr_si, environmentIntensity = pbr_ri, maxSimultaneousLights = 4, useSpecularOverAlpha = false, useRadianceOverAlpha = false, usePhysicalLightFalloff = false, useAlphaFromAlbedoTexture = false, useEmissiveAsIllumination = false, reflectionTexture = skytex }; skyboxMaterial = skyboxMaterialPbr; } else { var skyboxMaterialStd = new BabylonDefaultMaterial { name = "SceneSkyboxMaterial", id = Guid.NewGuid().ToString(), backFaceCulling = false, disableLighting = true, diffuse = Color.black.ToFloat(), specular = Color.black.ToFloat(), ambient = Color.clear.ToFloat(), reflectionTexture = skytex }; skyboxMaterial = skyboxMaterialStd; } if (skyboxMaterial != null) { skybox.materialId = skyboxMaterial.id; babylonScene.MeshesList.Add(skybox); babylonScene.MaterialsList.Add(skyboxMaterial); babylonScene.AddTextureCube("SceneSkyboxMaterial"); } } } } } }
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 --- RaiseMessage("GLTFExporter.Material | babylonMaterial data", 2); RaiseMessage("GLTFExporter.Material | babylonMaterial.alpha=" + babylonMaterial.alpha, 3); RaiseMessage("GLTFExporter.Material | babylonMaterial.backFaceCulling=" + babylonMaterial.backFaceCulling, 3); RaiseMessage("GLTFExporter.Material | babylonMaterial.wireframe=" + babylonMaterial.wireframe, 3); RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.specularPower=" + babylonStandardMaterial.specularPower, 3); // Ambient for (int i = 0; i < babylonStandardMaterial.ambient.Length; i++) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.ambient[" + i + "]=" + babylonStandardMaterial.ambient[i], 3); } // Diffuse RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.diffuse.Length=" + babylonStandardMaterial.diffuse.Length, 3); for (int i = 0; i < babylonStandardMaterial.diffuse.Length; i++) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.diffuse[" + i + "]=" + babylonStandardMaterial.diffuse[i], 3); } if (babylonStandardMaterial.diffuseTexture == null) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.diffuseTexture=null", 3); } // Normal / bump if (babylonStandardMaterial.bumpTexture == null) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.bumpTexture=null", 3); } // Specular for (int i = 0; i < babylonStandardMaterial.specular.Length; i++) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.specular[" + i + "]=" + babylonStandardMaterial.specular[i], 3); } RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.specularPower=" + babylonStandardMaterial.specularPower, 3); // Occlusion if (babylonStandardMaterial.ambientTexture == null) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.ambientTexture=null", 3); } // Emissive for (int i = 0; i < babylonStandardMaterial.emissive.Length; i++) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.emissive[" + i + "]=" + babylonStandardMaterial.emissive[i], 3); } if (babylonStandardMaterial.emissiveTexture == null) { RaiseMessage("GLTFExporter.Material | babylonStandardMaterial.emissiveTexture=null", 3); } // -------------------------------- // --------- 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; gltfMaterial.emissiveTexture = ExportTexture(babylonStandardMaterial.emissiveTexture, gltf); // -------------------------------- // --- gltfPbrMetallicRoughness --- // -------------------------------- RaiseMessage("GLTFExporter.Material | create gltfPbrMetallicRoughness", 2); var gltfPbrMetallicRoughness = new GLTFPBRMetallicRoughness(); gltfMaterial.pbrMetallicRoughness = gltfPbrMetallicRoughness; // --- Global --- SpecularGlossiness _specularGlossiness = new SpecularGlossiness { diffuse = new BabylonColor3(babylonStandardMaterial.diffuse), 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 --- if (babylonStandardMaterial.diffuseTexture != null) { Func <string, Bitmap> loadTexture = delegate(string textureName) { var pathDiffuse = Path.Combine(gltf.OutputPath, textureName); if (File.Exists(pathDiffuse)) { return(new Bitmap(pathDiffuse)); } else { RaiseWarning(string.Format("GLTFExporter.Material | Texture {0} not found.", textureName), 2); return(null); } }; Bitmap diffuseBitmap = loadTexture(babylonStandardMaterial.diffuseTexture.name); if (diffuseBitmap != null) { Bitmap specularBitmap = null; if (babylonStandardMaterial.specularTexture != null) { specularBitmap = loadTexture(babylonStandardMaterial.specularTexture.name); } Bitmap opacityBitmap = null; if (babylonStandardMaterial.diffuseTexture.hasAlpha == false && babylonStandardMaterial.opacityTexture != null) { opacityBitmap = loadTexture(babylonStandardMaterial.opacityTexture.name); } // Retreive dimension from diffuse map var width = diffuseBitmap.Width; var height = diffuseBitmap.Height; // Create base color and metallic+roughness maps Bitmap baseColorBitmap = new Bitmap(width, height); Bitmap metallicRoughnessBitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { var diffuse = diffuseBitmap.GetPixel(x, y); SpecularGlossiness specularGlossinessTexture = new SpecularGlossiness { diffuse = new BabylonColor3(diffuse), opacity = babylonStandardMaterial.diffuseTexture.hasAlpha? diffuse.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 : 1, specular = specularBitmap != null ? new BabylonColor3(specularBitmap.GetPixel(x, y)) : new BabylonColor3(), glossiness = babylonStandardMaterial.useGlossinessFromSpecularMapAlpha && specularBitmap != null?specularBitmap.GetPixel(x, y).A / 255.0f : babylonStandardMaterial.specularPower / 256.0f }; 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 maps and textures gltfPbrMetallicRoughness.baseColorTexture = ExportBitmapTexture(babylonStandardMaterial.diffuseTexture, baseColorBitmap, babylonMaterial.name + "_baseColor" + ".png", gltf); gltfPbrMetallicRoughness.metallicRoughnessTexture = ExportBitmapTexture(babylonStandardMaterial.diffuseTexture, metallicRoughnessBitmap, babylonMaterial.name + "_metallicRoughness" + ".jpg", gltf); } } } }
private IList <BabylonAnimationGroup> ExportAnimationGroups(BabylonScene babylonScene) { IList <BabylonAnimationGroup> animationGroups = new List <BabylonAnimationGroup>(); // Retrieve and parse animation group data AnimationGroupList animationList = AnimationGroupList.InitAnimationGroups(logger); foreach (AnimationGroup animGroup in animationList) { logger?.RaiseMessage("Exporter.animationGroups | " + animGroup.Name, 1); BabylonAnimationGroup animationGroup = new BabylonAnimationGroup { name = animGroup.Name, from = animGroup.FrameStart, to = animGroup.FrameEnd, keepNonAnimated = animGroup.KeepNonAnimated, targetedAnimations = new List <BabylonTargetedAnimation>() }; // add animations of each nodes contained in the animGroup foreach (Guid guid in animGroup.NodeGuids) { IINode maxNode = Tools.GetINodeByGuid(guid); // node could have been deleted, silently ignore it if (maxNode == null) { continue; } if (exportParameters.exportAsSubmodel && !maxNode.Selected) { continue; } // Helpers can be exported as dummies and as bones string nodeId = maxNode.GetGuid().ToString(); string boneId = isGltfExported?maxNode.GetGuid().ToString(): maxNode.GetGuid().ToString() + "-bone"; // the suffix "-bone" is added in babylon export format to assure the uniqueness of IDs // Node BabylonNode node = null; babylonScene.NodeMap.TryGetValue(nodeId, out node); if (node != null) { if (node.animations != null && node.animations.Length != 0) { IList <BabylonAnimation> animations = GetSubAnimations(node, animationGroup.from, animationGroup.to); if (!animGroup.KeepStaticAnimation) { RemoveStaticAnimations(ref animations); } foreach (BabylonAnimation animation in animations) { BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation { animation = animation, targetId = nodeId }; animationGroup.targetedAnimations.Add(targetedAnimation); } } } // bone BabylonBone bone = null; int index = 0; while (index < babylonScene.SkeletonsList.Count && bone == null) { BabylonSkeleton skel = babylonScene.SkeletonsList[index]; bone = skel.bones.FirstOrDefault(b => b.id == boneId); index++; } if (bone != null) { if (bone.animation != null) { IList <BabylonAnimation> animations = GetSubAnimations(bone, animationGroup.from, animationGroup.to); foreach (BabylonAnimation animation in animations) { BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation { animation = animation, targetId = boneId }; animationGroup.targetedAnimations.Add(targetedAnimation); } } } } // add animations of each nodes contained in the animGroup foreach (Guid guid in animGroup.MaterialGuids) { IMtl maxMtl = Tools.GetIMtlByGuid(guid); // mat could have been deleted, silently ignore it if (maxMtl == null) { continue; } string matId = maxMtl.GetGuid().ToString(); // Material BabylonMaterial material = null; material = babylonScene.MaterialsList.FirstOrDefault(x => x.id == matId); if (material != null) { if (material.animations != null && material.animations.Length != 0) { IList <BabylonAnimation> animations = GetSubAnimations(material, animationGroup.from, animationGroup.to); foreach (BabylonAnimation animation in animations) { BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation { animation = animation, targetId = matId }; animationGroup.targetedAnimations.Add(targetedAnimation); } } } } if (animationGroup.targetedAnimations.Count > 0) { animationGroups.Add(animationGroup); } } return(animationGroups); }
private void ExportMaterial(Material materialNode, BabylonScene babylonScene) { var name = materialNode._Mtl.Name; var id = materialNode.GetGuid().ToString(); RaiseMessage(name, true); if (materialNode.NumSubMaterials > 0) { var babylonMultimaterial = new BabylonMultiMaterial(); babylonMultimaterial.name = name; babylonMultimaterial.id = id; var guids = new List <string>(); for (var index = 0; index < materialNode.NumSubMaterials; index++) { var subMat = materialNode.GetSubMaterial(index) as Material; if (subMat != null) { guids.Add(subMat.GetGuid().ToString()); if (!referencedMaterials.Contains(subMat)) { referencedMaterials.Add(subMat); ExportMaterial(subMat, babylonScene); } } else { guids.Add(Guid.Empty.ToString()); } } babylonMultimaterial.materials = guids.ToArray(); babylonScene.MultiMaterialsList.Add(babylonMultimaterial); return; } var babylonMaterial = new BabylonMaterial(); babylonMaterial.name = name; babylonMaterial.id = id; babylonMaterial.ambient = materialNode.GetAmbient(0).ToArray(); babylonMaterial.diffuse = materialNode.GetDiffuse(0).ToArray(); babylonMaterial.specular = materialNode.GetSpecular(0).Scale(materialNode.GetShinyStrength(0)); babylonMaterial.specularPower = materialNode.GetShininess(0) * 256; babylonMaterial.emissive = materialNode.SelfIlluminationColorOn ? materialNode.GetSelfIllumColor(0).ToArray() : materialNode.GetDiffuse(0).Scale(materialNode.GetSelfIllumination(0)); babylonMaterial.alpha = 1.0f - materialNode.GetTransparency(0); var stdMat = materialNode._Mtl.GetParamBlock(0).Owner as IStdMat2; if (stdMat != null) { // Textures babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, babylonScene); // Ambient babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, babylonScene); // Diffuse babylonMaterial.specularTexture = ExportTexture(stdMat, 2, babylonScene); // Specular babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, babylonScene); // Emissive babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, babylonScene); // Opacity babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, babylonScene); // Bump babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, babylonScene); // Reflection // Constraints if (babylonMaterial.diffuseTexture != null) { babylonMaterial.emissive = new [] { 1.0f, 1.0f, 1.0f }; } if (babylonMaterial.emissiveTexture != null) { babylonMaterial.emissive = new float[] { 0, 0, 0 }; } if (babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture != null && babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name && babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB) { // This is a alpha testing purpose babylonMaterial.opacityTexture = null; babylonMaterial.diffuseTexture.hasAlpha = true; RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", true); RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", true); } } babylonScene.MaterialsList.Add(babylonMaterial); }
void DumpStandardMaterial(NovaStandardMaterial stdMaterial, BabylonScene babylonScene) { var babylonMaterial = new BabylonMaterial(); babylonScene.MaterialsList.Add(babylonMaterial); babylonMaterial.name = stdMaterial.Name; babylonMaterial.id = stdMaterial.ID.ToString(); babylonMaterial.alpha = stdMaterial.Alpha; babylonMaterial.ambient = (stdMaterial.Ambient * (1.0f - stdMaterial.SelfIllumination)).ToArray(); babylonMaterial.diffuse = (stdMaterial.Diffuse * (1.0f - stdMaterial.SelfIllumination)).ToArray(); babylonMaterial.emissive = (stdMaterial.Emissive * stdMaterial.SelfIllumination).ToArray(); babylonMaterial.specular = stdMaterial.Specular.ToArray(); babylonMaterial.specularPower = stdMaterial.SpecularSharpness; babylonMaterial.backFaceCulling = (stdMaterial.CullMode == NovaCull.CounterClockwise); if (stdMaterial.DiffuseTexture != null && stdMaterial.DiffuseTexture.HasTextureData && stdMaterial.OpacityTexture != null && stdMaterial.OpacityTexture.HasTextureData) { if (stdMaterial.DiffuseTexture.LoadedTexture == stdMaterial.OpacityTexture.LoadedTexture) { stdMaterial.DiffuseTexture = stdMaterial.OpacityTexture; stdMaterial.OpacityTexture = null; } } if (stdMaterial.DiffuseTexture != null && stdMaterial.DiffuseTexture.HasTextureData && !stdMaterial.DiffuseTexture.IsVideo && !stdMaterial.DiffuseTexture.IsCubeRender) { babylonMaterial.diffuseTexture = new BabylonTexture(); DumpTexture(stdMaterial.DiffuseTexture, babylonMaterial.diffuseTexture, babylonScene); } if (stdMaterial.AmbientTexture != null && stdMaterial.AmbientTexture.HasTextureData && !stdMaterial.AmbientTexture.IsVideo && !stdMaterial.AmbientTexture.IsCubeRender) { babylonMaterial.ambientTexture = new BabylonTexture(); DumpTexture(stdMaterial.AmbientTexture, babylonMaterial.ambientTexture, babylonScene); } if (stdMaterial.OpacityTexture != null && stdMaterial.OpacityTexture.HasTextureData && !stdMaterial.OpacityTexture.IsVideo && !stdMaterial.OpacityTexture.IsCubeRender) { babylonMaterial.opacityTexture = new BabylonTexture(); DumpTexture(stdMaterial.OpacityTexture, babylonMaterial.opacityTexture, babylonScene); } if (mirrorsMaterials.ContainsKey(stdMaterial)) { babylonMaterial.reflectionTexture = new BabylonTexture(); var novaObject = mirrorsMaterials[stdMaterial]; DumpRenderTargetTexture(stdMaterial.ReflectionTexture, babylonMaterial.reflectionTexture, novaObject.MirrorMapSize, novaObject.MirrorLevel, novaObject.MirroredObjects); AttachMirrorPlane(babylonMaterial.reflectionTexture, novaObject); } else if (stdMaterial.ReflectionTexture != null && stdMaterial.ReflectionTexture.HasTextureData && !stdMaterial.ReflectionTexture.IsVideo && !stdMaterial.ReflectionTexture.IsCubeRender) { babylonMaterial.reflectionTexture = new BabylonTexture(); DumpTexture(stdMaterial.ReflectionTexture, babylonMaterial.reflectionTexture, babylonScene); } if (stdMaterial.EmissiveTexture != null && stdMaterial.EmissiveTexture.HasTextureData && !stdMaterial.EmissiveTexture.IsVideo && !stdMaterial.EmissiveTexture.IsCubeRender) { babylonMaterial.emissiveTexture = new BabylonTexture(); DumpTexture(stdMaterial.EmissiveTexture, babylonMaterial.emissiveTexture, babylonScene); } if (stdMaterial.SpecularTexture != null && stdMaterial.SpecularTexture.HasTextureData && !stdMaterial.SpecularTexture.IsVideo && !stdMaterial.SpecularTexture.IsCubeRender) { babylonMaterial.specularTexture = new BabylonTexture(); DumpTexture(stdMaterial.SpecularTexture, babylonMaterial.specularTexture, babylonScene); } if (stdMaterial.BumpTexture != null && stdMaterial.BumpTexture.HasTextureData && !stdMaterial.BumpTexture.IsVideo && !stdMaterial.BumpTexture.IsCubeRender) { babylonMaterial.bumpTexture = new BabylonTexture(); DumpTexture(stdMaterial.BumpTexture, babylonMaterial.bumpTexture, babylonScene); babylonMaterial.bumpTexture.level /= 2.0f; } }
void DumpPerPixelShader(NovaPerPixelShader ppShader, BabylonScene babylonScene) { var babylonMaterial = new BabylonMaterial(); babylonScene.MaterialsList.Add(babylonMaterial); babylonMaterial.name = ppShader.Name; babylonMaterial.id = ppShader.ID.ToString(); babylonMaterial.alpha = ppShader.Alpha; babylonMaterial.ambient = (ppShader.Ambient * (1.0f - ppShader.SelfIllumination)).ToArray(); babylonMaterial.diffuse = (ppShader.Diffuse * (1.0f - ppShader.SelfIllumination)).ToArray(); babylonMaterial.emissive = (ppShader.Emissive * ppShader.SelfIllumination).ToArray(); babylonMaterial.specular = ppShader.Specular.ToArray(); babylonMaterial.specularPower = ppShader.SpecularSharpness; babylonMaterial.backFaceCulling = (ppShader.CullMode == NovaCull.CounterClockwise); if (ppShader.DiffuseTexture != null && ppShader.DiffuseTexture.HasTextureData && ppShader.OpacityTexture != null && ppShader.OpacityTexture.HasTextureData) { if (ppShader.DiffuseTexture.LoadedTexture == ppShader.OpacityTexture.LoadedTexture) { ppShader.DiffuseTexture = ppShader.OpacityTexture; ppShader.OpacityTexture = null; } } if (ppShader.DiffuseTexture != null && ppShader.DiffuseTexture.HasTextureData && !ppShader.DiffuseTexture.IsVideo && !ppShader.DiffuseTexture.IsCubeRender) { babylonMaterial.diffuseTexture = new BabylonTexture(); DumpTexture(ppShader.DiffuseTexture, babylonMaterial.diffuseTexture, babylonScene); } if (ppShader.AmbientTexture != null && ppShader.AmbientTexture.HasTextureData && !ppShader.AmbientTexture.IsVideo && !ppShader.AmbientTexture.IsCubeRender) { babylonMaterial.ambientTexture = new BabylonTexture(); DumpTexture(ppShader.AmbientTexture, babylonMaterial.ambientTexture, babylonScene); } if (ppShader.OpacityTexture != null && ppShader.OpacityTexture.HasTextureData && !ppShader.OpacityTexture.IsVideo && !ppShader.OpacityTexture.IsCubeRender) { babylonMaterial.opacityTexture = new BabylonTexture(); DumpTexture(ppShader.OpacityTexture, babylonMaterial.opacityTexture, babylonScene); } if (mirrorsMaterials.ContainsKey(ppShader)) { babylonMaterial.reflectionTexture = new BabylonTexture(); var novaObject = mirrorsMaterials[ppShader]; DumpRenderTargetTexture(ppShader.ReflectionTexture, babylonMaterial.reflectionTexture, novaObject.MirrorMapSize, novaObject.MirrorLevel, novaObject.MirroredObjects); AttachMirrorPlane(babylonMaterial.reflectionTexture, novaObject); } else if (ppShader.ReflectionTexture != null && ppShader.ReflectionTexture.HasTextureData && !ppShader.ReflectionTexture.IsVideo && !ppShader.ReflectionTexture.IsCubeRender) { babylonMaterial.reflectionTexture = new BabylonTexture(); DumpTexture(ppShader.ReflectionTexture, babylonMaterial.reflectionTexture, babylonScene); } // Refraction if (ppShader.RefractionLevel > 0) { babylonMaterial.alpha = 1.0f - ppShader.RefractionLevel; } if (ppShader.EmissiveTexture != null && ppShader.EmissiveTexture.HasTextureData && !ppShader.EmissiveTexture.IsVideo && !ppShader.EmissiveTexture.IsCubeRender) { babylonMaterial.emissiveTexture = new BabylonTexture(); DumpTexture(ppShader.EmissiveTexture, babylonMaterial.emissiveTexture, babylonScene); } if (ppShader.SpecularTexture != null && ppShader.SpecularTexture.HasTextureData && !ppShader.SpecularTexture.IsVideo && !ppShader.SpecularTexture.IsCubeRender) { babylonMaterial.specularTexture = new BabylonTexture(); DumpTexture(ppShader.SpecularTexture, babylonMaterial.specularTexture, babylonScene); } if (ppShader.BumpTexture != null && ppShader.BumpTexture.HasTextureData && !ppShader.BumpTexture.IsVideo && !ppShader.BumpTexture.IsCubeRender) { babylonMaterial.bumpTexture = new BabylonTexture(); DumpTexture(ppShader.BumpTexture, babylonMaterial.bumpTexture, babylonScene); babylonMaterial.bumpTexture.level /= 2.0f; } }
private void ExportCommonBabylonAttributes(MFnDependencyNode babylonAttributesDependencyNode, BabylonMaterial babylonMaterial) { bool backfaceCulling = babylonAttributesDependencyNode.findPlug("babylonBackfaceCulling").asBool(); RaiseVerbose("backfaceCulling=" + backfaceCulling, 3); babylonMaterial.backFaceCulling = backfaceCulling; int maxSimultaneousLights = babylonAttributesDependencyNode.findPlug("babylonMaxSimultaneousLights").asInt(); RaiseVerbose("maxSimultaneousLights=" + maxSimultaneousLights, 3); babylonMaterial.maxSimultaneousLights = maxSimultaneousLights; bool unlit = babylonAttributesDependencyNode.findPlug("babylonUnlit").asBool(); RaiseVerbose("unlit=" + unlit, 3); babylonMaterial.isUnlit = unlit; }
private void ExportMaterial(IIGameMaterial materialNode, BabylonScene babylonScene) { var name = materialNode.MaterialName; var id = materialNode.MaxMaterial.GetGuid().ToString(); RaiseMessage(name, 1); if (materialNode.SubMaterialCount > 0) { var babylonMultimaterial = new BabylonMultiMaterial { name = name, id = id }; var guids = new List <string>(); for (var index = 0; index < materialNode.SubMaterialCount; index++) { var subMat = materialNode.GetSubMaterial(index); if (subMat != null) { guids.Add(subMat.MaxMaterial.GetGuid().ToString()); if (!referencedMaterials.Contains(subMat)) { referencedMaterials.Add(subMat); ExportMaterial(subMat, babylonScene); } } else { guids.Add(Guid.Empty.ToString()); } } babylonMultimaterial.materials = guids.ToArray(); babylonScene.MultiMaterialsList.Add(babylonMultimaterial); return; } var babylonMaterial = new BabylonMaterial { name = name, id = id, ambient = materialNode.MaxMaterial.GetAmbient(0, false).ToArray(), diffuse = materialNode.MaxMaterial.GetDiffuse(0, false).ToArray(), specular = materialNode.MaxMaterial.GetSpecular(0, false).Scale(materialNode.MaxMaterial.GetShinStr(0, false)), specularPower = materialNode.MaxMaterial.GetShininess(0, false) * 256, emissive = materialNode.MaxMaterial.GetSelfIllumColorOn(0, false) ? materialNode.MaxMaterial.GetSelfIllumColor(0, false).ToArray() : materialNode.MaxMaterial.GetDiffuse(0, false).Scale(materialNode.MaxMaterial.GetSelfIllum(0, false)), alpha = 1.0f - materialNode.MaxMaterial.GetXParency(0, false) }; var stdMat = materialNode.MaxMaterial.GetParamBlock(0).Owner as IStdMat2; if (stdMat != null) { babylonMaterial.backFaceCulling = !stdMat.TwoSided; babylonMaterial.wireframe = stdMat.Wire; // Textures BabylonFresnelParameters fresnelParameters; babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, out fresnelParameters, babylonScene); // Ambient babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, out fresnelParameters, babylonScene); // Diffuse if (fresnelParameters != null) { babylonMaterial.diffuseFresnelParameters = fresnelParameters; } babylonMaterial.specularTexture = ExportTexture(stdMat, 2, out fresnelParameters, babylonScene); // Specular babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, out fresnelParameters, babylonScene); // Emissive if (fresnelParameters != null) { babylonMaterial.emissiveFresnelParameters = fresnelParameters; if (babylonMaterial.emissive[0] == 0 && babylonMaterial.emissive[1] == 0 && babylonMaterial.emissive[2] == 0 && babylonMaterial.emissiveTexture == null) { babylonMaterial.emissive = new float[] { 1, 1, 1 }; } } babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, out fresnelParameters, babylonScene, false, true); // Opacity if (fresnelParameters != null) { babylonMaterial.opacityFresnelParameters = fresnelParameters; if (babylonMaterial.alpha == 1 && babylonMaterial.opacityTexture == null) { babylonMaterial.alpha = 0; } } babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, out fresnelParameters, babylonScene); // Bump babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, out fresnelParameters, babylonScene, true); // Reflection if (fresnelParameters != null) { if (babylonMaterial.reflectionTexture == null) { RaiseWarning("Fallout cannot be used with reflection channel without a texture", 2); } else { babylonMaterial.reflectionFresnelParameters = fresnelParameters; } } // Constraints if (babylonMaterial.diffuseTexture != null) { babylonMaterial.diffuse = new[] { 1.0f, 1.0f, 1.0f }; } if (babylonMaterial.emissiveTexture != null) { babylonMaterial.emissive = new float[] { 0, 0, 0 }; } if (babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture != null && babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name && babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB) { // This is a alpha testing purpose babylonMaterial.opacityTexture = null; babylonMaterial.diffuseTexture.hasAlpha = true; RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", 2); RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", 2); } } babylonScene.MaterialsList.Add(babylonMaterial); }
private BabylonMaterial DumpMaterial(Material material, Renderer renderer) { if (!materialsDictionary.ContainsKey(material.name)) { var bMat = new BabylonMaterial { name = material.name, id = Guid.NewGuid().ToString(), diffuse = new float[4], specular = new float[4] }; bMat.diffuse[0] = 1.0f; bMat.diffuse[1] = 1.0f; bMat.diffuse[2] = 1.0f; bMat.diffuse[3] = 1.0f; if (material.HasProperty("_Color")) { bMat.diffuse = material.color.ToFloat(); } if (material.HasProperty("_SpecColor")) { var specColor = material.GetColor("_SpecColor"); bMat.specular = specColor.ToFloat(); } if (material.HasProperty("_Shininess")) { var specShininess = material.GetFloat("_Shininess"); bMat.specularPower = specShininess * 128; } if (material.HasProperty("_Emission")) { var emissiveColor = material.GetColor("_Emission"); bMat.emissive = emissiveColor.ToFloat(); } if (material.mainTexture) { var mainTexturePath = AssetDatabase.GetAssetPath(material.mainTexture); bMat.diffuseTexture = new BabylonTexture { uScale = material.mainTextureScale.x, vScale = material.mainTextureScale.y, uOffset = material.mainTextureOffset.x, vOffset = material.mainTextureOffset.y }; var mainTexture2D = material.mainTexture as Texture2D; CopyTexture(mainTexturePath, mainTexture2D, bMat.diffuseTexture); var alphaCuttOff = 0f; if (material.HasProperty("_Cutoff")) { alphaCuttOff = material.GetFloat("_Cutoff"); } if ((mainTexture2D && mainTexture2D.alphaIsTransparency) || alphaCuttOff > 0) { bMat.diffuseTexture.hasAlpha = true; bMat.backFaceCulling = false; } bMat.diffuse[0] = 1.0f; bMat.diffuse[1] = 1.0f; bMat.diffuse[2] = 1.0f; bMat.diffuse[3] = 1.0f; } bMat.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap"); bMat.emissiveTexture = DumpTextureFromMaterial(material, "_Illum"); bMat.ambientTexture = DumpTextureFromMaterial(material, "_LightMap"); bMat.reflectionTexture = DumpTextureFromMaterial(material, "_Cube"); //if (bMat.ambientTexture == null && renderer.lightmapIndex >= 0 && renderer.lightmapIndex != 255 && LightmapSettings.lightmaps.Length > renderer.lightmapIndex) //{ // var lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar; // bMat.ambientTexture = DumpTexture(lightmap); // bMat.ambientTexture.coordinatesIndex = 1; // bMat.ambientTexture.uScale = renderer.lightmapTilingOffset.x; // bMat.ambientTexture.vScale = renderer.lightmapTilingOffset.y; // bMat.ambientTexture.uOffset = renderer.lightmapTilingOffset.z; // bMat.ambientTexture.vOffset = renderer.lightmapTilingOffset.w; //} materialsDictionary.Add(bMat.name, bMat); return(bMat); } return(materialsDictionary[material.name]); }