private void DoStart(int cellIdx, Camera targetCamera, PVSCell cell, PVSItemIDS items, RenderTexture targetTexture) { // 1. 设置Camera的位置 var camTrans = targetCamera.transform; camTrans.position = cell.position; // 2.设置RT // 3.渲染Items //int faceMask = 1 << (int)CubemapFace.PositiveZ; //targetCamera.RenderToCubemap(targetTexture, faceMask); targetCamera.Render(); //SaveCellRtToFileName (cellIdx, targetTexture); }
void Clear() { m_SelSaveMode = 0; m_SearchBounds = new Bounds(); m_GlobalNodeId = 0; m_CellArray = null; m_CellIngoreArray.Clear(); m_CellsResult = null; m_CellsSave = null; m_BoundsArray = null; m_PVSItemIDS = null; m_SelCellResult = -1; if (m_CheckCellBuffer != null) { m_CheckCellBuffer.Dispose(); m_CheckCellBuffer = null; } if (m_CameraBuffer != null) { m_CameraBuffer.Dispose(); m_CameraBuffer = null; } ClearThreads(); }
internal unsafe void Start(Camera targetCamera, PVSCell[] cells, PVSItemIDS items, Vector3 camDir, ComputeShader shader, bool isComputeMode) { if (targetCamera == null || cells == null || cells.Length <= 0 || !items.IsVaild || shader == null) { return; } try { CameraOldData camOldData = new CameraOldData(targetCamera); targetCamera.transform.forward = camDir; targetCamera.transform.up = Vector3.up; targetCamera.allowMSAA = false; targetCamera.allowHDR = false; targetCamera.backgroundColor = Color.black; targetCamera.clearFlags = CameraClearFlags.SolidColor; // 关闭GAMMA var oldSpace = UnityEditor.PlayerSettings.colorSpace; UnityEditor.PlayerSettings.colorSpace = cColorSpace; Material mat = AssetDatabase.LoadAssetAtPath <Material> ("Assets/PVS/Editor/PVS_MaskColor.mat"); Material[] mats = new Material[1] { mat }; // 设置TAG List <MeshOldData> oldDatas = new List <MeshOldData> (items.m_IDs.Count); List <int> itemColorTags = new List <int> (items.m_IDs.Count); int Red = cMaskColorStep; for (int i = 0; i < items.m_IDs.Count; ++i) { var trans = items.m_IDs [i]; var oldData = new MeshOldData(); oldData.tag = trans.gameObject.tag; oldData.layer = trans.gameObject.layer; oldData.isVisible = trans.gameObject.activeSelf; oldDatas.Add(oldData); trans.gameObject.SetActive(true); trans.gameObject.layer = cTrackLayer; //trans.gameObject.tag = cTrackTag; //trans.gameObject.layer = UnityEditor.EditorUserSettings.la var ms = trans.GetComponent <MeshRenderer> (); if (ms != null) { oldData.mats = ms.sharedMaterials; if (oldData.mats != null) { if (oldData.mats.Length <= 0) { oldData.mats = null; } else { bool isHasMat = false; for (int j = 0; j < oldData.mats.Length; ++j) { if (oldData.mats[j] != null) { isHasMat = true; break; } } if (!isHasMat) { oldData.mats = null; } } } oldData.mat = ms.sharedMaterial; ms.sharedMaterials = mats; MaterialPropertyBlock block = new MaterialPropertyBlock(); byte r = (byte)(Red & 0xFF); byte g = (byte)((Red >> 8) & 0xFF); byte b = (byte)((Red >> 16) & 0xFF); Color32 cc = new Color32(r, g, b, 255); block.SetColor("_MaskColor", cc); ms.SetPropertyBlock(block); itemColorTags.Add(Red); Red += cMaskColorStep; } } RenderTexture targetTexture = new RenderTexture(RTSize_Width, RTSize_Height, 16, cRTFormat, RenderTextureReadWrite.sRGB); targetTexture.useMipMap = false; targetTexture.autoGenerateMips = false; targetTexture.filterMode = FilterMode.Point; targetTexture.enableRandomWrite = false; targetTexture.isPowerOfTwo = false; if (!targetTexture.Create()) { Debug.LogError("创建RT失败"); return; } targetCamera.targetTexture = targetTexture; targetCamera.cullingMask = 1 << cTrackLayer; int[] resultBools = new int[items.m_IDs.Count]; ComputeBuffer resultBuffer = null; if (isComputeMode) { resultBuffer = new ComputeBuffer(resultBools.Length, System.Runtime.InteropServices.Marshal.SizeOf(typeof(int))); } // resultBuffer.SetData<int>(resultBoolList); for (int i = 0; i < cells.Length; ++i) { var cell = cells [i]; if (cell == null) { continue; } float process = ((float)i + 1) / (float)cells.Length; EditorUtility.DisplayProgressBar("RT烘焙处理", string.Format("格子索引:{0:D}", i), process); DoStart(i, targetCamera, cell, items, targetTexture); if (isComputeMode) { DispatchComputeShader(shader, targetTexture, resultBuffer); resultBuffer.GetData(resultBools); } else { System.Array.Clear(resultBools, 0, resultBools.Length); DispatchCpu(targetTexture, resultBools); } // if (resultBools[0] != -1) // Debug.Log(resultBools[0].ToString()); for (int j = 0; j < resultBools.Length; ++j) { bool isVisible = resultBools[j] != 0; cell.SetVisible(j + 1, isVisible); } } if (isComputeMode && resultBuffer != null) { resultBuffer.Release(); resultBuffer.Dispose(); } targetCamera.targetTexture = null; targetTexture.Release(); GameObject.DestroyImmediate(targetTexture); for (int i = 0; i < items.m_IDs.Count; ++i) { try { var trans = items.m_IDs [i]; trans.tag = oldDatas [i].tag; trans.gameObject.SetActive(oldDatas [i].isVisible); trans.gameObject.layer = oldDatas [i].layer; var ms = trans.GetComponent <MeshRenderer> (); if (ms != null) { if (oldDatas [i].mats != null) { ms.sharedMaterials = oldDatas [i].mats; } else { if (oldDatas[i].mat != null) { ms.sharedMaterial = oldDatas[i].mat; } } } } catch { } } UnityEditor.PlayerSettings.colorSpace = oldSpace; camOldData.AssignTo(targetCamera); } finally { EditorUtility.ClearProgressBar(); } }
private void ProcessCurrentScene(bool isOnlyInit = false) { // 获得当前场景NavMesh if (isOnlyInit) { var tris = UnityEngine.AI.NavMesh.CalculateTriangulation(); if (tris.vertices == null || tris.indices == null || tris.indices.Length <= 0 || tris.vertices.Length <= 0) { Debug.LogError("当前场景没有NavMesh"); return; } m_PVSItemIDS = GameObject.FindObjectOfType <PVSItemIDS>(); if (m_PVSItemIDS == null) { GameObject obj = new GameObject("PVSItemIDS", typeof(PVSItemIDS)); m_PVSItemIDS = obj.GetComponent <PVSItemIDS>(); } Vector3 minVec = Vector3.zero; Vector3 maxVec = Vector3.zero; for (int i = 0; i < tris.vertices.Length; ++i) { var vec = tris.vertices [i]; if (i == 0) { minVec = vec; maxVec = vec; } else { minVec.x = Mathf.Min(minVec.x, vec.x); minVec.y = Mathf.Min(minVec.y, vec.y); minVec.z = Mathf.Min(minVec.z, vec.z); maxVec.x = Mathf.Max(maxVec.x, vec.x); maxVec.y = Mathf.Max(maxVec.y, vec.y); maxVec.z = Mathf.Max(maxVec.z, vec.z); } } float camY = this.CamHeight; // 处理区域 Vector3 center = (maxVec + minVec) / 2.0f; Vector3 size = (maxVec - minVec); size.x = Mathf.Abs(size.x); size.y = Mathf.Abs(size.y); size.z = Mathf.Abs(size.z); m_SearchBounds = new Bounds(center, size); int col = Mathf.CeilToInt(size.x / PVSCell.CellSize); int row = Mathf.CeilToInt(size.z / PVSCell.CellSize); Vector3 halfSize = new Vector3(PVSCell.CellSize, 0, PVSCell.CellSize) / 2.0f; Vector3[] arr = new Vector3[col * row]; for (int r = 0; r < row; ++r) { for (int c = 0; c < col; ++c) { int idx = c + r * col; Vector3 pt = new Vector3(c * PVSCell.CellSize + minVec.x, center.y, r * PVSCell.CellSize + minVec.z) + halfSize; UnityEngine.AI.NavMeshHit hit; if (UnityEngine.AI.NavMesh.SamplePosition(pt, out hit, PVSCell.CellSize, int.MaxValue)) { pt.y = hit.position.y + camY / 2.0f; } else { // 再搜索四个角,看是否有效,否则直接SIZE为0 Vector3 c1 = pt - halfSize; Vector3 c2 = pt - new Vector3(halfSize.x, 0, -halfSize.z); Vector3 c3 = pt + halfSize; Vector3 c4 = pt + new Vector3(halfSize.x, 0, -halfSize.z); if ((!UnityEngine.AI.NavMesh.SamplePosition(c1, out hit, PVSCell.CellSize, int.MaxValue)) && (!UnityEngine.AI.NavMesh.SamplePosition(c2, out hit, PVSCell.CellSize, int.MaxValue)) && (!UnityEngine.AI.NavMesh.SamplePosition(c3, out hit, PVSCell.CellSize, int.MaxValue)) && (!UnityEngine.AI.NavMesh.SamplePosition(c4, out hit, PVSCell.CellSize, int.MaxValue)) ) { pt = Vector3.zero; m_CellIngoreArray.Add(idx); } } arr [idx] = pt; } } m_CellArray = arr; return; } var size1 = m_SearchBounds.size; int col1 = Mathf.CeilToInt(size1.x / PVSCell.CellSize); int row1 = Mathf.CeilToInt(size1.z / PVSCell.CellSize); InitPVSMeshes(); InitCellResults(); ClearThreads(); if (m_CheckCellBuffer != null) { m_CheckCellBuffer.Dispose(); m_CheckCellBuffer = null; } if (m_CameraBuffer != null) { m_CameraBuffer.Dispose(); m_CameraBuffer = null; } if (m_BakerMode == PVSSceneBakerMode.CameraRTCpuMode || m_BakerMode == PVSSceneBakerMode.CameraRTComputeMode) { if (m_PVSCellShader == null) { Debug.LogError("PVS烘焙ComputeShader找不到"); return; } PVSCameraRtTrack camRtTrack = new PVSCameraRtTrack(); camRtTrack.Start(m_TargetCamera, m_CellsResult, m_PVSItemIDS, m_TargetCamInfo.lookAt, m_PVSCellShader, m_BakerMode == PVSSceneBakerMode.CameraRTComputeMode); OnCpuThreadDone(); return; } if (!SystemInfo.supportsComputeShaders || m_BakerMode == PVSSceneBakerMode.CpuThreadMode) { if (m_BakerMode == PVSSceneBakerMode.ComputeShaderMode) { Debug.LogError("设备不支持ComputeShader"); } // 开启线程模式 CreateThreadMode(); return; } m_CheckCellBuffer = new ComputeBuffer(m_CellArray.Length, Marshal.SizeOf(typeof(Vector3))); m_CheckCellBuffer.SetData(m_CellArray); m_CameraBuffer = new ComputeBuffer(1, Marshal.SizeOf(typeof(PVSCameraInfo))); PVSCameraInfo[] camArr = new PVSCameraInfo[1]; camArr[0] = m_TargetCamInfo; m_CameraBuffer.SetData(camArr); if (m_PVSCellShader != null) { int main = m_PVSCellShader.FindKernel("PVSBaker"); m_PVSCellShader.SetBuffer(main, "pvsBakerPosArray", m_CheckCellBuffer); m_PVSCellShader.SetBuffer(main, "camera", m_CameraBuffer); m_PVSCellShader.Dispatch(main, col1, row1, 1); } else { Debug.LogError("PVS烘焙ComputeShader找不到"); } }