Skip to content

Construindo um mundo aberto no navegador, parte 27: Uma ilha criada com ruído, um terreno que parece terreno

Por Oleg Sidorkin, CTO e cofundador da Cinevva

Chegou agora? Consulte o guia da série. Ele explica o que é um spike e traz links para todas as partes.

A Parte 26 colocou água no mundo. Esta parte constrói a terra sob ela, em duas etapas que refletem como um lugar real passa a existir. O Spike 54 é o terreno em si: não esculpido à mão, mas criado a partir de ruído e depois desgastado até adquirir a drenagem e o litoral de um lugar pelo qual a água realmente correu. O Spike 55 é a superfície desse terreno: ele resolve o problema que derrota quase todo solo procedural, que é a aparência repetitiva de uma textura em ladrilhos. Juntos, os dois respondem a uma pergunta: um criador consegue obter uma ilha plausível e um solo que realmente pareça solo sem que um artista precise mexer em nenhum dos dois? A resposta é sim, desde que você copie as receitas certas.

Um litoral que o ruído, sozinho, não consegue criar

Abrir o Spike 54 em uma nova aba ↗ · Ver código-fonte

O mapa de altura segue as receitas da Red Blob Games, que consistem em uma pilha de pequenas transformações, cada uma corrigindo uma falha específica do ruído bruto. O movimento browniano fracionário soma várias oitavas de ruído Perlin para que o terreno tenha tanto colinas amplas quanto detalhes finos, mas o FBM simples parece suave e alinhado à grade. Por isso, o ponto de amostragem passa primeiro por uma distorção de domínio: cada coordenada é deslocada por outro campo de ruído, p=p+noise(p)s, o que curva as cristas e produz algo orgânico, em vez de preso aos eixos. Depois, a redistribuição, que eleva a altitude a uma potência ek, empurra os tons médios para baixo, fazendo com que o mundo tenha vales planos e picos agudos, em vez de tudo ficar na mesma inclinação suave. O elemento que transforma o resultado em uma ilha, e não em colinas infinitas, é uma atenuação radial: calcule uma distância euclidiana a partir do centro, d=min(1,nx2+ny2), e misture a elevação em direção a 1d para que o terreno desça até o oceano nas bordas. Um segundo campo de ruído independente se torna um mapa de umidade, que não afeta a forma, mas depois alimenta a etapa de biomas.

Isso produz uma forma, mas ainda é uma forma feita de ruído. Ela não tem rios, vales escavados pela água nem leques de sedimentos, porque nada jamais fluiu por sua superfície. A solução é a erosão hidráulica, adaptada da implementação de Sebastian Lague licenciada sob a MIT. Milhares de gotas d'água surgem em posições aleatórias e descem pelas encostas, cada uma preservando inércia para não fazer curvas bruscas em ângulo reto. Elas recolhem sedimentos quando aceleram e os depositam quando desaceleram ou se acumulam, enquanto um pincel circular pré-calculado espalha cada evento de erosão por um pequeno raio, fazendo com que a escavação seja suave, em vez de um risco de um único pixel. A evaporação encerra a gota ao longo de sua vida útil. Execute gotas suficientes e o terreno desenvolverá aquilo que o ruído não consegue imitar: redes de drenagem convergentes, vales que se alargam rio abaixo e áreas planas onde os sedimentos se assentaram.

Erosão na GPU e rios que sabem onde estão

A erosão na CPU está correta, mas é lenta. Por isso, o spike também a adapta para um shader de computação WebGPU, e a parte interessante é aquilo que as operações atômicas da GPU obrigam você a fazer. As alturas são armazenadas como i32 de ponto fixo, com escala de um milhão, porque a WGSL não oferece soma atômica de floats, e a única forma de permitir que milhares de gotas depositem e removam sedimentos da mesma célula em paralelo, sem condições de corrida, é usar atomicAdd e atomicSub com inteiros. A conversão de ida e volta do ponto fixo significa que, às vezes, uma célula pode ficar ligeiramente negativa sob forte arrasto simultâneo, o que é inofensivo e corrigido na leitura. A versão para CPU pré-calcula uma tabela de pincéis por célula, mas, em uma grade de 10012, essa tabela ocupa cerca de 100 MB. Por isso, a versão para GPU recalcula o pincel de cada gota em tempo real, trocando um pouco de aritmética por uma grande economia de memória. As posições iniciais das gotas continuam vindo da CPU por meio de um gerador Mulberry32, para que as execuções sejam determinísticas.

