【问题标题】:Perlin noise glitchPerlin 噪声故障
【发布时间】:2020-06-22 21:29:49
【问题描述】:

我有一个无限地图生成器。它适用于正坐标。 Positive coordinates generation 1

但是在负坐标上我有这个垃圾: Negative coordinates broken generation 2

void generateChunk(int x0, int y0) {
    Chunk chunk = new Chunk(x0, y0);
    for(int yTile = 0; yTile < Chunk.CHUNK_SIZE; yTile++) {
        for(int xTile = 0; xTile < Chunk.CHUNK_SIZE; xTile++) {

            int pX = chunk.x0 + xTile;
            int pY = chunk.y0 + yTile;

            double perlinNoiseHeight = floorPerlinNoise.getHeight(pX, pY);;

            if(perlinNoiseHeight > BEACH_AREA) {
                chunk.setFloor(GrassTile.ID, xTile, yTile);
            } else if(perlinNoiseHeight > 0) {
                chunk.setFloor(SandTile.ID, xTile, yTile);
            } else {
                chunk.setFloor(WaterTile.ID, xTile, yTile);
            }
        }
    }
    saveChunk(chunk);
}

柏林噪声类:

package org.ixnomad.game.level.generation;

public class PerlinNoise {

    private double persistence, frequency, amplitude;
    private int octaves;
    private long seed;

    public PerlinNoise(double persistence, double frequency, double amplitude, int octaves, long seed) {
        this.persistence    = persistence;
        this.amplitude      = amplitude;
        this.frequency      = frequency;
        this.octaves        = octaves;
        this.seed           = seed;
    }

    public double getHeight(double x, double y) {
        return amplitude * total(x, y) + 0.4;
    }

    private double total(double i, double j) {
        double total = 0.0d;
        double _ampl = 1;
        double _freq = frequency;
        for(int k = 0; k < octaves; k++) {
            total += getValue(j * _freq + seed, i * _freq + seed) * _ampl;
            _ampl *= persistence;
            _freq *= 2;
        }
        return total;
    }

    private double getValue(double x, double y) {
        int xInt = (int) x;
        int yInt = (int) y;
        double xFrac = x - xInt;
        double yFrac = y - yInt;

        double n01 = noise(xInt-1, yInt-1);
        double n02 = noise(xInt+1, yInt-1);
        double n03 = noise(xInt-1, yInt+1);
        double n04 = noise(xInt+1, yInt+1);
        double n05 = noise(xInt-1, yInt  );
        double n06 = noise(xInt+1, yInt  );
        double n07 = noise(xInt  , yInt-1);
        double n08 = noise(xInt  , yInt+1);
        double n09 = noise(xInt  , yInt  );

        double n12 = noise(xInt+2, yInt-1);
        double n14 = noise(xInt+2, yInt+1);
        double n16 = noise(xInt+2, yInt  );

        double n23 = noise(xInt-1, yInt+2);
        double n24 = noise(xInt+1, yInt+2);
        double n28 = noise(xInt  , yInt+2);

        double n34 = noise(xInt+2, yInt+2);

        double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
        double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
        double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
        double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);

        double v1 = interpolate(x0y0, x1y0, xFrac);
        double v2 = interpolate(x0y1, x1y1, xFrac);
        return interpolate(v1, v2, yFrac);
    }

    private double interpolate(double x, double y, double frac) {
        double negFrac = 1.0 - frac;
        double negFraqSqr = negFrac * negFrac;
        double fac1 = 3.0 * negFraqSqr - 2.0 * negFraqSqr * negFrac;

        double fracSqr = frac * frac;
        double fac2 = 3.0 * fracSqr - 2.0 * fracSqr * frac;

        return x * fac1 + y * fac2;
    }

    private double noise(int x, int y) {
        int n = x + y * 57;
        n = (n << 13) ^ n;
        int t = (n * (n * n * 15713 + 789221) + 1376312589) & 0x7fffffff;
        return 1.0d - (double) (t * 0.931322574615478515625e-9);
    }

}

我试图解决这个问题一整天,但我不知道,我做错了什么。我认为问题在于位移(private double noise(double x, double y)),但问题并不取决于它。 我尝试使用这个 Perlin 的算法:https://mrl.nyu.edu/~perlin/noise/ 但效果是一样的。

【问题讨论】:

    标签: java game-engine game-development procedural-generation


    【解决方案1】:

    早上好,我可能已经解决了问题:D Jush 应该睡觉并重新加载大脑)

    只需使用整数可以带来的最大值并将生成坐标移动到一半:D

    int maxint = 0x07fffffff;
    double perlinNoiseHeight = floorPerlinNoise.getHeight(pX + (maxint >> 1), pY + (maxint >> 1));
    

    这是一个简单的解决方案,但它有效) Negative coordinates

    【讨论】:

      猜你喜欢
      • 2014-02-15
      • 2020-06-06
      • 2011-09-20
      • 2021-06-30
      • 2013-07-23
      • 2011-03-19
      • 1970-01-01
      • 2014-05-21
      • 2014-04-18
      相关资源
      最近更新 更多