Estou brincando com o Perlin Noise depois de algum trabalho com a Diamond Square. Segui a implementação de Hugo Elias que, basicamente, faz uma série de funções com x, y como entrada para lançar cada valor de coordenada.
Meu código PHP está aqui :
Eu tenho duas perguntas:
Como uso o algoritmo para gerar um mapa de altura em uma matriz? Eu não o entendi completamente e apenas mudei para o pseudocódigo do PHP, mas fiz a última função (map_perlined) depois de ler em algum lugar que o algoritmo "magicamente" fornece valores de transição para cada ponto x, y dado (aparentemente, sem precisar ler seu valores adjacentes), eu apenas recebo isso ao usar como função aleatóriamt_rand(-100,100)/100;
E isso ao usar o criptográfico: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
(que, BTW, pode ser implementado "como está" no PHP?):
Então, resumindo, três perguntas:
- Meu código está correto?
- A função aleatória pode ser portada para PHP, conforme descrito no código? Não gera erros, mas os resultados não estão lá.
- Como eu realmente uso o algoritmo?
ATUALIZAR
Ok, criou uma porta PHP do código mostrado no artigo de Gustavson e, como outro codificador disse, apenas gera uma oitava. Existe algum outro site / documento / guia útil sobre como usar isso com os conceitos de múltiplas oitavas, amplitude, frequência etc. para controlar a função de ruído? No artigo de Gustavson, apenas mostra os resultados, não a implementação real do algoritmo, talvez esteja faltando alguma coisa?
ATUALIZAÇÃO 2
@NATHAN
Eu fiz algo como:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
for ($o = 0; $o < 8; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += SimplexNoise($i*$frequency, $j * $frequency) * $amplitude;
}
//$value = SimplexNoise($i, $j) + 0.5 * SimplexNoise($i, $j) + 0.25 * SimplexNoise($i, $j);
$this->mapArray[$i][$j] = new Cell($value);
E depois de normalizar os valores para 0..1, recebo um mapa de altura bastante monótono, como:
Como proponho o mapa? Talvez o que eu preciso implementar seja a versão 3D com o terceiro valor, uma altura aleatória? Mas, nesse caso, eu precisaria descobrir os valores dos vizinhos, que terminariam com algo como um algoritmo de diamante quadrado, exatamente o que não quero fazer.
ATUALIZAÇÃO 3
Mais trabalho de Perlin. Ainda não encontrei uma maneira de orientar o ruído para meus resultados. Verifique estas oitavas e o resultado final:
Oitava I a IV
Resumido
Cada oitava é praticamente a mesma. Verifique o código:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
$value = 0;
for ($o = 0; $o < 4; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += improved_noise($i*$frequency, $j*$frequency, 0.5)*$amplitude;
}
$this->map[$i][$j] = new Cell($value);
Os resultados são normalizados. O que você usaria tem uma forte influência no desenvolvimento do ruído? Vejo exemplos em que a alteração da amplitude fornece superfícies suaves ou ásperas, mas mesmo se eu der uma enorme amplitude, vejo pouca diferença.