Browse Source

PBR Exporter update

Sébastien Vandenberghe 9 years ago
parent
commit
27dd429741

+ 27 - 17
Exporters/3ds Max/BabylonExport.Entities/BabylonPBRMaterial.cs

@@ -6,7 +6,7 @@ namespace BabylonExport.Entities
     {
         [DataMember]
         public string customType { get; private set; }
-        
+
         [DataMember]
         public float directIntensity { get; set; }
 
@@ -47,19 +47,19 @@ namespace BabylonExport.Entities
         public float overloadedEmissiveIntensity { get; set; }
 
         [DataMember]
-        public float overloadedAmbient { get; set; }
+        public float[] overloadedAmbient { get; set; }
 
         [DataMember]
-        public float overloadedAlbedo { get; set; }
+        public float[] overloadedAlbedo { get; set; }
 
         [DataMember]
-        public float overloadedReflectivity { get; set; }
+        public float[] overloadedReflectivity { get; set; }
 
         [DataMember]
-        public float overloadedEmissive { get; set; }
+        public float[] overloadedEmissive { get; set; }
 
         [DataMember]
-        public float overloadedReflection { get; set; }
+        public float[] overloadedReflection { get; set; }
 
         [DataMember]
         public float overloadedMicroSurface { get; set; }
@@ -101,19 +101,19 @@ namespace BabylonExport.Entities
         public BabylonTexture refractionTexture { get; set; }
 
         [DataMember]
-        public float[] ambientColor { get; set; }
+        public float[] ambient { get; set; }
 
         [DataMember]
-        public float[] albedoColor { get; set; }
+        public float[] albedo { get; set; }
 
         [DataMember]
-        public float[] reflectivityColor { get; set; }
+        public float[] reflectivity { get; set; }
 
         [DataMember]
-        public float[] reflectionColor { get; set; }
+        public float[] reflection { get; set; }
 
         [DataMember]
-        public float[] emissiveColor { get; set; }
+        public float[] emissive { get; set; }
 
         [DataMember]
         public bool useAlphaFromAlbedoTexture { get; set; }
@@ -128,6 +128,9 @@ namespace BabylonExport.Entities
         public bool useSpecularOverAlpha { get; set; }
 
         [DataMember]
+        public bool useRadianceOverAlpha { get; set; }
+
+        [DataMember]
         public float indexOfRefraction { get; set; }
 
         [DataMember]
@@ -139,7 +142,7 @@ namespace BabylonExport.Entities
         [DataMember]
         public BabylonFresnelParameters opacityFresnelParameters { get; set; }
 
-        public BabylonPBRMaterial(): base()
+        public BabylonPBRMaterial() : base()
         {
             customType = "BABYLON.PBRMaterial";
 
@@ -153,10 +156,17 @@ namespace BabylonExport.Entities
             overloadedShadowIntensity = 1.0f;
             overloadedShadeIntensity = 1.0f;
 
-            ambientColor = new[] { 0f, 0f, 0f };
-            reflectionColor = new[] { 0f, 0f, 0f };
-            emissiveColor = new[] { 0f, 0f, 0f };
+            ambient = new[] { 0f, 0f, 0f };
+            albedo = new[] { 0f, 0f, 0f };
+            reflectivity = new[] { 0f, 0f, 0f };
+            reflection = new[] { 0f, 0f, 0f };
+            emissive = new[] { 0f, 0f, 0f };
+
+            overloadedAmbient = new[] { 0f, 0f, 0f };
+            overloadedAlbedo = new[] { 0f, 0f, 0f };
+            overloadedReflectivity = new[] { 0f, 0f, 0f };
+            overloadedEmissive = new[] { 0f, 0f, 0f };
+            overloadedReflection = new[] { 0f, 0f, 0f };
         }
     }
-}
-;
+}

BIN
Exporters/Unity 5/Unity3D2Babylon/BabylonExport.Entities.dll


File diff suppressed because it is too large
+ 48 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Cameras.cs


+ 292 - 24
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Materials.cs

@@ -41,13 +41,18 @@ namespace Unity3D2Babylon
                         case CubemapFace.NegativeZ:
                             faceTexturePath += "_nz.jpg";
                             break;
+                        default:
+                            continue;
                     }
 
