예제 #1
0
        static protected int RenderersToVolumes(ref Renderer[] renderers, ref ProbeReferenceVolume.Volume cellVolume, ref List <ProbeReferenceVolume.Volume> volumes, ref Dictionary <Scene, int> sceneRefs)
        {
            int num = 0;

            foreach (Renderer r in renderers)
            {
                var  flags        = GameObjectUtility.GetStaticEditorFlags(r.gameObject) & StaticEditorFlags.ContributeGI;
                bool contributeGI = (flags & StaticEditorFlags.ContributeGI) != 0;

                if (!r.enabled || !r.gameObject.activeSelf || !contributeGI)
                {
                    continue;
                }

                ProbeReferenceVolume.Volume v = ToVolume(r.bounds);

                if (ProbeVolumePositioning.OBBIntersect(ref cellVolume, ref v))
                {
                    volumes.Add(v);

                    TrackSceneRefs(r.gameObject.scene, ref sceneRefs);

                    num++;
                }
            }

            return(num);
        }
예제 #2
0
        public static void SubdivisionAlgorithm(ProbeReferenceVolume.Volume cellVolume, List <ProbeReferenceVolume.Volume> probeVolumes, List <ProbeReferenceVolume.Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, int subdivisionLevel, List <Flags> outFlags)
        {
            Flags f = new Flags();

            for (int i = 0; i < inBricks.Count; i++)
            {
                ProbeReferenceVolume.Volume brickVolume = ProbeVolumePositioning.CalculateBrickVolume(ref refTrans, inBricks[i]);

                // Find the local max from all overlapping probe volumes:
                float localMaxSubdiv = 0;
                float localMinSubdiv = 0;
                bool  overlap        = false;
                foreach (ProbeReferenceVolume.Volume v in probeVolumes)
                {
                    ProbeReferenceVolume.Volume vol = v;
                    if (ProbeVolumePositioning.OBBIntersect(ref vol, ref brickVolume))
                    {
                        overlap        = true;
                        localMaxSubdiv = Mathf.Max(localMaxSubdiv, vol.maxSubdivisionMultiplier);
                        // Do we use max for min subdiv too?
                        localMinSubdiv = Mathf.Max(localMinSubdiv, vol.minSubdivisionMultiplier);
                    }
                }

                bool belowMaxSubdiv = subdivisionLevel <= ProbeReferenceVolume.instance.GetMaxSubdivision(localMaxSubdiv);
                bool belowMinSubdiv = subdivisionLevel <= ProbeReferenceVolume.instance.GetMaxSubdivision(localMinSubdiv);

                // Keep bricks that overlap at least one probe volume, and at least one influencer (mesh)
                if ((belowMinSubdiv && overlap) || (belowMaxSubdiv && ShouldKeepBrick(probeVolumes, brickVolume) && ShouldKeepBrick(influenceVolumes, brickVolume)))
                {
                    f.subdivide = true;

                    // Transform into refvol space
                    brickVolume.Transform(refTrans.refSpaceToWS.inverse);
                    ProbeReferenceVolume.Volume cellVolumeTrans = new ProbeReferenceVolume.Volume(cellVolume);
                    cellVolumeTrans.Transform(refTrans.refSpaceToWS.inverse);
                    cellVolumeTrans.maxSubdivisionMultiplier = localMaxSubdiv;

                    // Discard parent brick if it extends outside of the cell, to prevent duplicates
                    var brickVolumeMax = brickVolume.corner + brickVolume.X + brickVolume.Y + brickVolume.Z;
                    var cellVolumeMax  = cellVolumeTrans.corner + cellVolumeTrans.X + cellVolumeTrans.Y + cellVolumeTrans.Z;

                    f.discard = brickVolumeMax.x > cellVolumeMax.x ||
                                brickVolumeMax.y > cellVolumeMax.y ||
                                brickVolumeMax.z > cellVolumeMax.z ||
                                brickVolume.corner.x < cellVolumeTrans.corner.x ||
                                brickVolume.corner.y < cellVolumeTrans.corner.y ||
                                brickVolume.corner.z < cellVolumeTrans.corner.z;
                }
                else
                {
                    f.discard   = true;
                    f.subdivide = false;
                }
                outFlags.Add(f);
            }
        }
