Exemple #1
0
        static WorkingMaterial CreateMaterial(string guidstr, Dictionary <string, WorkingTexture> textures)
        {
            WorkingMaterial material = null;
            string          path     = AssetDatabase.GUIDToAssetPath(guidstr);

            if (string.IsNullOrEmpty(path) == false)
            {
                Material mat = AssetDatabase.LoadAssetAtPath <Material>(path);
                if (mat != null)
                {
                    material = new WorkingMaterial(Allocator.Invalid, mat.GetInstanceID(), mat.name);
                }
            }

            if (material == null)
            {
                material = new WorkingMaterial(Allocator.Persistent, new Material(Shader.Find("Standard")));
            }

            foreach (var texture in textures)
            {
                material.AddTexture(texture.Key, texture.Value.Clone());
            }

            return(material);
        }
Exemple #2
0
        private WorkingMaterial CreateBakedMaterial(string name, Bounds bounds, bool useHighMaterial)
        {
            int    matInstanceID = useHighMaterial ? m_terrainMaterialInstanceId : m_terrainMaterialLowInstanceId;
            string matName       = useHighMaterial ? m_terrainMaterialName : m_terrainMaterialLowName;

            WorkingMaterial material = new WorkingMaterial(Allocator.Persistent, matInstanceID, matName);

            material.Name = name + "_Material";

            m_queue.EnqueueJob(() =>
            {
                WorkingTexture albedo = BakeAlbedo(name, bounds, m_hlod.TextureSize);
                material.AddTexture(m_hlod.AlbedoPropertyName, albedo);
            });

            if (m_hlod.UseNormal)
            {
                m_queue.EnqueueJob(() =>
                {
                    WorkingTexture normal = BakeNormal(name, bounds, m_hlod.TextureSize);
                    material.AddTexture(m_hlod.NormalPropertyName, normal);
                });
            }

            if (m_hlod.UseMask)
            {
                m_queue.EnqueueJob(() =>
                {
                    WorkingTexture mask = BakeMask(name, bounds, m_hlod.TextureSize);
                    material.AddTexture(m_hlod.MaskPropertyName, mask);
                });
            }

            return(material);
        }
Exemple #3
0
 void RemoveMaterialsTextures()
 {
     WorkingMaterial.SetTexture("_YTex", null);
     WorkingMaterial.SetTexture("_UTex", null);
     WorkingMaterial.SetTexture("_VTex", null);
     if (HasAlphaChannel)
     {
         WorkingMaterial.SetTexture("_ATex", null);
     }
 }
Exemple #4
0
 void UpdateMaterialsTextures()
 {
     WorkingMaterial.SetTexture("_YTex", yTexture);
     WorkingMaterial.SetTexture("_UTex", uTexture);
     WorkingMaterial.SetTexture("_VTex", vTexture);
     if (HasAlphaChannel)
     {
         WorkingMaterial.SetTexture("_ATex", aTexture);
     }
 }
Exemple #5
0
        private void Combine(Vector3 rootPosition, HLODBuildInfo info)
        {
            var materialTable = new Dictionary <string, WorkingMaterial>();
            var combineInfos  = new Dictionary <string, List <MeshCombiner.CombineInfo> >();

            for (int i = 0; i < info.WorkingObjects.Count; ++i)
            {
                var materials = info.WorkingObjects[i].Materials;
                for (int m = 0; m < materials.Count; ++m)
                {
                    //var mat = materials[m];
                    MeshCombiner.CombineInfo combineInfo = new MeshCombiner.CombineInfo();

                    combineInfo.Transform      = info.WorkingObjects[i].LocalToWorld;
                    combineInfo.Transform.m03 -= rootPosition.x;
                    combineInfo.Transform.m13 -= rootPosition.y;
                    combineInfo.Transform.m23 -= rootPosition.z;
                    combineInfo.Mesh           = info.WorkingObjects[i].Mesh;
                    combineInfo.MeshIndex      = m;

                    if (combineInfos.ContainsKey(materials[m].Identifier) == false)
                    {
                        combineInfos.Add(materials[m].Identifier, new List <MeshCombiner.CombineInfo>());
                        materialTable.Add(materials[m].Identifier, materials[m]);
                    }

                    combineInfos[materials[m].Identifier].Add(combineInfo);
                }
            }

            using (var originWorkingObject = info.WorkingObjects)
            {
                DisposableList <WorkingObject> combinedObjects = new DisposableList <WorkingObject>();
                info.WorkingObjects = combinedObjects;

                MeshCombiner combiner = new MeshCombiner();
                foreach (var pair in combineInfos)
                {
                    WorkingMesh     combinedMesh   = combiner.CombineMesh(Allocator.Persistent, pair.Value);
                    WorkingObject   combinedObject = new WorkingObject(Allocator.Persistent);
                    WorkingMaterial material       = materialTable[pair.Key].Clone();

                    combinedMesh.name   = info.Name + "_Mesh" + pair.Key;
                    combinedObject.Name = info.Name;
                    combinedObject.SetMesh(combinedMesh);
                    combinedObject.Materials.Add(material);

                    combinedObjects.Add(combinedObject);
                }
            }
        }
