Beispiel #1
0
        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);
        }
Beispiel #2
0
 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();
 }
Beispiel #3
0
        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();
            }
        }
Beispiel #4
0
        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找不到");
            }
        }