1

スクロールする地形を作成するために使用しようとしているパーリン ノイズ ジェネレーターがあります。

中央の地形、それを囲む同じ側の 8 つの地形 (これらは正常に機能しています)、および 3 倍大きい地形の 2 番目のリングがあります。これらの場合、ノイズ ジェネレーターが 3 倍の「密度」のノイズを出力する必要があります。これにより、小さな地形の上に大きな地形を配置でき、3 倍のタイル (およびマップ サイズ) を除いて、それらは一致します。 .

より大きなマップを生成したいだけではありません。それはすぐに法外になるでしょう。

私は何をすべきかわかりません; 明らかな解決策はすべて、何らかの形で失敗しました。

    /// <summary>
    /// Generates a new perlin map.
    /// </summary>
    /// <param name="xStart">The left coordinate (using 0, 0 as top-left and +, + as down and to the right).</param>
    /// <param name="yStart">The top coordinate (using 0, 0 as top-left and +, + as down and to the right).</param>
    /// <param name="width">The width of the map.</param>
    /// <param name="length">The length of the map.</param>
    /// <param name="persistance">If set, values lower than 1 make the map less noisey; values greater than 1 make the map more noisy.</param>
    /// <param name="fromShift">Low values here provide for a broader "base".</param>
    /// <param name="toShift">High values here provide for more speckled "highlights".</param>
    /// <param name="interpolate">If set to false, the algorithm will not smooth values.</param>
    public double[,] Generate(
        int xStart, int yStart,
        int width, int length,
        double? persistance,
        uint fromShift, uint toShift,
        bool interpolate = true,
    )
    {
        _noiseMap = new double[width, length];
        _workingMap = new double[width + 6, length + 6];
        _smoothedNoise = new double[width + 6, length + 6];
        int ifromShift = -(int)(toShift),
            itoShift = -(int)(fromShift);
        int idiv = 1 + (itoShift - ifromShift);
        double ddiv = 0;
        double amplitude = 0.0;
        if (persistance.HasValue)
            for (int i = ifromShift; i <= itoShift; ++i)
                ddiv += Math.Pow(persistance.Value, i);

        for (int i = ifromShift; i <= itoShift; ++i)
        {
            _frequency = Math.Pow(2, i);
            if (persistance.HasValue) amplitude = Math.Pow(persistance.Value, i);
            int useWidth = (int)(width * _frequency) + 1,
                useLength = (int)(length * _frequency) + 1;
            int useXStart = (int)(xStart * _frequency),
                useYStart = (int)(yStart * _frequency);
            double frequencyXStart = xStart * _frequency - useXStart,
                frequencyYStart = yStart * _frequency - useYStart;

            for (int y = 0; y < useLength + 5; ++y)
                for (int x = 0; x < useWidth + 5; ++x)
                {
                    int genX = ((int)(useXStart) + (int)((x) + 0.5));
                    int genY = ((int)(useYStart) + (int)((y) + 0.5));
                    _workingMap[x, y] = GenerateNoise(genX, genY);
                }

            if (interpolate)
            {
                for (int y = 1; y < length + 4; ++y)
                    for (int x = 1; x < width + 4; ++x)
                    {
                        _smoothedNoise[x, y] = SmoothedNoise(x, y);
                    }

                if (persistance.HasValue)
                    for (int y = 0; y < length; ++y)
                        for (int x = 0; x < width; ++x)
                        {
                            _noiseMap[x, y] += InterpolatedNoise((x * _frequency) + 2 + frequencyXStart, (y * _frequency) + 2 + frequencyYStart) * amplitude;
                            // _noiseMap[x, y] += _workingMap[x, y] * amplitude;
                        }
                else
                    for (int y = 0; y < length; ++y)
                        for (int x = 0; x < width; ++x)
                        {
                            _noiseMap[x, y] += InterpolatedNoise((x * _frequency) + 2 + frequencyXStart, (y * _frequency) + 2 + frequencyYStart) / idiv;
                            // _noiseMap[x, y] += _workingMap[x, y] / idiv;
                        }
            }
            else
                if (persistance.HasValue)
                    for (int y = 0; y < length; ++y)
                        for (int x = 0; x < width; ++x)
                        {
                            _noiseMap[x, y] +=
                                _workingMap[(int)((x * _frequency) + 2 + frequencyXStart), (int)((y * _frequency) + 2 + frequencyYStart)] * amplitude;
                        }
                else
                    for (int y = 0; y < length; ++y)
                        for (int x = 0; x < width; ++x)
                        {
                            _noiseMap[x, y] +=
                                _workingMap[(int)((x * _frequency) + 2 + frequencyXStart), (int)((y * _frequency) + 2 + frequencyYStart)] / idiv;
                        }
        }

        if (persistance.HasValue)
            for (int y = 0; y < length; ++y)
                for (int x = 0; x < width; ++x)
                {
                    _noiseMap[x, y] = _noiseMap[x, y] / ddiv;
                }

        return _noiseMap;
    }

ありがとう。

4

2 に答える 2

0

明確にするために(あなたの問題の私の理解をチェックするために)。

サイズXの辺を持つマップAを生成します。このマップは、それぞれサイズXの辺を持つ9つのマップB1 ... B9で囲まれています。次に、マップB1...を囲むマップC1...C2が必要です。外からB9。これらの各マップの側面のサイズは3Xですが、データポイントはX ^ 2のみです(各データポイントのサイズは3x3になります)。

右?

最近傍アルゴリズムでデータを補間してみましたか?コードが座標Xからのデータを要求する場合は、座標を3の倍数に丸めて使用します。これでうまくいくと思います。

別のオプションは、各再帰ステップでタイルを2つではなく、3つの部分に分割することを除いて、中点変位アルゴリズムを使用することです。これにより、1ラウンドを早期に停止できるようになり、探している結果が表示されます。3x3グリッドの交点でのみ生成されたデータポイントを含む高さマップ。残りのポイントに触れる必要はありません。

于 2011-03-16T15:29:40.117 に答える
0

パーリン ノイズは、サンプルよりもはるかに密度が高いため、1 つのアルゴリズムの形状はすべてのグリッドで密度が高くなります。さらに詳細が必要な場合は、オクターブまたはノイズの 2 番目のパスを追加する必要があります。この場合、グリッドは適切にオーバーレイされません。したがって、形状を選択し、異なるグリッド密度でサンプリングすることが問題です。

于 2014-03-05T09:40:51.793 に答える