Exemple #6
0
        private void Combine(Vector3 rootPosition, TexturePacker packer, HLODBuildInfo info, dynamic options)
        {
            var atlas = packer.GetAtlas(info);

            if (atlas == null)
            {
                return;
            }

            List <TextureInfo> textureInfoList           = options.TextureInfoList;
            List <MeshCombiner.CombineInfo> combineInfos = new List <MeshCombiner.CombineInfo>();

            for (int i = 0; i < info.WorkingObjects.Count; ++i)
            {
                var obj = info.WorkingObjects[i];
                ConvertMesh(obj.Mesh, obj.Materials, atlas, textureInfoList[0].InputName);

                for (int si = 0; si < obj.Mesh.subMeshCount; ++si)
                {
                    var ci = new MeshCombiner.CombineInfo();
                    ci.Mesh      = obj.Mesh;
                    ci.MeshIndex = si;

                    ci.Transform      = obj.LocalToWorld;
                    ci.Transform.m03 -= rootPosition.x;
                    ci.Transform.m13 -= rootPosition.y;
                    ci.Transform.m23 -= rootPosition.z;

                    combineInfos.Add(ci);
                }
            }

            MeshCombiner combiner     = new MeshCombiner();
            WorkingMesh  combinedMesh = combiner.CombineMesh(Allocator.Persistent, combineInfos);

            WorkingObject   newObj = new WorkingObject(Allocator.Persistent);
            WorkingMaterial newMat = m_createdMaterials[atlas].Clone();

            combinedMesh.name = info.Name + "_Mesh";
            newObj.Name       = info.Name;
            newObj.SetMesh(combinedMesh);
            newObj.Materials.Add(newMat);

            info.WorkingObjects.Dispose();
            info.WorkingObjects = new DisposableList <WorkingObject>();
            info.WorkingObjects.Add(newObj);
        }
Exemple #7
0
            public TexturePacker.MaterialTexture GetMaterialTextures(WorkingMaterial material)
            {
                if (m_textureCache.ContainsKey(material.Guid) == false)
                {
                    AddToCache(material);
                }

                var textures = m_textureCache[material.Guid];

                if (textures != null)
                {
                    string inputName = m_textureInfoList[0].InputName;
                    material.SetTexture(inputName, textures[0].Clone());
                }

                return(textures);
            }
Exemple #8
0
            private void AddToCache(WorkingMaterial material)
            {
                string         inputName = m_textureInfoList[0].InputName;
                WorkingTexture texture   = material.GetTexture(inputName);

                if (texture == null)
                {
                    texture = m_defaultTextures[m_textureInfoList[0].Type];
                }

                TexturePacker.MaterialTexture materialTexture = new TexturePacker.MaterialTexture();

                if (m_enableTintColor)
                {
                    Color tintColor = material.GetColor(m_tintColorName);

                    texture = texture.Clone();
                    ApplyTintColor(texture, tintColor);
                    materialTexture.Add(texture);
                    texture.Dispose();
                }
                else
                {
                    materialTexture.Add(texture);
                }


                for (int ti = 1; ti < m_textureInfoList.Count; ++ti)
                {
                    string         input = m_textureInfoList[ti].InputName;
                    WorkingTexture tex   = material.GetTexture(input);

                    if (tex == null)
                    {
                        tex = m_defaultTextures[m_textureInfoList[ti].Type];
                    }

                    materialTexture.Add(tex);
                }

                m_textureCache.Add(material.Guid, materialTexture);
            }
