平滑数据的问题

时间:2017-02-25 04:27:47

标签: c# algorithm unity3d smoothing

我正在尝试平滑我的2D数组。我确信有更好的方法,但我还没有找到它。到目前为止,我正在使用这段代码来平滑它。

你可以在后面看到,有一个区域,一个条目向上/向下错误的方向。它使单个像素看起来比周围的所有像素更暗/更亮。

在平滑数据方面我做错了什么?

        for (int i = 0; i < 3; i++) {
            for (int y = 0; y < mapChunkSize + 2; y++) {
                for (int x = 0; x < mapChunkSize + 2; x++) {
                    int count = 0;
                    int dir = 0;
                    if (x - 1 >= 0 && y - 1 >= 0 && noiseMap [x - 1, y - 1] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x - 1, y - 1] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }
                    if (x - 1 >= 0 && noiseMap [x - 1, y] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x - 1, y] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }
                    if (x - 1 >= 0 && y + 1 <= mapChunkSize && noiseMap [x - 1, y + 1] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x - 1, y + 1] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }

                    if (y - 1 >= 0 && noiseMap [x, y - 1] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x, y - 1] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }
                    if (y + 1 <= mapChunkSize && noiseMap [x, y + 1] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x, y + 1] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }

                    if (x + 1 <= mapChunkSize && y - 1 >= 0 && noiseMap [x + 1, y - 1] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x + 1, y - 1] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }
                    if (x + 1 <= mapChunkSize && noiseMap [x + 1, y] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x + 1, y] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }
                    if (x + 1 <= mapChunkSize && y + 1 <= mapChunkSize && noiseMap [x + 1, y + 1] != noiseMap [x, y]) {
                        count += 1;
                        if (noiseMap [x + 1, y + 1] > noiseMap [x, y]) {
                            dir += 1;
                        } else {
                            dir -= 1;
                        }
                    }

                    if (count > 4) {
                        if (dir > 0) {
                            noiseMap [x, y] += stepHeight;
                        }
                        if (dir < 0) {
                            noiseMap [x, y] -= stepHeight;
                        }
                    }
                }
            }
        }

在:

enter image description here

后:

enter image description here

1 个答案:

答案 0 :(得分:0)

该代码看起来像是调试的噩梦。话虽这么说,我之前看过像这样的图像伪像,看起来很像mcdowella建议的那样:你在分配2D阵列的同时从中读取,从而导致你的检查不准确。但是很难解读。

我确定你可以通过简单地提高一个小区的邻居的平均值来获得相同的行为。以下示例应该有希望做到这一点(未经测试,但希望传达这个想法):

//Assumes all height values in the 2D array are normalized between 0-1
float[,] RampAverage( float[,] values, int rampSteps){
    int valuesWidth = values.GetLength(0);
    int valuesHeight = values.GetLength(1);
    float[,] tempValues = new float[valuesWidth,valuesHeight];

    for (int x = 0; x < valuesWidth; x ++){
        for(int y = 0; y < valuesHeight; y++){
            Vector2 key = new Vector2(x,y);
            float neighborAverage = GetNeighborAverage(values,key);
            tempValues[x,y] = Ramp(neighborAverage,rampSteps);
        }
    }

    return tempValues;
}

// Assumes all values are between 0-1
float Ramp(float value, int rampSteps){
    float step = 1/rampSteps;
    int d = Mathf.FloorToInt(value/step);
    return d*step;
}

float GetNeighborAverage(float[,] values, Vector2 key){
    int contributors = 0;
    float value = 0;

    int maxX = values.GetLength(0)-1;
    int maxY = valuse.GetLength(1)-1;

    for (int y = -1; y <= 1; y++)
    {
        for (int x = -1; x <= 1; x++)
        {
            int xIndex = x + (int)key.x;
            int yIndex = y + (int)key.y;
            if (xIndex >= 0 && yIndex >= 0 && xIndex <= maxX-1 && yIndex <= maxY-1)
            {
                value += values[xIndex,yIndex];
                contributors ++;
            }
        }
    }
    return value/contributors;
}