// 处理摄影机问题 private void Update() { if (m_Targets != null && m_Targets.IsVaild) { PVSManager.GetInstance().UpdateViewer(this, onChged); } }
/// <summary> /// initialize PVS manager. /// </summary> /// <param name="pvsManager">the PVS manager.</param> public static void InitPVSManager(PVSManager pvsManager) { pvsManager.debugPlanes = new List <PVSManager.Plane>(); pvsManager.debugLines = new List <PVSManager.Line>(); var currentScene = SceneManager.GetActiveScene(); var allRootGos = new List <GameObject>(); currentScene.GetRootGameObjects(allRootGos); var worldBounds = new Bounds(Vector3.zero, Vector3.zero); var renderers = new List <Renderer>(); var colliders = new List <Renderer>(); foreach (var go in allRootGos) { WalkThroughTransformTree(go.transform, (tr) => { var renderer = tr.GetComponent <Renderer>(); if (!renderer || !tr.gameObject.isStatic) { return; } worldBounds.Encapsulate(renderer.bounds); if (renderer.gameObject.tag == "PVS") { renderers.Add(renderer); } colliders.Add(renderer); }); } var counts = new Vector3(math.ceil(worldBounds.size.x / pvsManager.cellSize.x), math.ceil(worldBounds.size.y / pvsManager.cellSize.y), math.ceil(worldBounds.size.z / pvsManager.cellSize.z)); worldBounds.size = new Vector3(counts.x * pvsManager.cellSize.x, counts.y * pvsManager.cellSize.y, counts.z * pvsManager.cellSize.z); pvsManager.worldBounds = worldBounds; pvsManager.renderers = renderers; pvsManager.colliders = colliders; pvsManager.AllocVisibleFlags(); Debug.Log($"{sizeof(int) * pvsManager.visibleFlags.Length} bytes were allocated for visible flags."); pvsManager.accelerationStructure = new RayTracingAccelerationStructure(); var subMeshFlagArray = new bool[32]; var subMeshCutoffArray = new bool[32]; for (var i = 0; i < 32; ++i) { subMeshFlagArray[i] = true; subMeshCutoffArray[i] = false; } foreach (var renderer in colliders) { pvsManager.accelerationStructure.AddInstance(renderer, subMeshFlagArray, subMeshCutoffArray); } pvsManager.accelerationStructure.Build(); }
/// <summary> /// Unity OnGUI. /// </summary> public void OnGUI() { _pvsManager = EditorGUILayout.ObjectField("PVS Manager", _pvsManager, typeof(PVSManager), true) as PVSManager; if (!_pvsManager || null == _pvsManager.visibleFlags || _pvsManager.visibleFlags.Length <= 0) { return; } if (GUILayout.Button("Init")) { PVSBaker.InitPVSManager(_pvsManager); } _scrollPosition = GUILayout.BeginScrollView(_scrollPosition); try { for (var i = 0; i < _pvsManager.renderers.Count; i += 3) { if (!GUILayout.Button($"Bake {i}-{i + 3}")) { continue; } _pvsManager.BuildAccelerationStructure(); try { for (var index = i; index < Mathf.Min(_pvsManager.renderers.Count, i + 3); ++index) { _pvsManager.accelerationStructure.Build(); PVSBaker.BakeVisibleFlagForRenderer(_pvsManager, index, index / 3.0f); } UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes(); } finally { EditorUtility.ClearProgressBar(); _pvsManager.ReleaseBakeResource(); } } } finally { GUILayout.EndScrollView(); } }
/// <summary> /// bake visible flag for one renderer. /// </summary> /// <param name="pvsManager">the PVS manager.</param> /// <param name="index">the renderer index.</param> /// <param name="progress">the baking progress.</param> public static bool BakeVisibleFlagForRenderer(PVSManager pvsManager, int index, float progress) { // if (EditorUtility.DisplayCancelableProgressBar("Backing", $"Renderer: {index}/{pvsManager.renderers.Count}", progress)) // { // return false; // } var renderer = pvsManager.renderers[index]; var targetBounds = renderer.bounds; targetBounds.Expand(1e-5f); var targetPlanes = PVSManager.GetPlanesFromBounds(ref targetBounds); for (var cellIndexX = 0; cellIndexX < pvsManager.cachedCellCountX; ++cellIndexX) { if (EditorUtility.DisplayCancelableProgressBar("Backing", $"Renderer: {index}/{pvsManager.renderers.Count} Cell: {cellIndexX}/{pvsManager.cachedCellCountX}", progress)) { return(false); } for (var cellIndexY = 0; cellIndexY < pvsManager.cachedCellCountY; ++cellIndexY) { // if (EditorUtility.DisplayCancelableProgressBar("Backing", $"Renderer: {index}/{pvsManager.renderers.Count} Cell: {cellIndexX}/{pvsManager.cachedCellCountX}, {cellIndexY}/{pvsManager.cachedCellCountY}", progress)) // { // return false; // } for (var cellIndexZ = 0; cellIndexZ < pvsManager.cachedCellCountZ; ++cellIndexZ) { // if (EditorUtility.DisplayCancelableProgressBar("Backing", $"Renderer: {index}/{pvsManager.renderers.Count} Cell: {cellIndexX}/{pvsManager.cachedCellCountX}, {cellIndexY}/{pvsManager.cachedCellCountY}, {cellIndexZ}/{pvsManager.cachedCellCountZ}", progress)) // { // return false; // } var viewBounds = new Bounds( pvsManager.worldBounds.min + new Vector3( cellIndexX * pvsManager.cellSize.x + 0.5f * pvsManager.cellSize.x, cellIndexY * pvsManager.cellSize.y + 0.5f * pvsManager.cellSize.y, cellIndexZ * pvsManager.cellSize.z + 0.5f * pvsManager.cellSize.z), pvsManager.cellSize); // check visible. var isVisible = false; if (viewBounds.Intersects(targetBounds)) { isVisible = true; } else { var viewPlanes = PVSManager.GetPlanesFromBounds(ref viewBounds); // find view bounds and target bounds side face side planes. foreach (var viewPlane in viewPlanes) { foreach (var targetPlane in targetPlanes) { if (!PVSManager.IsPlaneFacePlane(viewPlane, targetPlane)) { continue; } isVisible = pvsManager.RayTracingPlane2PlaneGPU(viewPlane, targetPlane); if (isVisible) { break; } } if (isVisible) { break; } } } pvsManager.SetVisibleFlag(index, cellIndexX, cellIndexY, cellIndexZ, isVisible); } } } return(true); }