Esempio n. 1
0
        /// <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.
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public override void Process(GridBuffer buffer, int channel)
        {
            int xCenter = (m_xMin + m_xMax) / 2;
            int yCenter = (m_yMin + m_yMax) / 2;

            float tmpValue = 0;

            for (int x = m_xMin; x <= xCenter; x++)
            {
                int xLeft = Mathf.Max(m_xMin, x - 1);

                for (int y = m_yMin; y <= yCenter; y++)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yTop = Mathf.Max(m_yMin, y - 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xLeft, y),
                            buffer.Read(channel, x, yTop),
                            buffer.Read(channel, xLeft, yTop));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }

            tmpValue = 0;

            for (int x = m_xMax; x > xCenter; x--)
            {
                int xRight = Mathf.Min(m_xMax, x + 1);

                for (int y = m_yMin; y <= yCenter; y++)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yTop = Mathf.Max(m_yMin, y - 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xRight, y),
                            buffer.Read(channel, x, yTop),
                            buffer.Read(channel, xRight, yTop));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }

            tmpValue = 0;

            for (int x = m_xMin; x <= xCenter; x++)
            {
                int xLeft = Mathf.Max(m_xMin, x - 1);

                for (int y = m_yMax; y > yCenter; y--)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yBottom = Mathf.Min(m_yMax, y + 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xLeft, y),
                            buffer.Read(channel, x, yBottom),
                            buffer.Read(channel, xLeft, yBottom));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }

            tmpValue = 0;

            for (int x = m_xMax; x > xCenter; x--)
            {
                int xRight = Mathf.Min(m_xMax, x + 1);

                for (int y = m_yMax; y > yCenter; y--)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yBottom = Mathf.Min(m_yMax, y + 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xRight, y),
                            buffer.Read(channel, x, yBottom),
                            buffer.Read(channel, xRight, yBottom));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }
        }
Esempio n. 3
0
        /// <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.
        }