Exemple #9
0
            public void From(WorkingMaterial material)
            {
                m_name = material.Name;
                bool needWrite = material.NeedWrite();

                if (needWrite)
                {
                    Material mat = material.ToMaterial();
                    m_jsonData  = EditorJsonUtility.ToJson(mat);
                    m_assetGuid = "";
                }
                else
                {
                    m_jsonData = "";
                    string path = AssetDatabase.GetAssetPath(material.InstanceID);
                    m_assetGuid = AssetDatabase.AssetPathToGUID(path);
                }

                m_id = material.Guid;
            }
Exemple #10
0
        private WorkingObject CreateBakedTerrain(string name, Bounds bounds, Heightmap heightmap, int distance)
        {
            WorkingObject wo = new WorkingObject(Allocator.Persistent);

            wo.Name = name;


            m_queue.EnqueueJob(() =>
            {
                WorkingMesh mesh = CreateBakedGeometry(name, heightmap, bounds, distance);
                wo.SetMesh(mesh);
            });

            m_queue.EnqueueJob(() =>
            {
                WorkingMaterial material = CreateBakedMaterial(name, bounds);
                wo.Materials.Add(material);
            });


            return(wo);
        }
Exemple #11
0
        private WorkingObject CreateBakedTerrain(string name, Bounds bounds, Heightmap heightmap, int distance, bool isLeaf)
        {
            WorkingObject wo = new WorkingObject(Allocator.Persistent);

            wo.Name            = name;
            wo.LightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;

            m_queue.EnqueueJob(() =>
            {
                WorkingMesh mesh = CreateBakedGeometry(name, heightmap, bounds, distance);
                wo.SetMesh(mesh);
            });

            m_queue.EnqueueJob(() =>
            {
                WorkingMaterial material = CreateBakedMaterial(name, bounds, isLeaf);
                wo.Materials.Add(material);
            });


            return(wo);
        }
