Palavras-chave:
Eu gostaria de gerar ruído Perlin inclinável. Estou trabalhando com as PerlinNoise*()
funções de Paul Bourke , que são assim:
// alpha is the "division factor" (how much to damp subsequent octaves with (usually 2))
// beta is the factor that multiplies your "jump" into the noise (usually 2)
// n is the number of "octaves" to add in
double PerlinNoise2D(double x,double y,double alpha,double beta,int n)
{
int i;
double val,sum = 0;
double p[2],scale = 1;
p[0] = x;
p[1] = y;
for (i=0;i<n;i++) {
val = noise2(p);
sum += val / scale;
scale *= alpha;
p[0] *= beta;
p[1] *= beta;
}
return(sum);
}
Usando código como:
real val = PerlinNoise2D( x,y, 2, 2, 12 ) ; // test
return val*val*skyColor + 2*val*(1-val)*gray + (1-val)*(1-val)*cloudColor ;
Dá céu como
O que não é inclinável.
Os valores de pixel são 0-> 256 (largura e altura), e pixel (0,0) usa (x, y) = (0,0) e pixel (256,256) usa (x, y) = (1,1)
Como posso torná-lo inclinável?
tiles
perlin-noise
bobobobo
fonte
fonte
Respostas:
Existem duas partes para produzir um ruído fBm perfeitamente inclinável como este. Primeiro, é necessário tornar a função de ruído Perlin inclinável. Aqui está um código Python para uma função de ruído Perlin simples que funciona com qualquer período de até 256 (você pode estendê-lo trivialmente o quanto quiser, modificando a primeira seção):
O ruído Perlin é gerado a partir de um somatório de pequenas "excedentes", que são o produto de um gradiente orientado aleatoriamente e uma função polinomial de queda separável. Isso fornece uma região positiva (amarela) e uma região negativa (azul)
As sobras têm uma extensão de 2x2 e estão centradas nos pontos inteiros da rede, de modo que o valor do ruído Perlin em cada ponto no espaço é produzido pela soma das sobras nos cantos da célula que ocupa.
Se você definir as direções do gradiente com um certo período, o ruído será reduzido com o mesmo período. É por isso que o código acima leva o módulo de coordenadas da treliça o período antes de colocá-lo na tabela de permutação.
O outro passo é que, ao somar as oitavas, você desejará escalar o período com a frequência da oitava. Basicamente, você desejará que cada oitava agrupe toda a imagem apenas uma vez, e não várias vezes:
Coloque isso junto e você terá algo como isto:
Como você pode ver, isso realmente combina perfeitamente:
Com alguns pequenos ajustes e mapeamento de cores, aqui está uma imagem de nuvem lado a lado 2x2:
Espero que isto ajude!
fonte
x*2**o
converter para C? é issox*pow(2,o)
oupow(x*2,o)
?x*pow(2, o)
, já que a exponenciação tem maior precedência que a multiplicação.a
valor? e não tenho certeza de como as funções são convertidas em C ... recebo apenas linhas retas na saída.im.putdata(data, 128, 128)
. : (Para aqueles não familiarizados com python ou PIL eles significam escala e offset, não tamanho da imagem.)Aqui está uma maneira bastante inteligente de usar o ruído 4D Perlin.
Basicamente, mapeie a coordenada X do seu pixel para um círculo 2D e a coordenada Y do seu pixel para um segundo círculo 2D e coloque esses dois círculos ortogonais entre si no espaço 4D. A textura resultante é inclinável, não tem distorção óbvia e não se repete da maneira que uma textura espelhada faria.
Copie e cole o código do artigo:
fonte
OK, entendi. A resposta é andar em um toro no ruído 3D, gerando uma textura 2D a partir dele.
Código:
Resultados:
Uma vez:
E lado a lado:
fonte
Uma maneira simples de pensar seria pegar a saída da função de ruído e espelhá-la / transformá-la em uma imagem com o dobro do tamanho. É difícil de explicar, então aqui está uma imagem:
Agora, neste caso, é bastante óbvio o que você fez quando olha para isso. Posso pensar em duas maneiras de (possivelmente :-)) resolver isso:
Você pode pegar essa imagem maior e gerar mais ruído em cima dela, mas (e não tenho certeza se isso é possível) focada no meio (para que as bordas permaneçam as mesmas). Isso poderia adicionar um pouco mais de diferença que faria seu cérebro pensar que não são apenas imagens espelhadas.
(Também não tenho certeza se isso é possível) Você pode tentar mexer nas entradas da função de ruído para gerar a imagem inicial de maneira diferente. Você precisaria fazer isso por tentativa e erro, mas procure por recursos que chamam sua atenção quando o ladrilha / espelha e, em seguida, tenta fazer com que não os gere.
Espero que isto ajude.
fonte
tex2d(abs(abs(uv.x)%2.0-1.0), abs(abs(uv.y)%2.0-1.0))
A primeira versão desta resposta estava realmente errada, eu a atualizei
Um método que usei com sucesso é tornar o domínio de ruído lado a lado. Em outras palavras, torne sua
noise2()
função básica periódica. Senoise2()
for periódico ebeta
inteiro, o ruído resultante terá o mesmo período quenoise2()
.Como podemos fazer
noise2()
periódicos? Na maioria das implementações, essa função usa algum tipo de ruído de rede. Ou seja, obtém números aleatórios em coordenadas inteiras e os interpola. Por exemplo:Esta função pode ser modificada trivialmente para se tornar periódica com o período inteiro. Basta adicionar uma linha:
antes de calcular
v1
ev2
. Dessa forma, os valores nas coordenadas inteiras repetirão todas as unidades do período e a interpolação garantirá que a função resultante seja suave.Observe, no entanto, que isso só funciona quando o Período é maior que 1. Portanto, para realmente usá-lo na criação de texturas perfeitas, você teria que experimentar um quadrado Período x Período, e não 1x1.
fonte
noise2
periódicos (com um período curto, como 1 unidade)? Eu acho que é isso que a pergunta está fazendo. O ruído Perlin padrão é periódico com um período de 256 em cada eixo, mas você deseja um ruído modificado com um período menor.noise2
como sugerido, você vai obter resultados periódicas, quer a própria função é periódica ou não. Porque os argumentos envolvem cada 1 unidade.Outra alternativa é gerar ruído usando bibliotecas libnoise. Você pode gerar ruído em uma quantidade infinita de espaço teórico, sem problemas.
Dê uma olhada no seguinte: http://libnoise.sourceforge.net/tutorials/tutorial3.html#tile
Há também uma porta XNA acima: http://bigblackblock.com/tools/libnoisexna
Se você acabar usando a porta XNA, poderá fazer algo assim:
GeneratePlanar é a função a ser chamada para obter as seções em cada direção que se conectam perfeitamente ao restante das texturas.
Obviamente, esse método é mais caro do que simplesmente ter uma única textura que pode ser usada em várias superfícies. Se você deseja criar algumas texturas inclináveis aleatórias, isso pode ser algo que lhe interessa.
fonte
Embora existam aqui algumas respostas que funcionariam, a maioria delas é complicada, lenta e problemática.
Tudo o que você realmente precisa fazer é usar uma função periódica de geração de ruído. É isso aí!
Uma excelente implementação de domínio público baseada no algoritmo de ruído "avançado" da Perlin pode ser encontrada aqui . A função que você precisa é pnoise2. O código foi escrito por Stefan Gustavson, que fez um comentário aqui sobre exatamente esse problema e como outros adotaram a abordagem errada. Escute Gustavson, ele sabe do que está falando.
Em relação às várias projeções esféricas que alguns aqui sugeriram: bem, elas funcionam essencialmente (lentamente), mas também produzem uma textura 2D que é uma esfera achatada, para que as bordas se condensem mais, provavelmente produzindo um efeito indesejado. Obviamente, se você pretende que sua textura 2D seja projetada em uma esfera, esse é o caminho a seguir, mas não é isso que estava sendo solicitado.
fonte
Aqui está uma maneira muito mais simples de fazer barulho lado a lado:
Você usa um invólucro modular para cada escala do ruído. Eles se ajustam às bordas da área, independentemente da escala de frequência usada. Então você só precisa usar ruído 2D normal, que é muito mais rápido. Aqui está o código WebGL ao vivo que pode ser encontrado em ShaderToy: https://www.shadertoy.com/view/4dlGW2
As três principais funções executam todo o trabalho e o fBM passa um vetor x / y em um intervalo de 0,0 a 1,0.
fonte
Tive alguns resultados não ruins interpolando perto das bordas do bloco, mas isso depende do efeito que você está tentando obter e dos parâmetros de ruído exatos. Funciona muito bem para ruídos um tanto embaçados, não tão bons com ruídos pontiagudos / finos.
fonte
Eu estava checando esse tópico em busca de uma resposta para um problema semelhante, e obtive uma solução limpa e compacta do desenvolvedor desse código python para gerar ruído fractal a partir do ruído perlin / simplex. O código atualizado é fornecido nesta edição (fechada) e pode ser retomado ao definir os gradientes para o lado direito do "gerador" iguais aos do lado esquerdo (e o mesmo para cima e para baixo), como em
Parece uma solução elegante e limpa, evito copiar todo o código aqui (já que não é minha própria solução), mas está disponível no link fornecido acima. Espero que isso possa ser útil para alguém que deseja produzir uma imagem 2D bidimensional como esta que eu precisava, livre de artefatos ou distorções.
fonte