/// <summary>
        /// Initialize the reference volume.
        /// </summary>
        /// <param name ="allocationSize"> Size used for the chunk allocator that handles bricks.</param>
        /// <param name ="memoryBudget">Probe reference volume memory budget.</param>
        /// <param name ="indexDimensions">Dimensions of the index data structure.</param>
        public void InitProbeReferenceVolume(int allocationSize, ProbeVolumeTextureMemoryBudget memoryBudget, Vector3Int indexDimensions)
        {
            if (!m_ProbeReferenceVolumeInit)
            {
                Profiler.BeginSample("Initialize Reference Volume");
                m_Pool = new ProbeBrickPool(allocationSize, memoryBudget);
                if ((indexDimensions.x * (indexDimensions.y + 1) * indexDimensions.z) == 0)
                {
                    // Give a momentarily dummy size to allow the system to function with no asset assigned.
                    indexDimensions = new Vector3Int(1, 1, 1);
                }
                m_Index = new ProbeBrickIndex(indexDimensions);

                m_TmpBricks[0]          = new List <Brick>();
                m_TmpBricks[1]          = new List <Brick>();
                m_TmpBricks[0].Capacity = m_TmpBricks[1].Capacity = 1024;

                // initialize offsets
                m_PositionOffsets[0] = 0.0f;
                float probeDelta = 1.0f / ProbeBrickPool.kBrickCellCount;
                for (int i = 1; i < ProbeBrickPool.kBrickProbeCountPerDim - 1; i++)
                {
                    m_PositionOffsets[i] = i * probeDelta;
                }
                m_PositionOffsets[m_PositionOffsets.Length - 1] = 1.0f;
                Profiler.EndSample();

                m_ProbeReferenceVolumeInit = true;
            }
            m_NeedLoadAsset = true;
        }
        private void LoadAsset(ProbeVolumeAsset asset)
        {
            var path = asset.GetSerializedFullPath();

            m_AssetPathToBricks[path] = new List <RegId>();

            foreach (var cell in asset.cells)
            {
                // Push data to HDRP
                bool compressed   = false;
                var  dataLocation = ProbeBrickPool.CreateDataLocation(cell.sh.Length, compressed, ProbeVolumeSHBands.SphericalHarmonicsL2);
                ProbeBrickPool.FillDataLocation(ref dataLocation, cell.sh, ProbeVolumeSHBands.SphericalHarmonicsL2);

                // TODO register ID of brick list
                List <ProbeBrickIndex.Brick> brickList = new List <ProbeBrickIndex.Brick>();
                brickList.AddRange(cell.bricks);
                var regId = AddBricks(brickList, dataLocation);

                cells[cell.index] = cell;
                m_AssetPathToBricks[path].Add(regId);

                dataLocation.Cleanup();
            }
        }