Mais duas passagens transformam o terreno desgastado em um mapa legível. A drenagem usa o método de acumulação de fluxo D8 da Red Blob: coloque uma unidade de chuva em cada célula, ordene todas as células pela elevação em ordem decrescente e passe a água acumulada de cada célula para seu único vizinho mais baixo. Assim, a água se acumula ao longo dos vales naturais, e qualquer célula cuja acumulação ultrapasse um limite é marcada como rio. O problema é que um mapa de altura erodido tem depressões, rebaixamentos locais sem uma saída descendente, e a água que entra em uma depressão simplesmente para, interrompendo a acumulação. Portanto, antes da drenagem, o preenchimento de depressões de Planchon-Darboux eleva cada uma delas até um pouco acima de seu vizinho mais baixo, minNeighbour+ϵ, iterando por menos de vinte passagens até que toda célula tenha por onde drenar. Por fim, os biomas são atribuídos segundo o método da Red Blob: uma consulta em dois eixos que cruza elevação e umidade, de modo que uma célula alta e seca se transforme em rocha, enquanto uma baixa e úmida se torne pântano, com substituições baseadas na inclinação aplicadas por cima. Faces íngremes são forçadas a virar rocha, independentemente da umidade; a faixa da linha d'água se torna praia; e as maiores elevações recebem neve. O resultado é uma ilha que você entende de imediato, gerada de ponta a ponta a partir de duas sementes de ruído.

O ladrilho que não para de se repetir

Abrir o Spike 55 em uma nova aba ↗ · Ver código-fonte

Um terreno precisa de um material que cubra quilômetros usando uma textura com apenas alguns metros de largura, e, no instante em que você amplia um ladrilho para cobrir o solo, o olhar percebe a repetição. O Spike 55 é um teste A/B de quatro modos de amostragem sobre a mesma geometria e iluminação, de modo que a única variável seja a forma como a textura é lida. A referência é plain: uma amostra nas coordenadas UV escaladas, com uma repetição evidente a cada poucos metros, que existe apenas como aquilo que os outros modos precisam superar. As camadas PBR gratuitas vêm da Poly Haven por meio de sua CDN: textura difusa, o mapa ARM empacotado (oclusão de ambiente, rugosidade e metalicidade) e um mapa normal GL, tudo sob CC0, carregado com anisotropia 8 e mipmaps.

Os outros três são abordagens diferentes para combater a repetição. O modo hex-linear usa a grade triangular de Heitz-Neyret: uma malha triangular inclinada é posicionada sobre a superfície, e cada fragmento fica dentro de um triângulo cujos três vértices recebem amostras com deslocamentos aleatórios, combinadas por pesos baricêntricos para que regiões vizinhas leiam partes diferentes da textura e a repetição em grande escala desapareça. Mas uma mistura linear simples de três amostras calcula a média de suas cores nas bordas dos triângulos, deixando um padrão triangular visível, exatamente o artefato encontrado pelo spike 48. O modo hex-vp é a correção publicada no mesmo artigo de 2018: depois da soma baricêntrica, subtraia a cor média da textura, redimensione pelo inverso da raiz quadrada da soma dos pesos ao quadrado para manter a variância constante e, então, acrescente novamente a média. Isso mantém o contraste estável durante a mistura, fazendo os triângulos desaparecerem. É por isso que o material realiza antecipadamente uma leitura 1 por 1 de cada textura carregada para estimar sua cor média. O quarto modo, iq-untiled, é a técnica 3 de Texture Repetition, de Inigo Quilez: duas amostras deslocadas, misturadas por um padrão de variação de baixa frequência, usando apenas duas amostras em vez de três e sem qualquer estrutura triangular desde o início — a opção barata que ainda apresenta bons resultados.

