예제 #1
0
        internal static void ProcessFrustumCullingResults()
        {
            if (m_indicesToRemove == null)
            {
                m_indicesToRemove = new List <int>();
            }

            foreach (MyFrustumCullQuery frustumQuery in m_cullQuery.FrustumQueries)
            {
                var  cullProxies     = frustumQuery.List;
                bool isShadowFrustum = ((frustumQuery.Type == MyFrustumEnum.ShadowCascade) || (frustumQuery.Type == MyFrustumEnum.ShadowProjection));
                for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex)
                {
                    MyCullProxy cullProxy = cullProxies[cullProxyIndex];
                    if (cullProxy == null)
                    {
                        continue;
                    }
                    foreach (MyRenderableProxy proxy in cullProxy.Proxies)
                    {
                        bool shouldCastShadows = (proxy.Flags & MyRenderableProxyFlags.CastShadows) == MyRenderableProxyFlags.CastShadows;
                        if (!proxy.IsInViewDistance() || (isShadowFrustum && !shouldCastShadows))
                        {
                            m_indicesToRemove.Add(cullProxyIndex);
                            break;
                        }
                        var worldMat = proxy.WorldMatrix;
                        worldMat.Translation          -= MyEnvironment.CameraPosition;
                        proxy.ObjectData.LocalMatrix   = worldMat;
                        proxy.ObjectData.MaterialIndex = MySceneMaterials.GetDrawMaterialIndex(proxy.PerMaterialIndex);
                    }
                }

                for (int removeIndex = m_indicesToRemove.Count - 1; removeIndex >= 0; --removeIndex)
                {
                    cullProxies.RemoveAtFast(m_indicesToRemove[removeIndex]);
                    frustumQuery.IsInsideList.RemoveAtFast(m_indicesToRemove[removeIndex]);
                }
                m_indicesToRemove.Clear();

                if (frustumQuery.Type == MyFrustumEnum.MainFrustum)
                {
                    MyPerformanceCounter.PerCameraDraw11Write.ViewFrustumObjectsNum = frustumQuery.List.Count;
                }
                else if (frustumQuery.Type == MyFrustumEnum.ShadowCascade)
                {
                    while (m_shadowCascadeProxies.Count < MyRenderProxy.Settings.ShadowCascadeCount)
                    {
                        m_shadowCascadeProxies.Add(new HashSet <MyCullProxy>());
                    }
                    while (m_shadowCascadeProxies_2.Count < MyRenderProxy.Settings.ShadowCascadeCount)
                    {
                        m_shadowCascadeProxies_2.Add(new HashSet <MyCullProxy_2>());
                    }

                    // List 1
                    m_shadowCascadeProxies[frustumQuery.CascadeIndex].Clear();
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex)
                    {
                        var  cullProxy = cullProxies[cullProxyIndex];
                        bool containedInHigherCascade = false;

                        // Cull items if they're fully contained in higher resolution cascades
                        for (int hashSetIndex = 0; hashSetIndex < frustumQuery.CascadeIndex; ++hashSetIndex)
                        {
                            if (m_shadowCascadeProxies[hashSetIndex].Contains(cullProxy))
                            {
                                cullProxies.RemoveAtFast(cullProxyIndex);
                                frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex);
                                --cullProxyIndex;
                                containedInHigherCascade = true;
                                break;
                            }
                        }

                        if (!containedInHigherCascade && frustumQuery.IsInsideList[cullProxyIndex])
                        {
                            m_shadowCascadeProxies[frustumQuery.CascadeIndex].Add(cullProxy);
                        }
                    }

                    // List 2
                    var cullProxies_2 = frustumQuery.List2;
                    m_shadowCascadeProxies_2[frustumQuery.CascadeIndex].Clear();
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies_2.Count; ++cullProxyIndex)
                    {
                        var  cullProxy_2 = cullProxies_2[cullProxyIndex];
                        bool containedInHigherCascade = false;

                        // Cull items if they're fully contained in higher resolution cascades
                        for (int hashSetIndex = 0; hashSetIndex < frustumQuery.CascadeIndex; ++hashSetIndex)
                        {
                            if (m_shadowCascadeProxies_2[hashSetIndex].Contains(cullProxy_2))
                            {
                                cullProxies_2.RemoveAtFast(cullProxyIndex);
                                frustumQuery.IsInsideList2.RemoveAtFast(cullProxyIndex);
                                --cullProxyIndex;
                                containedInHigherCascade = true;
                                break;
                            }
                        }

                        if (!containedInHigherCascade && frustumQuery.IsInsideList2[cullProxyIndex])
                        {
                            m_shadowCascadeProxies_2[frustumQuery.CascadeIndex].Add(cullProxy_2);
                        }
                    }

                    MyPerformanceCounter.PerCameraDraw11Write.ShadowCascadeObjectsNum[frustumQuery.CascadeIndex] = frustumQuery.List.Count;
                }

                if (frustumQuery.Ignored != null)
                {
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; cullProxyIndex++)
                    {
                        if (cullProxies[cullProxyIndex].Proxies.Length > 0 && frustumQuery.Ignored.Contains(cullProxies[cullProxyIndex].Proxies[0].Parent.m_owner.ID))
                        {
                            cullProxies.RemoveAtFast(cullProxyIndex);
                            --cullProxyIndex;
                        }
                    }
                }
            }
        }