Exemple #3
0
        // This is very much modeled  to be as close as possible to the way bricks are loaded in the texture pool.
        // Not necessarily a good thing.
        static void ComputeValidityMasks(BakingCell bakingCell)
        {
            var bricks           = bakingCell.bricks;
            var cell             = bakingCell;
            int chunkSize        = ProbeBrickPool.GetChunkSize();
            int brickChunksCount = (bricks.Length + chunkSize - 1) / chunkSize;

            var probeHasEmptySpaceInGrid = new NativeArray <bool>(bakingCell.probePositions.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);


            int chunkIndex = 0;

            while (chunkIndex < brickChunksCount)
            {
                int        chunkToProcess = Math.Min(ProbeReferenceVolume.kTemporaryDataLocChunkCount, brickChunksCount - chunkIndex);
                Vector3Int locSize = ProbeBrickPool.ProbeCountToDataLocSize(ProbeReferenceVolume.kTemporaryDataLocChunkCount * ProbeBrickPool.GetChunkSizeInProbeCount());
                int        size = locSize.x * locSize.y * locSize.z;
                int        startIndex = chunkIndex * ProbeBrickPool.GetChunkSizeInProbeCount();
                int        count = chunkToProcess * ProbeBrickPool.GetChunkSizeInProbeCount();
                int        shidx = startIndex;
                int        bx = 0, by = 0, bz = 0;

                s_Validity_locData.Resize(size);
                s_ProbeIndices.Resize(size);

                Dictionary <Vector3Int, (float, Vector3, Bounds)> probesToRestoreInfo = new Dictionary <Vector3Int, (float, Vector3, Bounds)>();
                HashSet <Vector3Int> probesToRestore = new HashSet <Vector3Int>();

                for (int brickIdx = startIndex; brickIdx < (startIndex + count); brickIdx += ProbeBrickPool.kBrickProbeCountTotal)
                {
                    for (int z = 0; z < ProbeBrickPool.kBrickProbeCountPerDim; z++)
                    {
                        for (int y = 0; y < ProbeBrickPool.kBrickProbeCountPerDim; y++)
                        {
                            for (int x = 0; x < ProbeBrickPool.kBrickProbeCountPerDim; x++)
                            {
                                int ix = bx + x;
                                int iy = by + y;
                                int iz = bz + z;

                                if (shidx >= cell.validity.Length)
                                {
                                    StoreScratchData(ix, iy, iz, locSize.x, locSize.y, 1.0f, shidx);
                                }
                                else
                                {
                                    StoreScratchData(ix, iy, iz, locSize.x, locSize.y, ProbeReferenceVolume.Cell.GetValidityFromPacked(cell.validity[shidx]), shidx);

                                    // Check if we need to do some extra check on this probe.
                                    bool   hasFreeNeighbourhood = false;
                                    Bounds invalidatingTouchupBound;
                                    if (s_ForceInvalidatedProbesAndTouchupVols.TryGetValue(cell.probePositions[shidx], out invalidatingTouchupBound))
                                    {
                                        int     actualBrickIdx = brickIdx / ProbeBrickPool.kBrickProbeCountTotal;
                                        float   brickSize      = ProbeReferenceVolume.CellSize(cell.bricks[actualBrickIdx].subdivisionLevel);
                                        Vector3 position       = cell.probePositions[shidx];
                                        probesToRestore.Add(new Vector3Int(ix, iy, iz));
                                        var searchDistance = (brickSize * m_BakingProfile.minBrickSize) / ProbeBrickPool.kBrickCellCount;
                                        hasFreeNeighbourhood = NeighbourhoodIsEmptySpace(position, searchDistance, invalidatingTouchupBound);
                                    }
                                    probeHasEmptySpaceInGrid[shidx] = hasFreeNeighbourhood;
                                }
                                shidx++;
                            }
                        }
                    }

                    // update the pool index
                    bx += ProbeBrickPool.kBrickProbeCountPerDim;
                    if (bx >= locSize.x)
                    {
                        bx  = 0;
                        by += ProbeBrickPool.kBrickProbeCountPerDim;
                        if (by >= locSize.y)
                        {
                            by  = 0;
                            bz += ProbeBrickPool.kBrickProbeCountPerDim;
                        }
                    }
                }

                for (int x = 0; x < locSize.x; ++x)
                {
                    for (int y = 0; y < locSize.y; ++y)
                    {
                        for (int z = 0; z < locSize.z; ++z)
                        {
                            int   outIdx        = ReadProbeIndex(x, y, z, locSize.x, locSize.y);
                            float probeValidity = ReadValidity(x, y, z, locSize.x, locSize.y);

                            if (outIdx < cell.validity.Length)
                            {
                                float[] validities    = new float[8];
                                bool    forceAllValid = false;
                                for (int o = 0; o < 8; ++o)
                                {
                                    Vector3Int off       = GetSampleOffset(o);
                                    Vector3Int samplePos = new Vector3Int(Mathf.Clamp(x + off.x, 0, locSize.x - 1),
                                                                          Mathf.Clamp(y + off.y, 0, locSize.y - 1),
                                                                          Mathf.Clamp(z + off.z, 0, ProbeBrickPool.kBrickProbeCountPerDim - 1));

                                    if (probesToRestore.Contains(samplePos))
                                    {
                                        if (probeHasEmptySpaceInGrid[outIdx])
                                        {
                                            forceAllValid = true;
                                        }
                                    }

                                    validities[o] = ReadValidity(samplePos.x, samplePos.y, samplePos.z, locSize.x, locSize.y);
                                }

                                byte  mask     = forceAllValid ? (byte)255 : Convert.ToByte(PackValidity(validities));
                                float validity = probeValidity;

                                cell.validity[outIdx] = ProbeReferenceVolume.Cell.PackValidityAndMask(validity, mask);
                            }
                        }
                    }
                }

                chunkIndex += ProbeReferenceVolume.kTemporaryDataLocChunkCount;
            }

            probeHasEmptySpaceInGrid.Dispose();
        }