/// <inheritdoc/> public override void Process(GridBuffer buffer, int channel) { // Side length of squares around points required for filling // Width x Height, IF positions were distributed evenly. float sparseness = Mathf.Sqrt(Width * Height / (float)GridPositions.Count); if (sparseness > 1) { sparseness *= c_Multiplier; foreach (Vector2Int pGrid in GridPositions) { int xGrid = pGrid.x; int yGrid = pGrid.y; float proximity = m_AuxGrid.Read(0, xGrid, yGrid); // Get matching kernel size for current proximity and point sparseness. var kernel = m_Kernels[Mathf.Min(Mathf.RoundToInt(sparseness * proximity), c_MaxRadius - 1)]; float bufferValue = buffer.Read(channel, xGrid, yGrid); foreach (var pKernel in kernel) { int xDilate = xGrid + pKernel.x; int yDilate = yGrid + pKernel.y; // TryRead -> Dilation area might go beyond grid size. if (m_AuxGrid.TryRead(1, xDilate, yDilate, out float kernelValue)) { // Occlusion, 3D specific: // Write maximum kernel value if already set. m_AuxGrid.Write(1, xDilate, yDilate, Mathf.Max(pKernel.value, kernelValue)); // Write maximum buffer value if already set. m_AuxGrid.Write(2, xDilate, yDilate, Mathf.Max(m_AuxGrid.Read(2, xDilate, yDilate), bufferValue)); Expand(xDilate, yDilate); } } } // Expanded area. for (int x = m_xMin; x <= m_xMax; x++) { for (int y = m_yMin; y <= m_yMax; y++) { if (m_AuxGrid.Read(1, x, y) > c_Threshold) { // Copy back dilated buffer values. buffer.Write(channel, x, y, m_AuxGrid.Read(2, x, y)); // Store for later Write(buffer, channel, value) call. GridPositions.Add(new Vector2Int(x, y)); } } } } // else: keep original positions, they're dense enough. }
/// <inheritdoc/> public override void Process(GridBuffer buffer, int channel) { // Side length of squares around points required for filling // Width x Height, IF positions were distributed evenly. float sparseness = Mathf.Sqrt(Width * Height / (float)GridPositions.Count); if (sparseness > 1) { // Make downsample area a bit larger than // sparseness value in order to prevent gaps. int size = Mathf.RoundToInt(sparseness) + 2; // TBD pad // Bottom/left offset. int xOffset = m_xMin - (size - Width % size) / 2; int yOffset = m_yMin - (size - Height % size) / 2; int nx = 0, ny = 0; foreach (Vector2Int point in GridPositions) { // Downsampling: grid pos -> sample pos. int xSample = (point.x - xOffset) / size; int ySample = (point.y - yOffset) / size; nx = Mathf.Max(nx, xSample); ny = Mathf.Max(ny, ySample); m_Samples[xSample, ySample] = Mathf.Max( m_Samples[xSample, ySample], buffer.Read(channel, point)); } // Replace grid points with squares (size x size). GridPositions.Clear(); for (int xSample = 0; xSample <= nx; xSample++) { for (int ySample = 0; ySample <= ny; ySample++) { float sampleValue = m_Samples[xSample, ySample]; if (sampleValue > 0) { // Upscaling: sample pos -> grid pos. int xGrid = xOffset + xSample * size; int yGrid = yOffset + ySample * size; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { Vector2Int gridPos = new Vector2Int(xGrid + x, yGrid + y); // TryRead -> Square might go beyond grid size. if (buffer.TryRead(channel, gridPos, out float bufferValue)) { // Occlusion, 3D specific: // Write maximum buffer value if already set. buffer.Write(channel, gridPos, Mathf.Max(bufferValue, sampleValue)); // Store for later Write(buffer, channel, value) call. GridPositions.Add(gridPos); } } } } } } } // else: keep original positions, they're dense enough. }