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); }
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); }
void RemoveMaterialsTextures() { WorkingMaterial.SetTexture("_YTex", null); WorkingMaterial.SetTexture("_UTex", null); WorkingMaterial.SetTexture("_VTex", null); if (HasAlphaChannel) { WorkingMaterial.SetTexture("_ATex", null); } }
void UpdateMaterialsTextures() { WorkingMaterial.SetTexture("_YTex", yTexture); WorkingMaterial.SetTexture("_UTex", uTexture); WorkingMaterial.SetTexture("_VTex", vTexture); if (HasAlphaChannel) { WorkingMaterial.SetTexture("_ATex", aTexture); } }
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); } } }
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); }
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); }
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); }
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; }
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); }
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); }
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; } } } }
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(); } }
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; } }