Sobre qualquer modo pode ser aplicada uma projeção triplanar opcional, que permite ao mesmo material revestir um penhasco sem esticar. Em vez de uma única coordenada UV, o shader amostra três projeções nos eixos do mundo: superfícies voltadas para X leem o plano YZ, Y lê ZX e Z lê XY. Depois, combina tudo usando abs(normalWorld) elevado a uma potência de nitidez entre quatro e oito, para que uma inclinação de 45 graus não sobreponha as três projeções em uma massa indefinida. O teste deixa a compensação clara: a mistura hexagonal com preservação de variância vence em qualidade, enquanto a técnica de duas amostras de Quilez é a opção mais consciente do desempenho. Ambas superam o modo simples por uma margem grande o bastante para que nenhum criador deva publicar um projeto usando o ladrilho simples.

Tecnologias mencionadas neste capítulo

Geração de mapas de altura por composição de receitas. As receitas da Red Blob Games compõem ruído bruto para formar terreno: FBM com distorção de domínio (p=p+noise(p)s) para cristas orgânicas, redistribuição ek para vales planos e picos agudos e uma atenuação radial euclidiana combinada em direção a 1d para rebaixar as bordas até o oceano e formar uma ilha. Um segundo campo de ruído funciona como mapa de umidade para a atribuição de biomas. Consulte geração de paisagens.

Erosão hidráulica na CPU e na GPU. O modelo de gotas de Sebastian Lague (inércia, capacidade de transporte, pincel circular pré-calculado para deposição e evaporação) esculpe uma drenagem real que o ruído não consegue imitar. A versão de computação WebGPU armazena alturas como i32 de ponto fixo em uma escala de um milhão, permitindo que as gotas usem atomicAdd/atomicSub na mesma célula em paralelo, recalcula o pincel de cada gota em tempo real para evitar uma tabela de cerca de 100 MB em 10012 e gera as posições iniciais usando um gerador Mulberry32 determinístico.

Drenagem D8 com preenchimento de depressões. A acumulação de fluxo D8 da Red Blob deposita uma unidade de chuva por célula, ordena as células pela elevação em ordem decrescente e transfere a água para o vizinho mais baixo de cada uma, marcando como rios aquelas que ultrapassam um limite. Primeiro, o preenchimento de depressões de Planchon-Darboux eleva cada rebaixamento local até minNeighbour+ϵ (iterando por menos de vinte passagens), para que a água nunca fique presa e a acumulação permaneça conectada. Uma consulta em dois eixos, cruzando elevação e umidade, atribui os biomas, com substituições baseadas na inclinação que forçam rocha em penhascos, praia na linha d'água e neve nos picos.

Quatro maneiras de eliminar a repetição de texturas. Sobre geometria e iluminação idênticas: plain (uma amostra, com repetição evidente), hex-linear (grade triangular de Heitz-Neyret, cuja mistura linear deixa um padrão de triângulos), hex-vp (a correção com preservação de variância da seção 3.3 do EGSR 2018, que subtrai a média, redimensiona pelo inverso da raiz quadrada dos pesos ao quadrado e acrescenta novamente a média, exigindo uma leitura média de 1×1 por textura) e iq-untiled (a técnica 3 de duas amostras de Inigo Quilez). A projeção triplanar amostra três planos nos eixos do mundo, combinados por abs(normalWorld) elevado a uma potência de 4 a 8, para que os penhascos não apresentem estiramento. A preservação de variância vence em qualidade; as duas amostras vencem em custo. Consulte materiais de terreno.


Parte 27 de 29. Anterior: Parte 26 — Três maneiras de criar água Próxima: Parte 28 — Grama até o horizonte e um terreno que se esconde Guia da série: /pt-BR/blog/2026-02-25-open-world-browser-series-guide