예제 #3
0
        // converts a volume into bricks, subdivides the bricks and culls subdivided volumes falling outside the original volume
        private void ConvertVolume(Volume cellVolume, List <Volume> subVolumes, SubdivisionDel subdivider, List <Brick> outSortedBricks)
        {
            Profiler.BeginSample("ConvertVolume");
            m_TmpBricks[0].Clear();
            Transform(cellVolume, out Volume vol);
            // rasterize bricks according to the coarsest grid
            Rasterize(vol, m_TmpBricks[0]);

            int subDivCount = 0;

            // iterative subdivision
            while (m_TmpBricks[0].Count > 0 && subDivCount <= GetMaxSubdivision(cellVolume.maxSubdivisionMultiplier))
            {
                m_TmpBricks[1].Clear();
                m_TmpFlags.Clear();
                m_TmpFlags.Capacity = Mathf.Max(m_TmpFlags.Capacity, m_TmpBricks[0].Count);

                Profiler.BeginSample("Subdivider");
                subdivider(m_Transform, subDivCount, m_TmpBricks[0], m_TmpFlags);
                Profiler.EndSample();
                Debug.Assert(m_TmpBricks[0].Count == m_TmpFlags.Count);

                for (int i = 0; i < m_TmpFlags.Count; i++)
                {
                    if (!m_TmpFlags[i].discard)
                    {
                        outSortedBricks.Add(m_TmpBricks[0][i]);
                    }
                    if (m_TmpFlags[i].subdivide)
                    {
                        m_TmpBricks[1].Add(m_TmpBricks[0][i]);
                    }
                }

                m_TmpBricks[0].Clear();
                if (m_TmpBricks[1].Count > 0)
                {
                    SubdivideBricks(m_TmpBricks[1], m_TmpBricks[0]);

                    // Cull out of bounds bricks
                    Profiler.BeginSample("Cull bricks");
                    for (int i = m_TmpBricks[0].Count - 1; i >= 0; i--)
                    {
                        if (!ProbeVolumePositioning.OBBIntersect(ref m_Transform, m_TmpBricks[0][i], ref cellVolume))
                        {
                            m_TmpBricks[0].RemoveAt(i);
                        }
                    }
                    Profiler.EndSample();
                }

                subDivCount++;
            }
            Profiler.EndSample();
        }
예제 #4
0
        internal static bool ShouldKeepBrick(List <ProbeReferenceVolume.Volume> volumes, ProbeReferenceVolume.Volume brick)
        {
            foreach (ProbeReferenceVolume.Volume v in volumes)
            {
                ProbeReferenceVolume.Volume vol = v;
                if (ProbeVolumePositioning.OBBIntersect(ref vol, ref brick))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        static protected void CullVolumes(ref List <ProbeReferenceVolume.Volume> cullees, ref List <ProbeReferenceVolume.Volume> cullers, ref List <ProbeReferenceVolume.Volume> result)
        {
            foreach (ProbeReferenceVolume.Volume v in cullers)
            {
                ProbeReferenceVolume.Volume lv = v;

                foreach (ProbeReferenceVolume.Volume c in cullees)
                {
                    if (result.Contains(c))
                    {
                        continue;
                    }

                    ProbeReferenceVolume.Volume lc = c;

                    if (ProbeVolumePositioning.OBBIntersect(ref lv, ref lc))
                    {
                        result.Add(c);
                    }
                }
            }
        }
예제 #6
0
        static protected int ProbeVolumesToVolumes(ref ProbeVolume[] probeVolumes, ref ProbeReferenceVolume.Volume cellVolume, ref List <ProbeReferenceVolume.Volume> volumes, ref Dictionary <Scene, int> sceneRefs)
        {
            int num = 0;

            foreach (ProbeVolume pv in probeVolumes)
            {
                if (!pv.isActiveAndEnabled)
                {
                    continue;
                }

                ProbeReferenceVolume.Volume indicatorVolume = new ProbeReferenceVolume.Volume(Matrix4x4.TRS(pv.transform.position, pv.transform.rotation, pv.GetExtents()), pv.parameters.maxSubdivisionMultiplier, pv.parameters.minSubdivisionMultiplier);

                if (ProbeVolumePositioning.OBBIntersect(ref cellVolume, ref indicatorVolume))
                {
                    cellVolume.maxSubdivisionMultiplier = Mathf.Max(cellVolume.maxSubdivisionMultiplier, pv.parameters.maxSubdivisionMultiplier, pv.parameters.minSubdivisionMultiplier);
                    volumes.Add(indicatorVolume);
                    TrackSceneRefs(pv.gameObject.scene, ref sceneRefs);
                    num++;
                }
            }

            return(num);
        }