Exemple #12
0
        private WorkingMaterial CreateBakedMaterial(string name, Bounds bounds)
        {
            WorkingMaterial material = new WorkingMaterial(Allocator.Persistent, m_terrainMaterialInstanceId, m_terrainMaterialName);

            material.Name = name + "_Material";

            m_queue.EnqueueJob(() =>
            {
                WorkingTexture albedo = BakeAlbedo(name, bounds, m_hlod.TextureSize);
                material.AddTexture(m_hlod.AlbedoPropertyName, albedo);
            });

            if (m_hlod.UseNormal)
            {
                m_queue.EnqueueJob(() =>
                {
                    WorkingTexture normal = BakeNormal(name, bounds, m_hlod.TextureSize);
                    material.AddTexture(m_hlod.NormalPropertyName, normal);
                });
            }

            return(material);
        }
        private void ExtractMaterial(Dictionary <int, HLODData> hlodDatas, string filenamePrefix)
        {
            Dictionary <string, HLODData.SerializableMaterial> hlodAllMaterials = new Dictionary <string, HLODData.SerializableMaterial>();

            //collect all materials
            foreach (var hlodData in hlodDatas.Values)
            {
                var hlodMaterials = hlodData.GetMaterials();
                for (int mi = 0; mi < hlodMaterials.Count; ++mi)
                {
                    if (hlodAllMaterials.ContainsKey(hlodMaterials[mi].ID) == false)
                    {
                        hlodAllMaterials.Add(hlodMaterials[mi].ID, hlodMaterials[mi]);
                    }
                }
            }

            Dictionary <string, HLODData.SerializableMaterial> extractedMaterials = new Dictionary <string, HLODData.SerializableMaterial>();

            //save files to disk
            foreach (var hlodMaterial in hlodAllMaterials)
            {
                hlodMaterial.Value.GetTextureCount();
                Material mat = hlodMaterial.Value.To();

                for (int ti = 0; ti < hlodMaterial.Value.GetTextureCount(); ++ti)
                {
                    var       serializeTexture = hlodMaterial.Value.GetTexture(ti);
                    Texture2D texture          = serializeTexture.To();
                    byte[]    bytes            = texture.EncodeToPNG();
                    string    textureFilename  = $"{filenamePrefix}_{mat.name}_{serializeTexture.TextureName}.png";
                    File.WriteAllBytes(textureFilename, bytes);

                    AssetDatabase.ImportAsset(textureFilename);

                    var assetImporter   = AssetImporter.GetAtPath(textureFilename);
                    var textureImporter = assetImporter as TextureImporter;

                    if (textureImporter)
                    {
                        textureImporter.wrapMode    = serializeTexture.WrapMode;
                        textureImporter.sRGBTexture = GraphicsFormatUtility.IsSRGBFormat(serializeTexture.GraphicsFormat);
                        textureImporter.SaveAndReimport();
                    }

                    var storedTexture = AssetDatabase.LoadAssetAtPath <Texture>(textureFilename);
                    m_manager.AddGeneratedResource(storedTexture);
                    mat.SetTexture(serializeTexture.Name, storedTexture);
                }

                string matFilename = $"{filenamePrefix}_{mat.name}.mat";
                AssetDatabase.CreateAsset(mat, matFilename);
                AssetDatabase.ImportAsset(matFilename);

                var storedMaterial = AssetDatabase.LoadAssetAtPath <Material>(matFilename);
                m_manager.AddGeneratedResource(storedMaterial);


                using (WorkingMaterial newWM = new WorkingMaterial(Collections.Allocator.Temp, storedMaterial))
                {
                    var newSM = new HLODData.SerializableMaterial();
                    newSM.From(newWM);

                    extractedMaterials.Add(hlodMaterial.Key, newSM);
                }
            }

            //apply to HLODData
            foreach (var hlodData in hlodDatas.Values)
            {
                var materials = hlodData.GetMaterials();
                for (int i = 0; i < materials.Count; ++i)
                {
                    if (extractedMaterials.ContainsKey(materials[i].ID) == false)
                    {
                        continue;
                    }

                    materials[i] = extractedMaterials[materials[i].ID];
                }

                var objects = hlodData.GetObjects();
                for (int oi = 0; oi < objects.Count; ++oi)
                {
                    var matIds = objects[oi].GetMaterialIds();

                    for (int mi = 0; mi < matIds.Count; ++mi)
                    {
                        if (extractedMaterials.ContainsKey(matIds[mi]) == false)
                        {
                            continue;
                        }

                        matIds[mi] = extractedMaterials[matIds[mi]].ID;
                    }
                }
            }
        }
