Beispiel #1
0
        private void DoUpdate(Camera camera = null)
        {
            if (camera != null)
            {
                m_Camera = camera;
            }
            if (m_Camera == null)
            {
                m_Camera = Camera.main;
            }
            if (m_Camera == null)
            {
                return;
            }
            try
            {
                m_LimitBounds.center = transform.position;

                Matrix4x4 mat_M = transform.localToWorldMatrix;
                Matrix4x4 mat_V = m_Camera.worldToCameraMatrix;
                Matrix4x4 mat_P = GL.GetGPUProjectionMatrix(m_Camera.projectionMatrix, true);
                m_GlobalState[0].MatM   = mat_M;
                m_GlobalState[0].MatMVP = mat_P * mat_V * mat_M;
                m_GlobalState[0].CameraLocalPosition = transform.InverseTransformPoint(m_Camera.transform.position);
                m_GlobalState[0].CameraLocalForward  = transform.InverseTransformDirection(m_Camera.transform.forward);
                m_CB_GlobalState.SetData(m_GlobalState);

                if (m_DisperseTempletes != null && m_DisperseTempletes.Count > 0)
                {
                    for (int iDisperse = 0; iDisperse < m_DisperseTempletes.Count; iDisperse++)
                    {
                        DisperseInfo disperseInfo = m_DisperseTempletes[iDisperse];
                        if (disperseInfo == null || disperseInfo.m_Material == null || disperseInfo.m_Mesh == null || disperseInfo.m_DisperseCount <= 0)
                        {
                            continue;
                        }

                        disperseInfo.ComputeShader.Dispatch(m_CS_MainKernel[iDisperse], disperseInfo.m_DisperseCount, 1, 1);
                        Graphics.DrawMeshInstancedIndirect(disperseInfo.m_Mesh
                                                           , 0
                                                           , disperseInfo.m_UseMaterial
                                                           , m_LimitBounds
                                                           , m_CB_BufferArgs[iDisperse]
                                                           , 0
                                                           , null
                                                           , ShadowCastingMode.Off
                                                           , false
                                                           , gameObject.layer
                                                           , m_Camera
                                                           , LightProbeUsage.Off);
                    }
                }
            }
            catch (Exception e)
            {
            }
        }
Beispiel #2
0
        /// <summary>
        /// 开始渲染,流程:
        ///		随机分布Mesh
        ///		分配显存
        ///		把Mesh的Transform信息发送给显存
        /// </summary>
        public void StartRendering(Camera camera)
        {
            try
            {
                m_Camera = camera;

                m_GlobalState    = new GlobalState[1];
                m_CB_GlobalState = new ComputeBuffer(1, Marshal.SizeOf(typeof(GlobalState)));
                int[] disperseMeshs = new int[m_DisperseTempletes.Count];
                if (m_DispersCount > 0)
                {
                    float totalWeight = 0;
                    int[] unitCounts  = new int[m_DisperseTempletes.Count];
                    for (int iTemplate = 0; iTemplate < m_DisperseTempletes.Count; iTemplate++)
                    {
                        totalWeight          += m_DisperseTempletes[iTemplate].m_Weight;
                        unitCounts[iTemplate] = 0;
                    }

                    for (int iDisperse = 0; iDisperse < m_DispersCount; iDisperse++)
                    {
                        float randomWeight  = UnityEngine.Random.Range(0, totalWeight);
                        int   templateIndex = 0;
                        for (int iTemplate = 0; iTemplate < m_DisperseTempletes.Count; iTemplate++)
                        {
                            randomWeight -= m_DisperseTempletes[iTemplate].m_Weight;
                            if (randomWeight < 0)
                            {
                                templateIndex = iTemplate;
                                break;
                            }
                        }

                        disperseMeshs[templateIndex]++;
                    }
                }
                if (disperseMeshs != null && disperseMeshs.Length > 0)
                {
                    m_CS_MainKernel = new int[disperseMeshs.Length];
                    for (int iDisperse = 0; iDisperse < disperseMeshs.Length; iDisperse++)
                    {
                        DisperseInfo disperseInfo  = m_DisperseTempletes[iDisperse];
                        int          disperseCount = disperseMeshs[iDisperse];
                        MeshState[]  meshStates    = new MeshState[disperseCount];
                        for (int iMesh = 0; iMesh < disperseCount; iMesh++)
                        {
                            Vector3 position  = UnityEngine.Random.insideUnitSphere;
                            float   magnitude = m_Offest;
                            magnitude  += position.magnitude * (1 - m_Offest);
                            position.x *= m_ScaleX;
                            position.y *= m_ScaleY;
                            position.z *= m_ScaleZ;
                            Vector3 rotation = Vector3.zero;
                            if (disperseInfo.m_RandX)
                            {
                                rotation.x = UnityEngine.Random.Range(0f, 360f);
                            }
                            if (disperseInfo.m_RandY)
                            {
                                rotation.y = UnityEngine.Random.Range(0f, 360f);
                            }
                            if (disperseInfo.m_RandZ)
                            {
                                rotation.z = UnityEngine.Random.Range(0f, 360f);
                            }
                            position = position.normalized * magnitude * m_Radius;
                            meshStates[iMesh].LocalPosition = position;
                            meshStates[iMesh].LocalRotation = rotation;
                            meshStates[iMesh].LocalScale    = RandomUtility.RandomScale(MinScale, MaxScale, ScaleMaxOffset);
                        }

                        ComputeBuffer m_CB_MeshState = new ComputeBuffer(disperseCount, Marshal.SizeOf(typeof(MeshState)));
                        m_CB_MeshState.SetData(meshStates);
                        m_CB_MeshStates.Add(m_CB_MeshState);
                        uint[] m_BufferArgs = new uint[5] {
                            disperseInfo.m_Mesh.GetIndexCount(0), (uint)disperseCount, 0, 0, 0
                        };
                        ComputeBuffer bufferArgs = new ComputeBuffer(1, (m_BufferArgs.Length * Marshal.SizeOf(typeof(uint)))
                                                                     , ComputeBufferType.IndirectArguments);
                        bufferArgs.SetData(m_BufferArgs);

                        m_CB_BufferArgs.Add(bufferArgs);
                        m_CS_MainKernel[iDisperse] = disperseInfo.ComputeShader.FindKernel(CS_MAIN_KERNEL_NAME);
                        disperseInfo.ComputeShader.SetBuffer(m_CS_MainKernel[iDisperse], CS_GLOBAL_STATE_NAME, m_CB_GlobalState);
                        disperseInfo.ComputeShader.SetBuffer(m_CS_MainKernel[iDisperse], CS_MESH_STATES_NAME, m_CB_MeshState);
                        disperseInfo.ComputeShader.SetVector(CS_PARAM1_NAME, new Vector4(MinDisplayToCamera, MaxDisplayDistanceToCamera, 0, 0));
                        if (disperseInfo.m_UseMaterial == null)
                        {
                            disperseInfo.m_UseMaterial = new Material(disperseInfo.m_Material);
                        }
                        disperseInfo.m_UseMaterial.SetBuffer(CS_MESH_STATES_NAME, m_CB_MeshState);
                        disperseInfo.m_DisperseCount = disperseCount;
                    }
                }

                m_LimitBounds = CaculateLimitBounds();
            }
            catch (Exception e)
            {
            }
        }