Tạo địa hình đảo với tiếng ồn Simplex (C # / XNA)


7

Tôi có một câu hỏi nhỏ: Có mã hay mẫu nào cho thấy tiếng ồn đơn giản hoạt động không? Tôi không thể tìm thấy bất cứ điều gì về nó ... Tôi nên thực hiện nó như thế nào, mà không có kiến ​​thức về thuật toán hoạt động như thế nào? ...

Câu hỏi khác là: tiếng ồn đơn giản có phải là thuật toán tốt cho việc tạo đảo không? Tôi cần những hòn đảo lớn (thực sự rất lớn), với các lớp khác nhau (cát, gras, đá) và sự khác biệt rõ ràng về chiều cao, có các cạnh mềm, để bạn có thể ra / xuống nước mà không phải nhảy qua các bề mặt không bằng phẳng.


Hãy xem gamedev.stackexchange.com/questions/4628/ Từ Ngoài ra, bạn có đang tìm kiếm tiếng ồn đơn giản cụ thể không? Tôi có một mẫu tiếng ồn do tôi tự viết, nhưng nó không đơn giản (hoặc perlin thực sự .. đó là tiếng ồn được gọi là 'giá trị', trông đủ gần)
Vịt Cộng sản

hmm, không có thêm thông tin về tiếng ồn đơn giản ... hay tuy nhiên? Các mẫu sẽ hữu ích :) có lẽ bạn có thể đưa nó cho tôi? cảm ơn :)
SharpShade

Tôi không muốn đây là câu trả lời vì đây không phải là tác phẩm của tôi, nhưng bạn có thể lấy bài viết Nghiên cứu về Tiếng ồn Simplex mà Ken đã viết tại: cs.umbc.edu/~olano/s2002c36/ch02.pdf (Liên kết này là từ dưới cùng của bài viết wikipedia được liên kết đến từ bài viết bạn đã đăng bên dưới.) PS: Nó bao gồm mã cho C và Java ở cuối bài viết.
James

Câu trả lời:


1

Trình tạo tiếng ồn của tôi trong C #, dựa trên điều này :

static class NoiseGenerator
{
    public static int Seed { get; private set; }

    public static int Octaves { get; set; }

    public static double Amplitude { get; set; }

    public static double Persistence { get; set; }

    public static double Frequency { get; set; }

    static NoiseGenerator()
    {
        Random r = new Random();
        //LOOOL
        NoiseGenerator.Seed = r.Next(Int32.MaxValue);
        NoiseGenerator.Octaves = 8;
        NoiseGenerator.Amplitude = 1;
        NoiseGenerator.Frequency = 0.015;
        NoiseGenerator.Persistence = 0.65;
    }

    public static double Noise(int x, int y)
    {
        //returns -1 to 1
        double total = 0.0;
        double freq = NoiseGenerator.Frequency, amp = NoiseGenerator.Amplitude;
        for (int i = 0; i < NoiseGenerator.Octaves; ++i)
        {
            total = total + NoiseGenerator.Smooth(x * freq, y * freq) * amp;
            freq *= 2;
            amp *= NoiseGenerator.Persistence;
        }
        if (total < -2.4) total = -2.4;
        else if (total > 2.4) total = 2.4;

        return (total/ 2.4);
    }

    public static double NoiseGeneration(int x, int y)
    {
        int n = x + y * 57;
        n = (n << 13) ^ n;

        return (1.0 - ((n * (n * n * 15731 + 789221) + NoiseGenerator.Seed) & 0x7fffffff) / 1073741824.0);
    }

    private static double Interpolate(double x, double y, double a)
    {
        double value = (1 - Math.Cos(a * Math.PI)) * 0.5;
        return x * (1 - value) + y * value;
    }

    private static double Smooth(double x, double y)
    {
        double n1 = NoiseGeneration((int)x, (int)y);
        double n2 = NoiseGeneration((int)x + 1, (int)y);
        double n3 = NoiseGeneration((int)x, (int)y + 1);
        double n4 = NoiseGeneration((int)x + 1, (int)y + 1);

        double i1 = Interpolate(n1, n2, x - (int)x);
        double i2 = Interpolate(n3, n4, x - (int)x);

        return Interpolate(i1, i2, y - (int)y);
    }
}

Nó không được bình luận, nhưng các phần chính:

Hạt giống là một giá trị được sử dụng để làm cho nó ngẫu nhiên - vì vậy bạn không tạo ra cùng một thứ mỗi lần. Ở đây tôi đã đặt nó trong NoiseGenerator.

Biên độ, tần số, tính bền bỉ và Octaves được giải thích trong bài viết - về cơ bản chúng ảnh hưởng đến những gì tiếng ồn kết quả trông như thế nào.

NoiseGenerator Hàm có nghĩa đen là một PRNG - cung cấp cho nó một đầu vào và nó tạo ra một số ngẫu nhiên với số đó là một hạt giống.

Noiselà những gì bạn gọi để có được một giá trị tiếng ồn. Tôi tìm thấy các giá trị là khoảng -2,4 đến 2,4 (thực tế là khoảng 2.40032483 hoặc một cái gì đó để chúng được kẹp) và tôi đã sửa chúng thành hai lần giữa -1 and 1.

Tôi không có bất kỳ vấn đề tốc độ với điều này. Tôi đã kết xuất một lưới 400x400 gồm các họa tiết 1x1 với các giá trị được đặt bởi điều này và chỉ nhận được độ trễ nhỏ (và đó là tính toán lại nhiễu mỗi khung hình).

Đối với thế hệ đảo, hãy xem câu hỏi này - đặc biệt, liên kết này gần như chính xác những gì bạn muốn, mặc dù trong AS3.


Ehm, xin lỗi tôi đã quên nói rằng tôi cần một trình tạo tạo ra sơ đồ chiều cao. Hoặc làm thế nào tôi có thể sử dụng điều này để tạo địa hình? Hiện tại, tôi tạo ra một sơ đồ chiều cao (tôi đã thử nhiều thuật toán khác nhau ...) và sau đó tính toán các đỉnh. Vấn đề lớn là, tôi cần một thuật toán thế hệ tạo ra các hòn đảo ưa nhìn: - / tôi biết, tôi khó, nhưng tôi không biết làm thế nào tôi nên làm điều này ...
SharpShade

@Razer Sử dụng tọa độ của sơ đồ chiều cao của bạn - giả sử x, y - làm đầu vào cho chức năng Nhiễu. Nó sẽ gán cho mỗi điểm một giá trị trong khoảng từ -1 đến 1, do đó bạn có thể cần thực hiện một số thao tác chuẩn hóa ((giá trị + 1) * 127.5f hoạt động để có được giá trị trong khoảng từ 0 đến 255)
Vịt Cộng sản

Nó hoạt động, nhưng không hay lắm ... Những gì tôi muốn là một cái gì đó như thế này: hazelmckendrick.com/demos/terrain-generation-tropical-island
SharpShade

1
@Razer Tại sao không sử dụng nguồn đó?
Vịt Cộng sản

Bởi vì không có mô tả về các thuật toán được sử dụng, không có mã và không có gì. Vâng tôi biết, nguồn được bao gồm, nhưng nó Cs. Tôi không hiểu được C ++: - /
SharpShade

1

Ok cảm ơn tất cả sự giúp đỡ :)

2 ngày trước tôi đã tìm thấy "Libnoise" và một cổng C # tốt. Tôi sẽ lấy cái này, bởi vì có Trình kết xuất biểu hiện trong đó giúp hiển thị các chiều cao mượt mà hơn :)


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.