-                    var tempTexture = new Texture2D(cubemap.width, cubemap.height, cubemap.format, false);
+                    var tempTexture = new Texture2D(cubemap.width, cubemap.height, TextureFormat.RGB24, false);
 
                     tempTexture.SetPixels(cubemap.GetPixels(face));
                     tempTexture.Apply();
 
+                    // Flip faces in cube texture.
+                    tempTexture = FlipTexture(tempTexture);
+
                     File.WriteAllBytes(faceTexturePath, tempTexture.EncodeToJPG());
                 }
 
@@ -64,6 +69,22 @@ namespace Unity3D2Babylon
             babylonTexture.coordinatesMode = 3;
         }
 
+        private Texture2D FlipTexture(Texture2D original)
+        {
+            Texture2D flipped = new Texture2D(original.width, original.height);
+
+            for (int i = 0; i < original.width; i++)
+            {
+                for (int j = 0; j < original.height; j++)
+                {
+                    flipped.SetPixel(i, original.height - j - 1, original.GetPixel(i, j));
+                }
+            }
+            flipped.Apply();
+
+            return flipped;
+        }
+
         private void CopyTexture(string texturePath, Texture2D texture2D, BabylonTexture babylonTexture, bool isLightmap = false)
         {
             bool needToDelete = false;
@@ -125,7 +146,7 @@ namespace Unity3D2Babylon
                     textureImporter.convertToNormalmap = previousConvertToNormalmap;
                     textureImporter.textureType = previousTextureType;
                     textureImporter.grayscaleToAlpha = previousGrayscaleToAlpha;
-                   
+
                     AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
                 }
                 catch (Exception ex)
