public IEnumerator GenerateHLODInstancing(bool propagateUpwards = true, int treeHeight = 2, GameObject hlods = null) { if (ChildDeep() <= treeHeight) { HashSet <Renderer> hlodRenderers = new HashSet <Renderer>(); Renderer[] renderers = GetAllRendererByLodGroups(); foreach (var r in renderers) { var mr = r as MeshRenderer; if (mr) { //hlodRenderers.Add(mr); // Use the coarsest LOD if it exists var mrLODGroup = mr.GetComponentInParent <LODGroup>(); if (mrLODGroup) { var mrLODs = mrLODGroup.GetLODs(); var maxLOD = mrLODGroup.lodCount - 1; var mrLOD = mrLODs[maxLOD]; foreach (var lr in mrLOD.renderers) { if (lr && lr.GetComponent <MeshFilter>()) { hlodRenderers.Add(lr); } } } else if (mr.GetComponent <MeshFilter>()) { hlodRenderers.Add(mr); } } yield return(null); } var lodRenderers = new List <Renderer>(); CleanupHLOD(); GameObject hlodRoot = new GameObject(transform.name); hlodRoot.transform.parent = hlods.transform; var parent = hlodRoot.transform; foreach (var r in hlodRenderers) { var rendererTransform = r.transform; var child = new GameObject(r.name, typeof(MeshFilter), typeof(MeshRenderer)); var childTransform = child.transform; childTransform.SetPositionAndRotation(rendererTransform.position, rendererTransform.rotation); childTransform.localScale = rendererTransform.lossyScale; childTransform.SetParent(parent, true); var mr = child.GetComponent <MeshRenderer>(); EditorUtility.CopySerialized(r.GetComponent <MeshFilter>(), child.GetComponent <MeshFilter>()); EditorUtility.CopySerialized(r.GetComponent <MeshRenderer>(), mr); lodRenderers.Add(mr); } LOD lod = new LOD(); var lodGroup = hlodRoot.GetComponent <LODGroup>(); if (!lodGroup) { lodGroup = hlodRoot.AddComponent <LODGroup>(); } lodGroup.enabled = false; UnityLODGroupFast lodGroupFast = ScriptableObject.CreateInstance <UnityLODGroupFast>(); lodGroupFast.Init(lodGroup, hlodRoot); this.combined = lodGroupFast; EditorUtility.DisplayProgressBar("合并网格和贴图", name, 0.8f); var batcher = (IBatcher)Activator.CreateInstance(ObjectUtils.batcherType); yield return(batcher.Batch(m_CurrHLODGenerate, this)); lod.renderers = hlodRoot.GetComponentsInChildren <Renderer>(false); lodGroup.SetLODs(new LOD[] { lod }); //lodGroup.size += 5;//lod屏幕占比偏差 if (propagateUpwards) { var lodVolumeParent = transform.parent; var parentLODVolume = lodVolumeParent ? lodVolumeParent.GetComponentInParent <LODVolume>() : null; if (parentLODVolume) { yield return(parentLODVolume.GenerateHLODInstancing()); } } hlodRoot.GetComponent <MeshRenderer>().enabled = false; } }
IEnumerator UpdateOctreeByLodGroup(GameObject[] gameObjects = null) { if (gameObjects == null || gameObjects.Count() < 1) { yield break; } if (!m_RootVolume) { if (m_CreateRootVolumeForScene == SceneManager.GetActiveScene().name) { #if UNITY_EDITOR m_RootVolume = LODVolume.Create(m_CurrHLODGenerate); #endif } else { yield break; } } var lodGroups = m_FoundLODGroups; lodGroups.Clear(); foreach (var objRoot in gameObjects) { LODGroup [] childGroups = objRoot.GetComponentsInChildren <LODGroup>(); lodGroups.AddRange(childGroups); } // Remove any renderers that should not be there (e.g. HLODs) lodGroups.RemoveAll(r => m_ExcludedLODGroups.Contains(r) ); lodGroups.RemoveAll(l => { if (l) { // Check against previous collection if (m_ExcludedLODGroups.Contains(l)) { return(false); } var rds = l.GetLODs()[0].renderers; foreach (var r in rds) { if (r == null) { return(false); } var mf = r.GetComponent <MeshFilter>(); if (!mf || (mf.sharedMesh && mf.sharedMesh.GetTopology(0) != MeshTopology.Triangles)) { m_ExcludedLODGroups.Add(l); return(true); } #if UNITY_EDITOR //根据包围盒直径进行剔除不需要计算的模型 if (m_CurrHLODGenerate.m_BVHDivide.m_Cull) { bool result = m_CurrHLODGenerate.m_BVHDivide.CullByMesh(r.transform); if (result) { m_ExcludedLODGroups.Add(l); return(true); } } #endif } } return(false); }); var existingLODGroups = m_ExistingLODGroups; existingLODGroups.Clear(); existingLODGroups.UnionWith(m_RootVolume.lodGroups.Select(l => l._lodGroup)); var removed = m_RemovedLODGroups; removed.Clear(); removed.UnionWith(m_ExistingLODGroups); removed.ExceptWith(lodGroups); var added = m_AddedLODGroups; added.Clear(); added.UnionWith(lodGroups); added.ExceptWith(existingLODGroups); int count = 1; foreach (var l in removed) { if (existingLODGroups.Contains(l)) { #if UNITY_EDITOR yield return(m_RootVolume.RemoveLodGroup(l)); #endif // Check if the BVH shrunk yield return(SetRootLODVolume()); } } count = 1; foreach (var l in added) { EditorUtility.DisplayProgressBar("网格划分", l.name, (float)count++ / added.Count); if (!existingLODGroups.Contains(l)) { UnityLODGroupFast lodGroupFast = CreateInstance <UnityLODGroupFast>(); #if UNITY_EDITOR lodGroupFast.Init(l, l.gameObject); //UnityLODGroupFast lodGroupFast = new UnityLODGroupFast(l, l.gameObject); yield return(m_RootVolume.AddLodGroup(lodGroupFast)); #endif l.transform.hasChanged = false; // Check if the BVH grew yield return(SetRootLODVolume()); } } }