void AddNeighbor(Queue <FloodFillPixelInfo> queue, ref FloodFillPixelInfo info, int textureSize, int dx, int dy, float decayMultiplier) { FloodFillPixelInfo neighbor = info; neighbor.currentPixel.x += dx; neighbor.currentPixel.y += dy; if (neighbor.currentPixel.x < 0 || neighbor.currentPixel.x >= textureSize || neighbor.currentPixel.y < 0 || neighbor.currentPixel.y >= textureSize) { // Out of bounds return; } var distance = neighbor.DistanceToSource(); var weight = (neighbor.startValue - distance / textureSize * decayMultiplier); weight = Mathf.Clamp01(weight); if (weight <= 0) { return; } int nx = neighbor.currentPixel.x; int ny = neighbor.currentPixel.y; float existingWeight = splatData.Data[nx, ny]; if (weight > existingWeight) { splatData.Data[nx, ny] = weight; queue.Enqueue(neighbor); } }
/// <summary> /// flood fills from every pixel whose value is are greater than 0. /// This creates a nice blur like effect. Useful for making thick lines from the generated map /// </summary> /// <param name="splatData"></param> /// <param name="decay"></param> public void DecayFloodFill(float decayMultiplier) { var sw = System.Diagnostics.Stopwatch.StartNew(); int textureSize = splatData.Data.GetLength(0); var queue = new Queue <FloodFillPixelInfo>(); for (int y = 0; y < textureSize; y++) { for (int x = 0; x < textureSize; x++) { float value = splatData.Data[x, y]; if (value > 0.01f) { var info = new FloodFillPixelInfo(); info.currentPixel = new IntVector2(x, y); info.sourcePixel = new IntVector2(x, y); info.startValue = value; queue.Enqueue(info); } } } while (queue.Count > 0) { var front = queue.Dequeue(); AddNeighbor(queue, ref front, textureSize, -1, 0, decayMultiplier); AddNeighbor(queue, ref front, textureSize, 1, 0, decayMultiplier); AddNeighbor(queue, ref front, textureSize, 0, 1, decayMultiplier); AddNeighbor(queue, ref front, textureSize, 0, -1, decayMultiplier); } sw.Stop(); Debug.Log("Time elapsed: " + (sw.ElapsedMilliseconds / 1000.0f) + " s"); }