@@ -146,7 +167,21 @@ namespace Unity3D2Babylon
 
         private BabylonMaterial DumpMaterial(Material material, Renderer renderer)
         {
-            var materialNotSupported = false; 
+            if (renderer.sharedMaterial.shader.name == "Standard")
+            {
+                return DumpPBRMaterial(renderer.sharedMaterial, renderer, true);
+            }
+            else if (renderer.sharedMaterial.shader.name == "Standard (Specular setup)")
+            {
+                return DumpPBRMaterial(renderer.sharedMaterial, renderer, false);
+            }
+
+            return DumpStandardMaterial(renderer.sharedMaterial, renderer);
+        }
+
+        private BabylonMaterial DumpStandardMaterial(Material material, Renderer renderer)
+        {
+            var materialNotSupported = false;
 
             if (!materialsDictionary.ContainsKey(material.name))
             {
@@ -252,43 +287,276 @@ namespace Unity3D2Babylon
             return materialsDictionary[material.name];
         }
 
+        private BabylonMaterial DumpPBRMaterial(Material material, Renderer renderer, bool metallic)
+        {
+            if (materialsDictionary.ContainsKey(material.name))
+            {
+                return materialsDictionary[material.name];
+            }
 
-        private BabylonMaterial DumpPBRMaterial(Material material, Renderer renderer)
+            var babylonPbrMaterial = new BabylonPBRMaterial
+            {
+                name = material.name,
+                id = Guid.NewGuid().ToString(),
+                albedo = new float[4],
+                useEmissiveAsIllumination = true,
+                useSpecularOverAlpha = true,
+                useRadianceOverAlpha = true,
+            };
+
+            babylonPbrMaterial.environmentIntensity = RenderSettings.ambientIntensity;
+
+            // Albedo
+            if (material.HasProperty("_Color"))
+            {
+                babylonPbrMaterial.albedo = material.color.ToFloat();
+            }
+            babylonPbrMaterial.albedoTexture = DumpTextureFromMaterial(material, "_MainTex");
+
+            // Transparency
+            DumpTransparency(material, babylonPbrMaterial);
+
+            // Glossiess/Reflectivity
+            DumpGlossinessReflectivity(material, metallic, babylonPbrMaterial);
+
+            // Occlusion
+            babylonPbrMaterial.ambientTexture = DumpTextureFromMaterial(material, "_OcclusionMap");
+            if (babylonPbrMaterial.ambientTexture != null && material.HasProperty("_OcclusionStrength"))
+            {
+                babylonPbrMaterial.ambientTexture.level = material.GetFloat("_OcclusionStrength");
+            }
+
+            // Emissive
+            if (material.HasProperty("_EmissionColor"))
+            {
+                babylonPbrMaterial.emissive = material.GetColor("_EmissionColor").ToFloat();
+            }
+            babylonPbrMaterial.emissiveTexture = DumpTextureFromMaterial(material, "_EmissionMap");
+
+            // Normal
+            babylonPbrMaterial.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap");
+            if (babylonPbrMaterial.bumpTexture != null && material.HasProperty("_BumpMapScale"))
+            {
+                babylonPbrMaterial.bumpTexture.level = material.GetFloat("_BumpMapScale");
+            }
+
+            // Reflection
+            babylonPbrMaterial.reflectionTexture = DumpReflectionTexture();
+
+            materialsDictionary.Add(babylonPbrMaterial.name, babylonPbrMaterial);
+            return babylonPbrMaterial;
+        }
+
+        private void DumpGlossinessReflectivity(Material material, bool metallic, BabylonPBRMaterial babylonPbrMaterial)
         {
-            if (!materialsDictionary.ContainsKey(material.name))
+            if (material.HasProperty("_Glossiness"))
+            {
+                babylonPbrMaterial.microSurface = material.GetFloat("_Glossiness");
+            }
+
+            if (metallic)
             {
-                var bMat = new BabylonPBRMaterial
+                if (material.HasProperty("_Metallic"))
                 {
-                    name = material.name,
-                    id = Guid.NewGuid().ToString(),
-                    albedoColor = new float[4]
-                };
+                    var metalness = material.GetFloat("_Metallic");
+                    babylonPbrMaterial.reflectivity = new float[] { metalness * babylonPbrMaterial.albedo[0],
+                        metalness * babylonPbrMaterial.albedo[1],
+                        metalness * babylonPbrMaterial.albedo[2] };
 
-                if (material.HasProperty("_Color"))
+                    if (babylonPbrMaterial.albedoTexture != null)
+                    {
+                        var albedoTexture = material.GetTexture("_MainTex") as Texture2D;
+                        if (albedoTexture != null)
+                        {
+                            var albedoPixels = GetPixels(albedoTexture);
+                            var reflectivityTexture = new Texture2D(albedoTexture.width, albedoTexture.height, TextureFormat.RGBA32, false);
+                            reflectivityTexture.alphaIsTransparency = true;
+                            babylonPbrMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
+
+                            var metallicTexture = material.GetTexture("_MetallicGlossMap") as Texture2D;
+                            if (metallicTexture == null)
+                            {
+                                for (var i = 0; i < albedoTexture.width; i++)
+                                {
+                                    for (var j = 0; j < albedoTexture.height; j++)
+                                    {
+                                        albedoPixels[j * albedoTexture.width + i].r *= metalness;
+                                        albedoPixels[j * albedoTexture.width + i].g *= metalness;
+                                        albedoPixels[j * albedoTexture.width + i].b *= metalness;
+                                        albedoPixels[j * albedoTexture.width + i].a = babylonPbrMaterial.microSurface;
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                var metallicPixels = GetPixels(metallicTexture);
+                                for (var i = 0; i < albedoTexture.width; i++)
+                                {
+                                    for (var j = 0; j < albedoTexture.height; j++)
+                                    {
+                                        var pixel = albedoPixels[j * albedoTexture.width + i];
+                                        var metallicPixel = metallicPixels[j * albedoTexture.width + i];
+                                        albedoPixels[j * albedoTexture.width + i].r *= metallicPixel.r;
+                                        albedoPixels[j * albedoTexture.width + i].g *= metallicPixel.r;
+                                        albedoPixels[j * albedoTexture.width + i].b *= metallicPixel.r;
+                                        albedoPixels[j * albedoTexture.width + i].a = metallicPixel.a;
+                                    }
+                                }
+                            }
+
+                            reflectivityTexture.SetPixels(albedoPixels);
+                            reflectivityTexture.Apply();
+
+                            var textureName = albedoTexture.name + "_MetallicGlossMap.png";
+                            var babylonTexture = new BabylonTexture { name = textureName };
+                            var textureScale = material.GetTextureScale("_MainTex");
+                            babylonTexture.uScale = textureScale.x;
+                            babylonTexture.vScale = textureScale.y;
+
+                            var textureOffset = material.GetTextureOffset("_MainTex");
+                            babylonTexture.uOffset = textureOffset.x;
+                            babylonTexture.vOffset = textureOffset.y;
+
+                            var reflectivityTexturePath = Path.Combine(Path.GetTempPath(), textureName);
+                            File.WriteAllBytes(reflectivityTexturePath, reflectivityTexture.EncodeToPNG());
+                            babylonScene.AddTexture(reflectivityTexturePath);
+                            if (File.Exists(reflectivityTexturePath))
+                            {
+                                File.Delete(reflectivityTexturePath);
+                            }
+
+                            babylonPbrMaterial.reflectivityTexture = babylonTexture;
+                        }
+                    }
+                    //else
+                    //{
+                    //      TODO. Manage Albedo Cube Texture.
+                    //}
+                }
+            }
+            else
+            {
+
+                if (material.HasProperty("_SpecColor"))
+                {
+                    babylonPbrMaterial.reflectivity = material.GetColor("_SpecColor").ToFloat();
+                }
+                babylonPbrMaterial.reflectivityTexture = DumpTextureFromMaterial(material, "_SpecGlossMap");
+                if (babylonPbrMaterial.reflectivityTexture != null && babylonPbrMaterial.reflectivityTexture.hasAlpha)
                 {
-                    bMat.albedoColor = material.color.ToFloat();
+                    babylonPbrMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
                 }
+            }
+        }
 
-                bMat.albedoTexture = DumpTextureFromMaterial(material, "_MainTex");
+        private static Color[] GetPixels(Texture2D texture)
+        {
+            string texturePath = AssetDatabase.GetAssetPath(texture);
+
+            // Change texture import settings to be able to read texture data
+            var textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
+            var previousIsReadable = textureImporter.isReadable;
+            var previousNormalMap = textureImporter.normalmap;
+            var previousLightmap = textureImporter.lightmap;
+            var previousConvertToNormalmap = textureImporter.convertToNormalmap;
+            var previousTextureType = textureImporter.textureType;
+            var previousGrayscaleToAlpha = textureImporter.grayscaleToAlpha;
+
+            textureImporter.textureType = TextureImporterType.Advanced;
+            textureImporter.isReadable = true;
+            textureImporter.lightmap = false;
+            textureImporter.normalmap = false;
+            textureImporter.convertToNormalmap = false;
+            textureImporter.grayscaleToAlpha = false;
+
+            AssetDatabase.ImportAsset(texturePath);
+
+            var pixels = texture.GetPixels();
+
+            // Restore
+            textureImporter.isReadable = previousIsReadable;
+            textureImporter.normalmap = previousNormalMap;
+            textureImporter.lightmap = previousLightmap;
+            textureImporter.convertToNormalmap = previousConvertToNormalmap;
+            textureImporter.textureType = previousTextureType;
+            textureImporter.grayscaleToAlpha = previousGrayscaleToAlpha;
+
+            return pixels;
+        }
 
-                if (material.HasProperty("_Glossiness"))
+        private static void DumpTransparency(Material material, BabylonPBRMaterial babylonPbrMaterial)
+        {
+            if (material.HasProperty("_Mode"))
+            {
+                var mode = material.GetFloat("_Mode");
+                if (mode == 2.0f)
                 {
-                    bMat.microSurface = material.GetFloat("_Glossiness");
+                    // Transparent Albedo
+                    if (babylonPbrMaterial.albedoTexture != null && babylonPbrMaterial.albedoTexture.hasAlpha)
+                    {
+                        babylonPbrMaterial.useAlphaFromAlbedoTexture = true;
+                    }
+                    // Material Alpha
+                    else
+                    {
+                        babylonPbrMaterial.alpha = babylonPbrMaterial.albedo[3];
+                    }
                 }
-
-                if (material.HasProperty("_Metallic"))
+                else if (mode == 1.0f)
                 {
-                    var metallic = material.GetFloat("_Metallic");
-                    bMat.reflectivityColor = new float[] { metallic, metallic, metallic };
+                    // Cutout
+                    // Follow the texture hasAlpha property.
                 }
+                else
+                {
+                    // Opaque
+                    if (babylonPbrMaterial.albedoTexture != null)
+                    {
+                        babylonPbrMaterial.albedoTexture.hasAlpha = false;
+                    }
+                    babylonPbrMaterial.alpha = 1.0f;
+                }
+            }
+        }
 
-                bMat.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap");
+        private BabylonTexture DumpReflectionTexture()
+        {
+            if (sceneReflectionTexture != null)
+            {
+                return sceneReflectionTexture;
+            }
 
-                materialsDictionary.Add(bMat.name, bMat);
-                return bMat;
+            // Take only reflection source currently and not the RenderSettings.ambientMode
+            if (RenderSettings.defaultReflectionMode == UnityEngine.Rendering.DefaultReflectionMode.Skybox)
+            {
+                var skybox = RenderSettings.skybox;
+                if (skybox != null)
+                {
+                    if (skybox.shader.name == "Skybox/Cubemap")
+                    {
+                        var cubeMap = skybox.GetTexture("_Tex") as Cubemap;
+                        if (cubeMap != null)
+                        {
+                            sceneReflectionTexture = new BabylonTexture();
+                            CopyTextureCube("sceneReflectionTexture.hdr", cubeMap, sceneReflectionTexture);
+                            sceneReflectionTexture.level = RenderSettings.reflectionIntensity;
+                        }
+                    }
+                    //else if (skybox.shader.name == "Skybox/6 Sided")
+                    //{
+                    //    // TODO. HDR faces.
+                    //}
+                }
+            }
+            else if (RenderSettings.customReflection != null)
+            {
+                var cubeMap = RenderSettings.customReflection;
+                sceneReflectionTexture = new BabylonTexture();
+                CopyTextureCube("sceneReflectionTexture.hdr", cubeMap, sceneReflectionTexture);
+                sceneReflectionTexture.level = RenderSettings.reflectionIntensity;
             }
 
-            return materialsDictionary[material.name];
+            return sceneReflectionTexture;
         }
 
         private BabylonTexture DumpTextureFromMaterial(Material material, string name)
@@ -308,6 +576,7 @@ namespace Unity3D2Babylon
             {
                 return null;
             }
+
             var texturePath = AssetDatabase.GetAssetPath(texture);
             var textureName = Path.GetFileName(texturePath);
             var babylonTexture = new BabylonTexture { name = textureName };
@@ -324,7 +593,6 @@ namespace Unity3D2Babylon
             }
 
             var texture2D = texture as Texture2D;
-
             if (texture2D)
             {
                 babylonTexture.hasAlpha = texture2D.alphaIsTransparency;

+ 2 - 16
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.Meshes.cs

@@ -164,14 +164,7 @@ namespace Unity3D2Babylon
                                 var sharedMaterial = renderer.sharedMaterials[i];
                                 BabylonMaterial babylonMaterial;
 
-                                if (sharedMaterial.HasProperty("_Metallic"))
-                                {
-                                    babylonMaterial = DumpPBRMaterial(sharedMaterial, renderer);
-                                }
-                                else
-                                {
-                                    babylonMaterial = DumpMaterial(sharedMaterial, renderer);
-                                }
+                                babylonMaterial = DumpMaterial(sharedMaterial, renderer);
 
                                 bMultiMat.materials[i] = babylonMaterial.id;
                             }
@@ -207,14 +200,7 @@ namespace Unity3D2Babylon
                     }
                     else
                     {
-                        if (renderer.sharedMaterial.HasProperty("_Metallic"))
-                        {
-                            babylonMesh.materialId = DumpPBRMaterial(renderer.sharedMaterial, renderer).id;
-                        }
-                        else
-                        {
-                            babylonMesh.materialId = DumpMaterial(renderer.sharedMaterial, renderer).id;
-                        }
+                        babylonMesh.materialId = DumpMaterial(renderer.sharedMaterial, renderer).id;
                     }
                 }
 

+ 3 - 0
Exporters/Unity 5/Unity3D2Babylon/SceneBuilder.cs

@@ -25,6 +25,8 @@ namespace Unity3D2Babylon
 
         readonly ExportationOptions exportationOptions;
 
+        BabylonTexture sceneReflectionTexture;
+
         public SceneBuilder(string outputPath, string sceneName, ExportationOptions exportationOptions)
         {
             OutputPath = outputPath;
@@ -143,6 +145,7 @@ namespace Unity3D2Babylon
                 if (camera != null)
                 {
                     ConvertUnityCameraToBabylon(camera, progress);
+                    ConvertUnitySkyboxToBabylon(camera, progress);
                     continue;
                 }