Gerando terrenos insulares com ruído simplex (C # / XNA)

7

Eu tenho uma pequena pergunta: Existe algum código ou amostra que mostra como o ruído simplex funciona? Não consigo encontrar nada sobre isso ... Como devo implementá-lo, sem o conhecimento de como o algoritmo funciona? ...

A outra pergunta é: o ruído simplex é um bom algoritmo para a geração de ilhas? Preciso de ilhas enormes (realmente enormes), com diferentes camadas (areia, areia, pedra) e diferenças de altura claramente visíveis, com bordas suaves, para que você possa sair / entrar na água sem pular superfícies irregulares.

SharpShade
fonte
Confira gamedev.stackexchange.com/questions/4628/… Além disso, você está procurando ruído especificamente simplex? Eu tenho uma amostra de ruído me escreveu, mas não é simplex (ou perlin really..it é o chamado 'valor' de ruído, que parece perto o suficiente)
A Comunista Duck
hmm, não há mais informações sobre o ruído simplex ... ou mesmo assim? A amostra seria útil :) talvez você possa me dar? Obrigado :)
SharpShade 8/11
Não quero que isso seja uma resposta, porque não é meu trabalho, mas você pode obter o artigo de Pesquisa sobre Simplex Noise que Ken escreveu em: cs.umbc.edu/~olano/s2002c36/ch02.pdf (este link foi publicado no na parte inferior do artigo da wikipedia, com link para o artigo que você publicou abaixo.) PS: Inclui código para C e Java no final do artigo.
James

Respostas:

1

Meu gerador de ruído em C #, com base nisso :

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ão é comentado, mas as partes principais:

A semente é um valor usado para torná-la aleatória - para que você não gere a mesma coisa sempre. Aqui eu coloquei no NoiseGenerator.

Amplitude, Frequência, Persistência e Oitavas são explicadas no artigo - elas afetam basicamente a aparência do ruído resultante.

NoiseGenerator A função é literalmente um PRNG - digite uma entrada e gera um número aleatório com isso como uma semente.

Noiseé o que você chama para obter um valor de ruído. Eu descobri que os valores estavam em torno de -2,4 a 2,4 (na verdade, cerca de 2.40032483 ou algo assim, eles são fixados) e eu os corrigi para o dobro -1 and 1.

Eu não tive nenhum problema de velocidade com isso. Eu estava renderizando uma grade de 400 x 400 de sprites 1x1 com valores definidos por isso e estava obtendo apenas um pequeno atraso (e isso estava recalculando o ruído a cada quadro).

Para a geração de ilhas, confira esta pergunta - em particular, esse link é quase exatamente o que você deseja, embora no AS3.

O Pato Comunista
fonte
Ehm, desculpe, esqueci de dizer que preciso de um gerador que gere um mapa de altura. Ou como posso usar isso para gerar terreno? No momento, gero um mapa de altura (tentei vários algoritmos ...) e depois calculo os vértices. A grande coisa é, eu preciso de um algoritmo de geração que gera boa aparência ilhas: - / i sabe, estou difícil, mas eu não sei como eu deveria fazer isso ...
SharpShade
@Razer Use as coordenadas do seu mapa de altura - digamos x, y - como entrada da função Noise. Ele atribuirá a cada ponto um valor entre -1 e 1, portanto, talvez seja necessário normalizar ((valor + 1) * 127,5f funciona para obtê-lo entre 0 e 255)
The Communist Duck
Ele funciona, mas não muito agradável ... O que eu quero é algo como isto: hazelmckendrick.com/demos/terrain-generation-tropical-island
SharpShade
11
@Razer Por que não usar essa fonte?
O pato comunista
Porque não há descrição dos algoritmos usados, nenhum código e nada. Sim, eu sei, a fonte está incluída, mas é c ++. Eu não entendo C ++: - /
SharpShade 9/11
1

Ok, obrigado a todos pela ajuda :)

2 dias atrás eu encontrei "Libnoise" e uma boa porta C #. Vou pegar esse aqui, porque tem um renderizador que renderiza mapas de altura mais suaves :)

SharpShade
fonte