Exemple #14
0
        public IEnumerator CreateImpl()
        {
            try
            {
                using (m_queue = new JobQueue(8))
                {
                    Stopwatch sw = new Stopwatch();

                    AssetDatabase.Refresh();
                    AssetDatabase.SaveAssets();

                    sw.Reset();
                    sw.Start();

                    EditorUtility.DisplayProgressBar("Bake HLOD", "Initialize Bake", 0.0f);


                    TerrainData data = m_hlod.TerrainData;

                    m_size = data.size;

                    m_heightmap = new Heightmap(data.heightmapResolution, data.heightmapResolution, data.size,
                                                data.GetHeights(0, 0, data.heightmapResolution, data.heightmapResolution));

                    string materialPath = AssetDatabase.GUIDToAssetPath(m_hlod.MaterialGUID);
                    m_terrainMaterial = AssetDatabase.LoadAssetAtPath <Material>(materialPath);
                    if (m_terrainMaterial == null)
                    {
                        m_terrainMaterial = new Material(Shader.Find("Standard"));
                    }

                    m_terrainMaterialInstanceId = m_terrainMaterial.GetInstanceID();
                    m_terrainMaterialName       = m_terrainMaterial.name;

                    using (m_alphamaps = new DisposableList <WorkingTexture>())
                        using (m_layers = new DisposableList <Layer>())
                        {
                            for (int i = 0; i < data.alphamapTextures.Length; ++i)
                            {
                                m_alphamaps.Add(new WorkingTexture(Allocator.Persistent, data.alphamapTextures[i]));
                            }

                            for (int i = 0; i < data.terrainLayers.Length; ++i)
                            {
                                m_layers.Add(new Layer(data.terrainLayers[i]));
                            }


                            QuadTreeSpaceSplitter splitter =
                                new QuadTreeSpaceSplitter(0.0f);

                            SpaceNode rootNode = splitter.CreateSpaceTree(m_hlod.GetBounds(), m_hlod.ChunkSize * 2.0f,
                                                                          m_hlod.transform.position, null, progress => { });

                            EditorUtility.DisplayProgressBar("Bake HLOD", "Create mesh", 0.0f);

                            using (DisposableList <HLODBuildInfo> buildInfos = CreateBuildInfo(data, rootNode))
                            {
                                yield return(m_queue.WaitFinish());

                                //Write material & textures

                                for (int i = 0; i < buildInfos.Count; ++i)
                                {
                                    int curIndex = i;
                                    m_queue.EnqueueJob(() =>
                                    {
                                        ISimplifier simplifier = (ISimplifier)Activator.CreateInstance(m_hlod.SimplifierType,
                                                                                                       new object[] { m_hlod.SimplifierOptions });
                                        simplifier.SimplifyImmidiate(buildInfos[curIndex]);
                                    });
                                }

                                EditorUtility.DisplayProgressBar("Bake HLOD", "Simplify meshes", 0.0f);
                                yield return(m_queue.WaitFinish());

                                Debug.Log("[TerrainHLOD] Simplify: " + sw.Elapsed.ToString("g"));
                                sw.Reset();
                                sw.Start();
                                EditorUtility.DisplayProgressBar("Bake HLOD", "Make border", 0.0f);

                                for (int i = 0; i < buildInfos.Count; ++i)
                                {
                                    HLODBuildInfo info = buildInfos[i];
                                    m_queue.EnqueueJob(() =>
                                    {
                                        for (int oi = 0; oi < info.WorkingObjects.Count; ++oi)
                                        {
                                            WorkingObject o       = info.WorkingObjects[oi];
                                            int borderVertexCount = m_hlod.BorderVertexCount * Mathf.RoundToInt(Mathf.Pow(2.0f, (float)info.Distances[oi]));
                                            using (WorkingMesh m = MakeBorder(o.Mesh, info.Heightmap, borderVertexCount))
                                            {
                                                ReampUV(m, info.Heightmap);
                                                o.SetMesh(MakeFillHoleMesh(m));
                                            }
                                        }
                                    });
                                }
                                yield return(m_queue.WaitFinish());

                                Debug.Log("[TerrainHLOD] Make Border: " + sw.Elapsed.ToString("g"));
                                sw.Reset();
                                sw.Start();


                                for (int i = 0; i < buildInfos.Count; ++i)
                                {
                                    SpaceNode     node = buildInfos[i].Target;
                                    HLODBuildInfo info = buildInfos[i];
                                    if (node.HasChild() == false)
                                    {
                                        SpaceNode parent = node.ParentNode;
                                        node.ParentNode = null;

                                        GameObject go = new GameObject(buildInfos[i].Name);

                                        for (int wi = 0; wi < info.WorkingObjects.Count; ++wi)
                                        {
                                            WorkingObject wo       = info.WorkingObjects[wi];
                                            GameObject    targetGO = null;
                                            if (wi == 0)
                                            {
                                                targetGO = go;
                                            }
                                            else
                                            {
                                                targetGO = new GameObject(wi.ToString());
                                                targetGO.transform.SetParent(go.transform, false);
                                            }

                                            List <Material> materials = new List <Material>();
                                            for (int mi = 0; mi < wo.Materials.Count; ++mi)
                                            {
                                                WorkingMaterial wm = wo.Materials[mi];
                                                if (wm.NeedWrite() == false)
                                                {
                                                    materials.Add(wm.ToMaterial());
                                                    continue;
                                                }

                                                Material mat          = new Material(wm.ToMaterial());
                                                string[] textureNames = wm.GetTextureNames();
                                                for (int ti = 0; ti < textureNames.Length; ++ti)
                                                {
                                                    WorkingTexture wt  = wm.GetTexture(textureNames[ti]);
                                                    Texture2D      tex = wt.ToTexture();
                                                    tex.wrapMode = wt.WrapMode;
                                                    mat.name     = targetGO.name + "_Mat";
                                                    mat.SetTexture(textureNames[ti], tex);
                                                }
                                                mat.EnableKeyword("_NORMALMAP");
                                                materials.Add(mat);
                                            }

                                            targetGO.AddComponent <MeshFilter>().sharedMesh        = wo.Mesh.ToMesh();
                                            targetGO.AddComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                                        }

                                        go.transform.SetParent(m_hlod.transform, false);
                                        m_hlod.AddGeneratedResource(go);

                                        parent.Objects.Add(go);
                                        buildInfos.RemoveAt(i);
                                        i -= 1;
                                    }
                                }

                                //controller
                                IStreamingBuilder builder =
                                    (IStreamingBuilder)Activator.CreateInstance(m_hlod.StreamingType,
                                                                                new object[] { m_hlod, m_hlod.StreamingOptions });

                                builder.Build(rootNode, buildInfos, m_hlod.gameObject, m_hlod.CullDistance, m_hlod.LODDistance, true, false,
                                              progress =>
                                {
                                    EditorUtility.DisplayProgressBar("Bake HLOD", "Storing results.",
                                                                     0.75f + progress * 0.25f);
                                });

                                Debug.Log("[TerrainHLOD] Build: " + sw.Elapsed.ToString("g"));
                            }
                        }

                    EditorUtility.SetDirty(m_hlod.gameObject);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                GC.Collect();
            }
        }
Exemple #15
0
        private void PackingTexture(TexturePacker packer, DisposableList <HLODBuildInfo> targets, dynamic options, Action <float> onProgress)
        {
            List <TextureInfo> textureInfoList = options.TextureInfoList;

            using (MaterialTextureCache cache = new MaterialTextureCache(options))
            {
                for (int i = 0; i < targets.Count; ++i)
                {
                    var workingObjects = targets[i].WorkingObjects;
                    Dictionary <Guid, TexturePacker.MaterialTexture> textures =
                        new Dictionary <Guid, TexturePacker.MaterialTexture>();

                    for (int oi = 0; oi < workingObjects.Count; ++oi)
                    {
                        var materials = workingObjects[oi].Materials;

                        for (int m = 0; m < materials.Count; ++m)
                        {
                            var materialTextures = cache.GetMaterialTextures(materials[m]);
                            if (materialTextures == null)
                            {
                                continue;
                            }

                            if (textures.ContainsKey(materialTextures[0].GetGUID()) == true)
                            {
                                continue;
                            }

                            textures.Add(materialTextures[0].GetGUID(), materialTextures);
                        }
                    }


                    packer.AddTextureGroup(targets[i], textures.Values.ToList());


                    if (onProgress != null)
                    {
                        onProgress(((float)i / targets.Count) * 0.1f);
                    }
                }
            }

            packer.Pack(TextureFormat.RGBA32, options.PackTextureSize, options.LimitTextureSize, false);
            if (onProgress != null)
            {
                onProgress(0.3f);
            }

            int index   = 1;
            var atlases = packer.GetAllAtlases();

            foreach (var atlas in atlases)
            {
                Dictionary <string, WorkingTexture> textures = new Dictionary <string, WorkingTexture>();
                for (int i = 0; i < atlas.Textures.Count; ++i)
                {
                    WorkingTexture wt = atlas.Textures[i];
                    wt.Name = "CombinedTexture " + index + "_" + i;
                    if (textureInfoList[i].Type == PackingType.Normal)
                    {
                        wt.Linear = true;
                    }

                    textures.Add(textureInfoList[i].OutputName, wt);
                }

                WorkingMaterial mat = CreateMaterial(options.MaterialGUID, textures);
                mat.Name = "CombinedMaterial " + index;
                m_createdMaterials.Add(atlas, mat);
                index += 1;
            }
        }