Pergunta

Eu estive interessado (como um hobby) na geração de ruído pseudo-aleatório, especificamente os algoritmos Perlin e Simplex. A vantagem para Simplex é a velocidade (especialmente em dimensões superiores), mas Perlin pode estar lado a lado de forma relativamente fácil. Eu queria saber se alguém tinha conhecimento de um algoritmo simplex ladrilhos? Fixo-dimensão é bom, genérico é melhor; pseudocódigo é bom, c / c ++ é melhor.

Foi útil?

Solução 3

Parece esta questão tem sido razoavelmente resolvido aqui , com uma descrição detalhada da idéia por trás da solução de trabalho aqui . Uma resposta fantástica a um problema de longa data!

Outras dicas

Apenas telha seu ruído da mesma maneira que você faria em Perlin fazê-lo apenas após a inclinação. Você pode fazer isso modificando a parte que recebe as permutaions para fazer o mod 256 (ou & 255, o que você está usando) depois (em vez de antes) você adicionar às compensações para os obter os outros cantos do canto base. Este é o pouco modificada do código HLSL:

uint3 iIdx0 = p0SI % 256;
uint3 iIdx1 = (p0SI + pI1) % 256;
uint3 iIdx2 = (p0SI + pI2) % 256;
uint3 iIdx3 = (p0SI + 1.0f) % 256;
uint iGI0 = gPerm[ iIdx0.x + gPerm[ iIdx0.y + gPerm[ iIdx0.z ] ] ] % 12;
uint iGI1 = gPerm[ iIdx1.x + gPerm[ iIdx1.y + gPerm[ iIdx1.z ] ] ] % 12;
uint iGI2 = gPerm[ iIdx2.x + gPerm[ iIdx2.y + gPerm[ iIdx2.z ] ] ] % 12;
uint iGI3 = gPerm[ iIdx3.x + gPerm[ iIdx3.y + gPerm[ iIdx3.z ] ] ] % 12;

p0SI é o ponto de canto 0 e PI2 e PI2 são vetores para um canto e canto 2 calculada da maneira usual. Note-se que em HLSL escalares promover a vectores automaticamente em operatons mistos assim, por exemplo 1.0f é realmente (1.0,1.0,1.0). Eu só percebi isso stuf azulejos fora, mas apprently ele funciona. Se você precisa de sombra um grande planeta ou algo assim, mas só tem precisão simples no seu cartão existem mais alguns passos. Hit me up.

Edit: você sabe depois de pensar nisso mais um pouco Eu não acho que você tem que mudar nada. Eu acho que telhas autmatically em 256 unidades como implementado.

Mesmo se alguns anos passados, esta questão ainda está entre os melhores resultados no Google.

Em simplex ruído, x e y de uma linha reta get (ortonormal) grade enviesada para encontrar o simplex o ponto é em (um triângulo em 2D), assim com técnicas comuns de azulejos (% 255 ou qualquer outro), ele faz azulejo, mas telhas em coordenadas distorcidas, que é telhas "na diagonal", que é bastante inútil.

Uma solução simples que eu encontrei é a "un-inclinação" o resultado, de modo que X original e Y são de primeira distorcida "à esquerda", em seguida, o algoritmo irá distorcer-los "para a direita", ea final resultado será a uma grade não enviesada alinhado-re.

Se, por exemplo, sua implementação simplex é semelhante ao SimplexNoise.java pode encontrar em todos os lugares na rede, ele distorce a grade usando:

var F2 = 0.5*(Math.sqrt(3.0)-1.0);
var s = (xin+yin)*F2; // Hairy factor for 2D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);

Você pode simplesmente "pré-inclinação"-lo na direção oposta no ponto de entrada do método:

var G2 = (3.0-Math.sqrt(3.0))/6.0;
var t = (xin+yin)*G2;
xin-=t;
yin-=t;

Infelizmente, produz um efeito de alguma forma, de aparência estranha (isto é, que parece um pouco distorcida: D)., Que geralmente não é um problema, mas depende do que você precisa que o ruído para

Desde que era um problema para mim, eu tentei aplicar esta "-inversa distorcendo" apenas para um par de oitavas, os que mais peso no resultado final e, em vez de interpolação utilizado para oitavas "leves". Esta solução me deu azulejos satisfatória baseado em Perlin simplex ruído, causa interpolação em todas as oitavas iria produzir muito atenuação sobre as fronteiras de azulejos, e quando mais oitavas são adicionados sem artificial desviando o efeito de aparência strage fica enterrado sob o ruído adicional.

Recentemente necessário ladrilhos ruído simplex e me deparei com esta questão.

Para ladrilhos ruído usando qualquer função de ruído, você pode linearmente interpolate amostras de telha adicional:

Ftileable(x, y) = ( 
       F(x, y) * (w - x) * (h - y) + 
       F(x - w, y) * (x) * (h - y) + 
       F(x - w, y - h) * (x) * (y) + 
       F(x, y - h) * (w - x) * (y)
) / (wh)

onde F () é a sua função de ruído. Note-se que x, y deve ser coordenadas dentro de uma telha indivíduo: x no intervalo [0, W), y no intervalo [0, h). Você poderia usar algo como Tilex = x -. Math.Floor (x / w) * w ou fmod ()

Se o desempenho é crítico ou para dimensões maiores, isto pode não ser o caminho a percorrer, pois requer 2 pesquisas ^ D para dimensão D. É também produzidos valores mais baixos para os centros de telhas para mim.

Retirado de: http: //webstaff.itn .liu.se / ~ stegu / TNM022-2005 / perlinnoiselinks / perlin-noise-math-faq.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top