예제 #2
0
        internal static void DispatchCulling()
        {
            //MyPerformanceCounter.PerCameraDraw11Write.RenderableObjectsNum = MyRenderablesBoundingTree.m_tree.CountLeaves(MyRenderablesBoundingTree.m_tree.GetRoot());

            MyRender11.GetRenderProfiler().StartProfilingBlock("CreateTasksAndWait");
            List <Task> tasks = new List <Task>();

            for (int i = 1; i < m_cullQuery.Size; i++)
            {
                m_cullQuery.FrustumQuery[i].List.Clear();
                m_cullQuery.FrustumQuery[i].IsInsideList.Clear();
                tasks.Add(Parallel.Start(new MyCullingWork(m_cullQuery.FrustumQuery[i])));
            }

            if (m_cullQuery.Size > 0)
            {
                m_cullQuery.FrustumQuery[0].List.Clear();
                m_cullQuery.FrustumQuery[0].IsInsideList.Clear();
                new MyCullingWork(m_cullQuery.FrustumQuery[0]).DoWork();
            }

            foreach (var task in tasks)
            {
                task.Wait();
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            //bool ok = false;
            //for (int i = 0; i < m_cullQuery.Size; i++ )
            //{
            //    if(m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.MainFrustum)
            //    {
            //        foreach(var e in m_cullQuery.FrustumQuery[i].List)
            //        {
            //            if(e.Proxies[0].Parent.m_owner.ID == 1417)
            //            {
            //                ok = true; break;
            //            }
            //        }
            //    }
            //}

            //var x = 7;

            MyRender11.GetRenderProfiler().StartProfilingBlock("ProcessResults");
            for (int i = 0; i < m_cullQuery.Size; i++)
            {
                if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.MainFrustum)
                {
                    MyPerformanceCounter.PerCameraDraw11Write.ViewFrustumObjectsNum = m_cullQuery.FrustumQuery[i].List.Count;

                    int N = m_cullQuery.FrustumQuery[i].List.Count;
                    for (int j = 0; j < N; j++)
                    {
                        foreach (var proxy in m_cullQuery.FrustumQuery[i].List[j].Proxies)
                        {
                            var worldMat = proxy.WorldMatrix;
                            worldMat.Translation          -= MyEnvironment.CameraPosition;
                            proxy.ObjectData.LocalMatrix   = worldMat;
                            proxy.ObjectData.MaterialIndex = MySceneMaterials.GetDrawMaterialIndex(proxy.PerMaterialIndex);
                        }
                    }
                }
                else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade0)
                {
                    MyPerformanceCounter.PerCameraDraw11Write.Cascade0ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count;

                    //
                    m_inCascade0.Clear();
                    int N = m_cullQuery.FrustumQuery[i].List.Count;
                    for (int j = 0; j < N; j++)
                    {
                        if (m_cullQuery.FrustumQuery[i].IsInsideList[j])
                        {
                            var item = m_cullQuery.FrustumQuery[i].List[j];
                            m_inCascade0.Add(item);
                        }
                    }

                    //
                    m_inCascade0_2.Clear();
                    N = m_cullQuery.FrustumQuery[i].List2.Count;
                    for (int j = 0; j < N; j++)
                    {
                        if (m_cullQuery.FrustumQuery[i].IsInsideList2[j])
                        {
                            var item = m_cullQuery.FrustumQuery[i].List2[j];
                            m_inCascade0_2.Add(item);
                        }
                    }
                }
                else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade1)
                {
                    //
                    m_inCascade1.Clear();
                    var list = m_cullQuery.FrustumQuery[i].List;
                    int N    = list.Count;
                    for (int j = 0; j < N; j++)
                    {
                        var item = list[j];
                        if (m_inCascade0.Contains(item))
                        {
                            // drop
                            list.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                        else if (m_cullQuery.FrustumQuery[i].IsInsideList[j])
                        {
                            m_inCascade1.Add(item);
                        }
                    }

                    //
                    m_inCascade1_2.Clear();
                    var list2 = m_cullQuery.FrustumQuery[i].List2;
                    N = list2.Count;
                    for (int j = 0; j < N; j++)
                    {
                        var item = list2[j];
                        if (m_inCascade0_2.Contains(item))
                        {
                            // drop
                            list2.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                        else if (m_cullQuery.FrustumQuery[i].IsInsideList2[j])
                        {
                            m_inCascade1_2.Add(item);
                        }
                    }

                    MyPerformanceCounter.PerCameraDraw11Write.Cascade1ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count;
                }
                else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade2)
                {
                    //
                    m_inCascade2.Clear();
                    var list = m_cullQuery.FrustumQuery[i].List;
                    int N    = list.Count;
                    for (int j = 0; j < N; j++)
                    {
                        var item = list[j];
                        if (m_inCascade0.Contains(item) || m_inCascade1.Contains(item))
                        {
                            // drop
                            list.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                        else if (m_cullQuery.FrustumQuery[i].IsInsideList[j])
                        {
                            m_inCascade2.Add(item);
                        }
                    }

                    //
                    m_inCascade2_2.Clear();
                    var list2 = m_cullQuery.FrustumQuery[i].List2;
                    N = list2.Count;
                    for (int j = 0; j < N; j++)
                    {
                        var item = list2[j];
                        if (m_inCascade0_2.Contains(item) || m_inCascade1_2.Contains(item))
                        {
                            // drop
                            list2.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                        else if (m_cullQuery.FrustumQuery[i].IsInsideList2[j])
                        {
                            m_inCascade2_2.Add(item);
                        }
                    }

                    MyPerformanceCounter.PerCameraDraw11Write.Cascade2ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count;
                }
                else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade3)
                {
                    var list = m_cullQuery.FrustumQuery[i].List;
                    int N    = list.Count;
                    for (int j = 0; j < N; j++)
                    {
                        var item = list[j];
                        if (m_inCascade0.Contains(item) || m_inCascade1.Contains(item) || m_inCascade2.Contains(item))
                        {
                            // drop
                            list.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                    }

                    //
                    var list2 = m_cullQuery.FrustumQuery[i].List2;
                    N = list2.Count;
                    for (int j = 0; j < N; j++)
                    {
                        var item = list2[j];
                        if (m_inCascade0_2.Contains(item) || m_inCascade1_2.Contains(item) || m_inCascade2_2.Contains(item))
                        {
                            // drop
                            list2.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                    }

                    MyPerformanceCounter.PerCameraDraw11Write.Cascade3ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count;
                }
                if (m_cullQuery.FrustumQuery[i].Ignored != null)
                {
                    var list = m_cullQuery.FrustumQuery[i].List;

                    int N = list.Count;
                    for (int j = 0; j < N; j++)
                    {
                        if (list[j].Proxies.Length > 0 && m_cullQuery.FrustumQuery[i].Ignored.Contains(list[j].Proxies[0].Parent.m_owner.ID))
                        {
                            list.RemoveAtFast(j);
                            j--;
                            N--;
                        }
                    }
                }
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();
        }
예제 #3
0
        protected override void ProcessCullQueryResults(MyCullQuery cullQuery)
        {
            ProfilerShort.Begin("Reset");

            foreach (MyFrustumCullQuery frustumQuery in cullQuery.FrustumCullQueries)
            {
                var cullProxies = frustumQuery.List;
                foreach (MyCullProxy cullProxy in cullProxies)
                {
                    cullProxy.Updated = false;
                    cullProxy.FirstFullyContainingCascadeIndex = uint.MaxValue;
                }
            }
            ProfilerShort.End();
            foreach (var frustumQuery in cullQuery.FrustumCullQueries)
            {
                ProfilerShort.Begin("Distance cull and update");

                var  cullProxies     = frustumQuery.List;
                bool isShadowFrustum = (frustumQuery.Type == MyFrustumEnum.ShadowCascade) || (frustumQuery.Type == MyFrustumEnum.ShadowProjection);
                for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex)
                {
                    MyCullProxy cullProxy = cullProxies[cullProxyIndex];
                    if (cullProxy == null || cullProxy.RenderableProxies == null || cullProxy.RenderableProxies.Length == 0 || cullProxy.RenderableProxies[0].Parent == null || !cullProxy.RenderableProxies[0].Parent.IsVisible)
                    {
                        m_tmpIndicesToRemove.Add(cullProxyIndex);
                        continue;
                    }

                    if (!cullProxy.Updated)
                    {
                        var renderableComponent = cullProxy.Parent;
                        if (renderableComponent != null)
                        {
                            renderableComponent.OnFrameUpdate();
                            if (renderableComponent.IsCulled)
                            {
                                m_tmpIndicesToRemove.Add(cullProxyIndex);
                                continue;
                            }
                            renderableComponent.UpdateInstanceLods();
                        }

                        // Proxies can get removed in UpdateInstanceLods
                        if (cullProxy.RenderableProxies == null)
                        {
                            m_tmpIndicesToRemove.Add(cullProxyIndex);
                            continue;
                        }

                        foreach (MyRenderableProxy proxy in cullProxy.RenderableProxies)
                        {
                            bool shouldCastShadows = proxy.Flags.HasFlags(MyRenderableProxyFlags.CastShadows) &&
                                                     (proxy.Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance) || frustumQuery.CascadeIndex < 4);

                            if (isShadowFrustum && !shouldCastShadows)
                            {
                                m_tmpIndicesToRemove.Add(cullProxyIndex);
                                break;
                            }
                            var worldMat = proxy.WorldMatrix;
                            worldMat.Translation -= MyEnvironment.CameraPosition;
                            proxy.CommonObjectData.LocalMatrix   = worldMat;
                            proxy.CommonObjectData.MaterialIndex = MySceneMaterials.GetDrawMaterialIndex(proxy.PerMaterialIndex);
                        }
                        cullProxy.Updated = true;
                    }
                }

                for (int removeIndex = m_tmpIndicesToRemove.Count - 1; removeIndex >= 0; --removeIndex)
                {
                    cullProxies.RemoveAtFast(m_tmpIndicesToRemove[removeIndex]);
                    frustumQuery.IsInsideList.RemoveAtFast(m_tmpIndicesToRemove[removeIndex]);
                }
                m_tmpIndicesToRemove.SetSize(0);

                ProfilerShort.BeginNextBlock("Culling by query type");
                if (frustumQuery.Type == MyFrustumEnum.MainFrustum)
                {
                    MyPerformanceCounter.PerCameraDraw11Write.ViewFrustumObjectsNum = frustumQuery.List.Count;
                }
                else if (frustumQuery.Type == MyFrustumEnum.ShadowCascade)
                {
                    while (m_shadowCascadeProxies2.Count < MyRenderProxy.Settings.ShadowCascadeCount)
                    {
                        m_shadowCascadeProxies2.Add(new HashSet <MyCullProxy_2>());
                    }

                    bool isHighCascade = frustumQuery.CascadeIndex < 3;

                    if (cullProxies.Count == 0)
                    {
                        MyShadowCascades.ShadowCascadeObjectsCounter[frustumQuery.CascadeIndex]  = 0;
                        MyShadowCascades.ShadowCascadeTriangleCounter[frustumQuery.CascadeIndex] = 0;
                    }

                    // List 1
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex)
                    {
                        var cullProxy = cullProxies[cullProxyIndex];

                        if ((isHighCascade && (cullProxy.FirstFullyContainingCascadeIndex < frustumQuery.CascadeIndex - 1)) ||
                            (!isHighCascade && cullProxy.FirstFullyContainingCascadeIndex < frustumQuery.CascadeIndex) ||
                            cullProxy.RenderableProxies == null)
                        {
                            cullProxies.RemoveAtFast(cullProxyIndex);
                            frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex);
                            --cullProxyIndex;
                            continue;
                        }
                        else
                        {
                            foreach (var renderableProxy in cullProxy.RenderableProxies)
                            {
                                MyShadowCascades.ShadowCascadeTriangleCounter[frustumQuery.CascadeIndex] += (renderableProxy.InstanceCount > 0 ? renderableProxy.InstanceCount : 1) * renderableProxy.DrawSubmesh.IndexCount / 3;
                            }

                            if (frustumQuery.IsInsideList[cullProxyIndex])
                            {
                                cullProxy.FirstFullyContainingCascadeIndex = (uint)frustumQuery.CascadeIndex;
                            }
                        }
                    }

                    // List 2
                    var cullProxies2 = frustumQuery.List2;
                    m_shadowCascadeProxies2[frustumQuery.CascadeIndex].Clear();
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies2.Count; ++cullProxyIndex)
                    {
                        var  cullProxy2 = cullProxies2[cullProxyIndex];
                        bool containedInHigherCascade = false;

                        // Cull items if they're fully contained in higher resolution cascades
                        for (int hashSetIndex = 0; hashSetIndex < frustumQuery.CascadeIndex; ++hashSetIndex)
                        {
                            if (m_shadowCascadeProxies2[hashSetIndex].Contains(cullProxy2))
                            {
                                cullProxies2.RemoveAtFast(cullProxyIndex);
                                frustumQuery.IsInsideList2.RemoveAtFast(cullProxyIndex);
                                --cullProxyIndex;
                                containedInHigherCascade = true;
                                break;
                            }
                        }

                        if (!containedInHigherCascade && frustumQuery.IsInsideList2[cullProxyIndex])
                        {
                            m_shadowCascadeProxies2[frustumQuery.CascadeIndex].Add(cullProxy2);
                        }
                    }

                    MyShadowCascades.ShadowCascadeObjectsCounter[frustumQuery.CascadeIndex] = cullProxies.Count;
                }
                else if (frustumQuery.Type == MyFrustumEnum.ShadowProjection)
                {
                    MyShadows.OtherShadowsTriangleCounter = 0;
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex)
                    {
                        var cullProxy = frustumQuery.List[cullProxyIndex];
                        if (cullProxy.RenderableProxies == null)
                        {
                            cullProxies.RemoveAtFast(cullProxyIndex);
                            frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex);
                            --cullProxyIndex;
                            continue;
                        }
                        foreach (var proxy in cullProxy.RenderableProxies)
                        {
                            MyShadows.OtherShadowsTriangleCounter += Math.Max(proxy.InstanceCount, 1) * proxy.DrawSubmesh.IndexCount / 3;
                        }
                    }
                }
                ProfilerShort.End();
                if (frustumQuery.Ignored != null)
                {
                    for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; cullProxyIndex++)
                    {
                        if ((cullProxies[cullProxyIndex].RenderableProxies == null || cullProxies[cullProxyIndex].RenderableProxies.Length == 0 || cullProxies[cullProxyIndex].RenderableProxies[0] == null) || (frustumQuery.Ignored.Contains(cullProxies[cullProxyIndex].RenderableProxies[0].Parent.Owner.ID)))
                        {
                            cullProxies.RemoveAtFast(cullProxyIndex);
                            frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex);
                            --cullProxyIndex;
                            continue;
                        }
                    }
                }
            }
            for (int cascadeIndex = 0; cascadeIndex < MyRenderProxy.Settings.ShadowCascadeCount; ++cascadeIndex)
            {
                if (MyShadowCascades.ShadowCascadeObjectsCounter[cascadeIndex] >= 0)
                {
                    MyPerformanceCounter.PerCameraDraw11Write.ShadowCascadeObjectsNum[cascadeIndex] = MyShadowCascades.ShadowCascadeObjectsCounter[cascadeIndex];
                    MyShadowCascades.ShadowCascadeObjectsCounter[cascadeIndex] = -1;
                }
                if (MyShadowCascades.ShadowCascadeTriangleCounter[cascadeIndex] >= 0)
                {
                    MyPerformanceCounter.PerCameraDraw11Write.ShadowCascadeTriangles[cascadeIndex] = MyShadowCascades.ShadowCascadeTriangleCounter[cascadeIndex];
                    MyShadowCascades.ShadowCascadeTriangleCounter[cascadeIndex] = -1;
                }
            }
            if (MyShadows.OtherShadowsTriangleCounter >= 0)
            {
                MyPerformanceCounter.PerCameraDraw11Write.OtherShadowTriangles = MyShadows.OtherShadowsTriangleCounter;
                MyShadows.OtherShadowsTriangleCounter = -1;
            }
        }