Skip to content

Geração de paisagens com LOD dinâmico e streaming para mundos abertos no navegador

Mapas de altura com ruído Perlin são o ponto de partida padrão para terrenos procedurais. Sobreponha algumas oitavas de fBm, aplique um gradiente de cores e você terá algo que se parece com um terreno. Todo tutorial termina aqui. Mas paisagens reais não se parecem com camadas de ruído. Elas têm vales fluviais escavados pela água, paredões moldados por fraturas de tensão, cavernas e arcos formados pela erosão ao longo de milhões de anos. Elas têm texturas correlacionadas (grama em terreno plano, rocha em encostas íngremes, neve acima da linha das árvores) que surgem dos mesmos processos físicos que moldaram a geometria.

Este guia aborda o que vem depois do ruído. Métodos de geração fundamentados na física, representações volumétricas compatíveis com cavernas e saliências, síntese neural de terreno baseada em difusão e os pipelines de LOD e streaming orientados por GPU necessários para renderizar tudo isso em uma aba do navegador a 60 fps.

Tudo aqui é voltado para nossa restrição específica: um mundo aberto multijogador executado em WebGL 2 / WebGPU, transmitido pela rede e editável por criadores.

Por que mapas de altura não são suficientes

Um mapa de altura armazena um valor de altura por ponto da grade. É uma função 2D: dados (x, z), retorna y. Essa representação é compacta, adequada para GPU e rápida de renderizar. Mas ela tem limitações fundamentais que importam em um mundo voltado para criadores.

Sem cavernas nem saliências. Um mapa de altura não consegue representar um terreno em que um ponto tenha duas alturas diferentes. Cavernas, arcos, saliências rochosas, túneis e ilhas flutuantes são todos impossíveis. Minecraft, No Man's Sky e Deep Rock Galactic precisam de terreno volumétrico por esse motivo.

Sem elementos verticais. Um paredão vertical em um mapa de altura é uma inclinação quase infinita, o que causa estiramento extremo de texturas e artefatos de colisão. Paredões reais têm elementos horizontais (saliências, fendas) que um mapa de altura não consegue representar.

Ruído parece ruído. Mesmo com 8 oitavas de fBm e deformação de domínio, o terreno mantém uma aparência sintética. Falta a estrutura direcional da geologia real: linhas de crista, redes de drenagem, depósitos de sedimentos e dobras tectônicas. Esses padrões surgem de processos físicos, não de funções de ruído.

As edições dos criadores são limitadas. Se os criadores só puderem modificar alturas, não poderão escavar túneis, criar cavernas nem construir espaços subterrâneos. Para um mundo que os criadores possam realmente moldar, a representação do terreno precisa permitir tanto subtração quanto adição.

A solução não é abandonar completamente os mapas de altura. Eles continuam sendo a melhor representação para os 90% do terreno que consistem em uma superfície simples. A solução é uma abordagem híbrida: terreno-base com mapa de altura e sobreposições volumétricas onde geometrias complexas forem necessárias, geração fisicamente correta para formas de relevo realistas e síntese neural para alcançar a diversidade que o ruído não consegue oferecer.

A resposta rápida: o que realmente construiríamos

Antes do aprofundamento, este é o modelo de decisão. O restante do artigo explica cada parte.

Representação do terreno

Use um sistema híbrido de mapa de altura + SDF. O mapa de altura cobre o mundo inteiro (é barato, compacto e comprovado). Volumes SDF existem apenas onde cavernas, saliências ou elementos escavados por criadores os exigem (talvez 5–10% dos chunks). Isso mantém 90% do mundo com o custo de um mapa de altura, permitindo geometria arbitrária onde necessário.

Pipeline de geração

Execute no servidor como um processo encadeado:

  1. Terrain Diffusion (ou MESA para prompts de texto) gera o mapa de altura-base a partir de uma seed. Isso substitui o ruído por formas de relevo geologicamente realistas, treinadas com dados reais de elevação.
  2. Erosão analítica (lei da potência do escoamento) refina o mapa de altura com redes fluviais e linhas de crista em milissegundos.
  3. TerraFusion ou Geodiffussr gera texturas correlacionadas a partir do mapa de altura (ou use regras procedurais de inclinação/altitude como alternativa para WebGL 2).
  4. Simulação de ecossistema produz mapas de densidade da vegetação.
  5. Erosão no estilo Arenite gera volumes SDF para paredões, arcos e cavernas onde o terreno os exigir.
  6. Divida em chunks, compacte e envie para a CDN. Chunk médio: 2–8 KB. Chunk complexo com dados volumétricos: 20–100 KB.

Os criadores interagem com esse pipeline ajustando parâmetros ("mais úmido", "mais montanhoso", "adicionar cavernas"), esboçando suas intenções ou esculpindo diretamente com pincéis e ferramentas SDF.

Estratégia de LOD

Recursos do navegadorLOD do mapa de alturaLOD volumétricoLOD da vegetação
WebGPUQuadtree orientada por GPU (CDLOD) com descarte via compute + desenho indiretoSDF multirresolução com marching cubes via compute + TransvoxelComputeInstanceCulling com desenho indireto
WebGL 2Geometry clipmaps com atualizações dos anéis pela CPUMalhas pré-geradas em 2–3 níveis de LOD, armazenadas em cacheDescarte de frustum pela CPU, InstancedMesh

Ambos os caminhos usam geomorphing no shader de vértice para transições sem pop-in. Ambos usam impostores em billboard para vegetação distante. O caminho WebGPU é mais rápido (orçamento de 3,5 ms para o terreno), mas o caminho WebGL 2 é viável (6,5 ms).

Streaming

Carregamento progressivo: primeiro a geometria do terreno (<100 ms), depois as texturas (<300 ms), em seguida a vegetação (<1 s) e, por fim, os dados volumétricos (❤️ s). Pré-busca com base na velocidade do jogador. Orçamento de memória: 256 MB no total para o terreno.

Edição

Pincéis de mapa de altura para esculpir a superfície (elevar, rebaixar, suavizar, erodir). Primitivas SDF para edição volumétrica (escavar cavernas, adicionar arcos). Ambas são instantâneas localmente, sincronizam com o servidor em 100–300 ms e são transmitidas aos demais jogadores por atualizações delta.

O que construir e em qual ordem

Meses 1–2: terreno com mapa de altura e geometry clipmaps. Apenas WebGL 2. Streaming a partir da CDN. Materiais procedurais baseados em inclinação/altitude. Isso coloca o terreno na tela em qualquer navegador. Use ruído + erosão analítica para a geração (Terrain Diffusion pode esperar).

Meses 3–4: vegetação e atmosfera. Grama e árvores instanciadas pela GPU a partir de mapas de densidade. Céu procedural com ciclo de dia e noite. Névoa atmosférica. Mapas de sombras em cascata. O mundo começa a parecer um lugar de verdade.

Meses 5–6: edição por criadores. Ferramentas de pincel para mapas de altura. Sincronização baseada em deltas para edições multijogador do terreno. Bloqueio espacial para edição simultânea. É quando os criadores começam a moldar o mundo.

Meses 7–9: terreno volumétrico e caminho WebGPU. Sobreposições SDF para cavernas e saliências. Marching cubes em compute no WebGPU. Transvoxel para limites entre LODs. Ferramentas de escultura SDF. Isso libera o conjunto completo de ferramentas de criação.

Meses 10–12: geração neural e refinamento. Terrain Diffusion ou MESA para o mapa de altura-base. TerraFusion/Geodiffussr para texturas. Ruído phasor para microdetalhes. Ladrilhamento hexagonal para evitar repetições. Texturização virtual. Mesclagem laplaciana. O terreno atinge qualidade de produção.

Essa ordem significa que haverá algo jogável após 2 meses, algo bonito após 4, algo editável após 6 e algo de última geração após 12.

O restante deste artigo apresenta a pesquisa por trás de cada decisão.

Representações de terreno além de mapas de altura

Campos de distância com sinal (SDFs)

Um campo de distância com sinal armazena, em cada ponto do espaço 3D, a distância até a superfície mais próxima. Valores positivos ficam do lado de fora, valores negativos ficam do lado de dentro e o cruzamento por zero representa a própria superfície. SDFs representam formas 3D arbitrárias, incluindo cavernas, arcos e geometrias flutuantes.

Para renderizar um SDF como malha, você executa marching cubes (ou uma variante) para extrair o cruzamento por zero como triângulos. A resolução da malha depende da resolução da grade: uma grade SDF de 256x256x256 produz um terreno que cobre aproximadamente um chunk com resolução de 1 metro.

Implementação no navegador: marching cubes em WebGPU é executado inteiramente na GPU por meio de shaders compute. A implementação webgpu-marching-cubes de Will Usher processa uma grade 256^3 em tempo real no navegador, alcançando desempenho de nível nativo. O algoritmo é altamente paralelizável (cada célula é processada de forma independente), o que o torna ideal para compute na GPU.

wgsl
@compute @workgroup_size(4, 4, 4)
fn marchingCubes(@builtin(global_invocation_id) id: vec3<u32>) {
    let sdfValues = sampleSDF(id);
    let caseIndex = classifyCell(sdfValues);
    if (caseIndex == 0u || caseIndex == 255u) { return; }
    let triangles = lookupTriangulation(caseIndex);
    let vertices = interpolateEdges(sdfValues, triangles);
    appendToMeshBuffer(vertices);
}

Custo de armazenamento: um SDF 256^3 com precisão quantizada de 8 bits ocupa 16 MB sem compactação. Mas a maior parte do volume está vazia (longe da superfície). A codificação run-length ou o armazenamento em octree esparsa normalmente reduz isso para 100–500 KB por chunk, um valor comparável ao terreno com mapa de altura.

Edição: terrenos SDF são naturalmente editáveis. Adicionar material é uma operação min() no campo de distância. Remover material (escavar) é uma operação max() com uma forma negada. A mesclagem suave entre formas usa smoothMin(). Essas operações são executadas em um shader compute em taxas interativas.

Contorno dual

Marching cubes posiciona vértices nas arestas da grade, o que produz superfícies suaves, mas perde elementos pontiagudos (bordas de paredões, cantos de rochas). O contorno dual posiciona um vértice por célula na posição que melhor representa a superfície dentro dela, preservando arestas e cantos bem definidos.

O algoritmo precisa tanto dos valores do campo de distância quanto das normais da superfície (o gradiente do SDF) em cada ponto da grade. Ele resolve um pequeno problema de mínimos quadrados por célula para encontrar a posição ideal do vértice. O resultado é uma malha que representa tanto terrenos suaves quanto elementos rochosos bem definidos.

Neural Dual Contouring (Chen et al., 2022, arXiv:2202.01999) substitui o solucionador de mínimos quadrados por uma rede neural que prevê posições ideais dos vértices e cruzamentos de arestas. Ele alcança maior precisão na reconstrução de superfícies e na preservação de elementos, especialmente em formações rochosas naturais complexas.

O algoritmo Transvoxel

O problema mais difícil do terreno volumétrico não é gerar a malha. São as transições de LOD. Quando um chunk de alta resolução fica ao lado de um chunk de baixa resolução, as malhas não se alinham no limite, criando fissuras visíveis.

O algoritmo Transvoxel, criado por Eric Lengyel (transvoxel.org), resolve isso inserindo células especiais de transição ao longo dos limites entre resoluções. Essas células fazem a ponte entre as diferentes resoluções com triângulos adicionais que correspondem exatamente aos dois lados. O algoritmo reduz o complexo problema dos limites a 73 classes de equivalência (em comparação com cerca de 1,2 milhão de casos em uma abordagem de força bruta).

O Transvoxel foi projetado especificamente para aplicações em tempo real nas quais os dados de voxel mudam dinamicamente (edições de criadores, erosão, mineração). Ele não é patenteado e já foi usado em jogos lançados (Space Engineers, Astroneer). Para um mundo no navegador com terreno volumétrico editável, o Transvoxel é a solução de LOD.

Híbrido: mapa de altura-base + sobreposições volumétricas

A abordagem prática para um mundo aberto no navegador é um sistema em camadas:

Camada 1: terreno com mapa de altura cobre o mundo inteiro. Essa é a representação barata e compacta para colinas onduladas, vales e montanhas. Ela é transmitida como pequenos fragmentos de mapa de altura por chunk (2–4 KB cada). A renderização usa geometry clipmaps com custo constante para a GPU.

Camada 2: sobreposições volumétricas existem apenas nos chunks em que geometrias complexas são necessárias. Cavernas, paredões, arcos, túneis escavados por criadores e espaços subterrâneos são armazenados como volumes SDF esparsos. Apenas chunks com dados volumétricos incorrem no custo de armazenamento de SDF e de marching cubes.

Camada 3: modificações dos criadores são armazenadas como edições SDF sobre as camadas-base. Quando um criador escava um túnel, a forma SDF desse túnel é armazenada. O sistema de renderização combina a superfície do mapa de altura com subtrações e adições volumétricas para produzir a malha final.

Esse sistema híbrido custa quase nada em terrenos planos (apenas o mapa de altura) e escala somente onde há complexidade. Em um mundo típico, talvez apenas 5–10% dos chunks precisem de dados volumétricos.

Geração de terreno fisicamente correta

O ruído produz terrenos aleatórios. A física produz terrenos realistas. A diferença é visível: terrenos baseados em ruído não têm estrutura (são irregularmente acidentados em toda parte), enquanto terrenos físicos têm redes fluviais, linhas de crista, leques aluviais e faixas de paredões que surgem da erosão e da tectônica.

Erosão hidráulica: a base

A implementação de erosão hidráulica de Sebastian Lague em ação. Gotas de chuva simuladas descem o terreno, erodem material conforme a velocidade e a inclinação e depositam sedimentos quando a velocidade diminui — transformando ruído plano em vales fluviais, linhas de crista e leques aluviais.

A água flui para baixo, recolhe sedimentos e os deposita quando perde velocidade. Esse único processo, simulado ao longo de milhões de anos virtuais, transforma ruído sem características marcantes em terrenos com formações geológicas reconhecíveis. A abordagem baseada em partículas lança gotas de chuva simuladas sobre o mapa de alturas. Cada gota flui encosta abaixo (seguindo o gradiente), erode material de acordo com a velocidade e a inclinação, transporta sedimentos como carga dissolvida e deposita esses sedimentos quando a velocidade diminui ou a capacidade é excedida. Após 200.000 a 500.000 partículas, o terreno desenvolve:

  • Vales fluviais que seguem o caminho de maior fluxo de água
  • Linhas de crista que separam bacias hidrográficas
  • Leques aluviais onde vales íngremes se abrem em planícies
  • Vales em V em terrenos montanhosos e em U em terrenos glaciais

Implementação na GPU: A simulação de partículas pode ser paralelizada. Cada partícula é independente (a aproximação ignora a interação entre partículas, o que é aceitável para erosão). Um shader de computação WebGPU processa 10.000 partículas por quadro a 60 fps, concluindo 200.000 partículas em cerca de 3 segundos em tempo real.

A implementação de código aberto de Sebastian Lague (GitHub) é o ponto de partida padrão. Ela é executada em uma única thread em C# e processa um mapa de alturas de 1024x1024 em poucos segundos. A versão para GPU é de 50 a 100 vezes mais rápida.

Erosão Térmica

A água não é a única força de erosão. Mudanças de temperatura fazem a rocha rachar e se fragmentar (intemperismo térmico). Quando a inclinação entre dois pontos do terreno excede o ângulo de repouso de um material, o material cai do ponto mais alto para o mais baixo. Isso produz:

  • Encostas de tálus na base de penhascos (acúmulos de rochas que caíram)
  • Linhas de crista suavizadas ao longo do tempo
  • Perfis dependentes do material (rochas duras mantêm encostas íngremes, enquanto solos macios desmoronam em ângulos suaves)

A erosão térmica é mais simples que a erosão hidráulica. É uma operação local: para cada célula, compare a diferença de altura com as células vizinhas. Se a inclinação exceder o limite, mova o material encosta abaixo. Ela é executada como uma única passagem de shader de computação por iteração e converge em 50 a 100 iterações.

Combinar erosão hidráulica e térmica produz terrenos com aparência muito mais natural do que qualquer uma delas isoladamente. A água esculpe vales; a erosão térmica suaviza as cristas entre eles e preenche o fundo dos vales com detritos.

A Lei da Potência do Fluxo: Erosão Analítica

Pesquisas recentes oferecem uma alternativa à simulação baseada em partículas. A lei da potência do fluxo (uma equação geomorfológica que relaciona a taxa de erosão à área de drenagem e à inclinação) pode ser resolvida analiticamente, em vez de simulada de forma iterativa.

Cordonnier et al. (2024, HAL) combinam a lei analítica da potência do fluxo com processos de deslizamento de terra e difusão de encostas. O resultado é uma geração de terreno fundamentada na física, mas executada como uma função matemática, em vez de uma simulação temporal. Você fornece um mapa de alturas baseado em ruído e parâmetros (taxa de precipitação, dureza da rocha, taxa de soerguimento tectônico) e obtém um terreno erodido em milissegundos.

Essa abordagem analítica é ideal para um mundo no navegador porque é executada uma única vez no servidor durante a geração do terreno, e não de forma iterativa. Os parâmetros podem ser ajustados pelos criadores ("deixe esta região mais montanhosa" ajusta a taxa de soerguimento; "deixe-a mais úmida" aumenta a precipitação e aprofunda os vales).

Arenite: Erosão Multifísica (SIGGRAPH 2025)

O Arenite simula tensão, erosão eólica, erosão fluvial e deposição de partículas para gerar arcos, chaminés de fada e morros-testemunho a partir de rochas estratificadas. A geração no servidor produz volumes SDF que alimentam diretamente um pipeline de marching cubes.

O Arenite (Página do projeto) é um simulador de arenito baseado em física que gera arcos, alcovas, chaminés de fada e morros-testemunho a partir de condições iniciais simples. Os usuários pintam mapas de erodibilidade (camadas de rocha macia e rocha dura) e vegetação; depois, o sistema simula:

  • Distribuição de tensão pela coluna rochosa
  • Erosão eólica que remove preferencialmente o material macio exposto
  • Erosão fluvial causada pelo fluxo de água
  • Deposição de partículas que cria novas formações

A implementação na GPU é executada em menos de 5 minutos para formações complexas em uma GPU de desktop. Embora isso seja lento demais para uso em tempo real no navegador, é rápido o suficiente para geração no servidor. Um criador poderia definir uma face de penhasco com camadas de rocha macia e dura e obter uma formação de arco realista em poucos minutos.

A saída é um campo de voxels 3D, que se encaixa diretamente em nosso pipeline de SDF/marching cubes.

Erosão Flexível em Diferentes Representações

Um artigo de 2024 do IRIT-STORM ("Erosão Flexível de Terrenos", Springer) resolve um problema prático: a maioria dos métodos de erosão funciona apenas em campos de altura. Se o seu terreno usa voxels, SDFs ou materiais em camadas, você precisa de código de erosão separado para cada um.

O método de erosão flexível decompõe a erosão em dois processos independentes: alteração do terreno (remoção de material da superfície) e transporte de material (movimentação de sedimentos com partículas regidas por princípios básicos da física). Cada partícula tem tamanho, densidade, restituição e capacidade de sedimentos configuráveis. Um campo vetorial opcional controla o movimento das partículas para obter uma dinâmica de fluidos realista.

Como as partículas interagem com o terreno por meio de uma interface unificada de alteração de material, a mesma simulação funciona em campos de altura, grades de voxels, superfícies implícitas e pilhas de materiais em camadas. Para nosso terreno híbrido (base de mapa de alturas + sobreposições SDF), isso significa que um único sistema de erosão lida com ambas as representações. A simulação de partículas é executada em paralelo na GPU.

Redes Fluviais e Bacias Hidrográficas

A erosão esculpe rios, mas gerar redes fluviais convincentes exige mais do que simplesmente fazer a água correr encosta abaixo. Duas abordagens produzem resultados melhores:

A geração orientada pela drenagem (Amit Patel, Red Blob Games, Projeto) constrói a rede fluvial antes de atribuir a elevação. Comece com um grafo (Voronoi ou malha de triângulos). Classifique as arestas como cristas (sem fluxo), entradas (a água entra) ou saídas (a água sai). Isso cria hierarquias de drenagem realistas, nas quais rios convergem de pequenos afluentes para grandes cursos d'água, seguindo o sistema de classificação de Rosgen para diferentes tipos de rios (canais entrelaçados em terrenos planos, desfiladeiros estreitos em montanhas).

O acúmulo de fluxo monitora a quantidade de água que passa por cada célula do terreno. Distribua chuva simulada uniformemente, faça-a fluir encosta abaixo e conte as passagens por célula. Células com alto acúmulo são canais fluviais. Células com acúmulo moderado são córregos sazonais. O mapa de acúmulo também determina a intensidade da erosão (mais água = mais erosão) e a distribuição da vegetação (as margens dos rios são mais úmidas e sustentam diferentes espécies vegetais).

Para um mundo criado pelo usuário, a rede fluvial é gerada no servidor durante a criação do terreno e armazenada como um mapa 2D de direção do fluxo, além de um mapa de acúmulo de água por chunk. O cliente no navegador usa esses mapas para renderizar superfícies de água (planos horizontais na altura correta dentro dos canais fluviais) e determinar a distribuição da vegetação (mais exuberante perto da água).

Geração de Costas e Linhas Litorâneas

As linhas costeiras são onde o terreno encontra a água e possuem características distintas que a erosão convencional não produz: falésias marinhas, depósitos de praia, planícies de maré, farilhões e plataformas de abrasão marinha.

O NEWTS1.0 (2024, MIT) modela a evolução de costas rochosas usando dois mecanismos de erosão: recuo uniforme (taxa de erosão constante) e erosão causada por ondas (taxa de erosão como função da distância de pista e do ângulo de incidência das ondas). O modelo percorre milhares de anos simulados e produz promontórios, baías, farilhões e arcos que correspondem à geomorfologia costeira real.

Para um mundo no navegador, os elementos costeiros seriam pré-gerados durante a criação do mundo. Os parâmetros (direção predominante das ondas, variação da dureza das rochas ao longo da costa) permitem que os criadores controlem as características do litoral. Uma configuração de "fiorde norueguês" produz enseadas com laterais íngremes. Uma configuração de "atol tropical" produz costas arenosas baixas com lagoas.

Geração de Cavernas e Ambientes Subterrâneos

Cavernas exigem terreno totalmente volumétrico (SDFs ou voxels), pois mapas de alturas não conseguem representar espaços fechados. As abordagens de geração incluem:

O limiar de ruído 3D é o método mais simples. Amostre ruído Perlin ou simplex 3D em cada voxel. Valores abaixo de um limite são sólidos; valores acima são vazios. Ajuste o limite e os parâmetros de ruído para controlar o diâmetro dos túneis, a conectividade e o tamanho das câmaras. Isso produz sistemas de cavernas orgânicos e sinuosos, semelhantes aos do Minecraft.

O PLUME (Procedural Layer Underground Modeling Engine) (2024, arXiv:2508.20926) gera ambientes realistas de cavernas e tubos de lava usando regras procedurais em camadas. Criado originalmente para pesquisas de exploração espacial (simulando tubos de lava marcianos), ele produz estruturas subterrâneas geologicamente plausíveis com estalactites, colunas e sistemas de câmaras.

Os túneis de sistema-L com escavação por metaballs usam uma gramática de sistema-L para criar caminhos de túneis ramificados pelo terreno e, em seguida, escavam a geometria real dos túneis usando superfícies implícitas de metaballs. As metaballs produzem paredes de cavernas suaves e arredondadas. Múltiplas passagens com parâmetros diferentes criam passagens principais, câmaras laterais e túneis de conexão estreitos.

Para um mundo criado pelo usuário, a geração de cavernas se integra ao sistema de sobreposição SDF. O terreno-base é um mapa de alturas (sem cavernas). Quando um chunk precisa de cavernas (seja por geração procedural ou pelo projeto do criador), é gerado um volume SDF que subtrai a geometria das cavernas do terreno-base. O pipeline de marching cubes renderiza a superfície combinada.

Vegetação como Processo Físico

A vegetação em jogos geralmente é posicionada proceduralmente com regras como "grama abaixo de 2.000 m, árvores abaixo de 1.500 m, neve acima de 3.000 m". Isso é rápido, mas produz uma distribuição uniforme e pouco realista.

A simulação de vegetação fundamentada na física modela cada planta competindo por recursos (luz, água e nutrientes do solo). A simulação:

  1. Espalha sementes pelo terreno
  2. Faz cada planta crescer de acordo com os recursos disponíveis (a água vem da simulação de erosão hidráulica, a luz solar depende da inclinação e da orientação da encosta, e a profundidade do solo depende do histórico de erosão)
  3. Faz as plantas competirem: árvores bloqueiam a luz da grama, e copas densas impedem o surgimento de novas mudas
  4. Ao longo do tempo simulado, os biomas surgem naturalmente: florestas em vales com água, vegetação esparsa em cristas expostas ao vento e áreas úmidas onde a água se acumula

A simulação de ecossistemas de Deussen et al. (Artigo) gera distribuições florestais que correspondem a padrões ecológicos do mundo real. A simulação é executada em uma grade 2D (uma célula por chunk de terreno) e produz mapas de densidade e atribuições de espécies que o sistema de renderização usa para posicionar vegetação instanciada na GPU.

Para um mundo no navegador, a simulação de vegetação é executada uma única vez durante a geração do mundo (no servidor). A saída é um conjunto de mapas de densidade por chunk: densidade de árvores, densidade de grama, densidade de flores e densidade de detritos rochosos. O cliente no navegador usa esses mapas com instanciamento na GPU para espalhar vegetação durante a execução.

Síntese de Terreno Baseada em Difusão

É nessa direção que a área avança mais rapidamente. Modelos de difusão (a mesma tecnologia por trás do Stable Diffusion para imagens) estão sendo aplicados à geração de terrenos, e os resultados são substancialmente mais realistas do que os métodos baseados em ruído.

Terrain Diffusion: Um Sucessor do Ruído Perlin

Terrain Diffusion sendo executado dentro do Minecraft, transmitindo terrenos infinitos e consistentes com a semente em tempo real. Treinado com dados de elevação do mundo real, ele produz paisagens com estruturas geológicas que funções de ruído não conseguem igualar.

Terrain Diffusion (Goslin, 2025, arXiv:2512.08309, Página do projeto) é o avanço mais significativo na geração procedural de terrenos desde o ruído Perlin, em 1985. Desde então, o trabalho foi aceito na SIGGRAPH 2026, e o título canônico no arXiv agora é "InfiniteDiffusion: Conectando Fidelidade Aprendida e Utilidade Procedural para Geração de Terrenos de Mundo Aberto". O algoritmo InfiniteDiffusion e o framework Terrain Diffusion são as duas metades do mesmo artigo.

A principal inovação é o InfiniteDiffusion, um algoritmo que reformula a amostragem por difusão para domínios ilimitados. Modelos de difusão tradicionais geram saídas de tamanho fixo (por exemplo, um mapa de alturas de 512x512). O InfiniteDiffusion gera terrenos de extensão infinita com:

  • Consistência da semente: A mesma semente sempre produz o mesmo terreno, como no ruído Perlin
  • Acesso aleatório em tempo constante: Você pode consultar a altura em qualquer ponto sem precisar gerar primeiro as regiões vizinhas
  • Ausência de artefatos nas bordas: Geração infinita sem emendas visíveis nem repetição

O sistema usa uma pilha hierárquica de modelos de difusão. O nível superior captura características em escala planetária (continentes, cadeias de montanhas). Cada nível subsequente acrescenta detalhes mais finos (picos individuais, vales e rugosidade em pequena escala). Uma codificação laplaciana compacta estabiliza as saídas em toda a enorme faixa dinâmica, do nível do mar aos picos do Himalaia.

Desempenho: A geração acompanha o ritmo da exploração em tempo real. O artigo relata que, mesmo no extremo teórico da velocidade orbital (cerca de 7.700 m/s), a síntese de terreno é executada 9 vezes mais rápido que o deslocamento em uma GPU de uso doméstico. O projeto inclui uma integração com o Minecraft que demonstra a síntese de terreno em tempo real. Por que isso é importante para nós: o Terrain Diffusion produz paisagens treinadas com dados de elevação do mundo real (a topografia real da Terra). A saída apresenta redes fluviais, cadeias de montanhas, formações costeiras e estruturas de planaltos que emergem dos dados de treinamento, e não de parâmetros de ruído ajustados manualmente. Um criador poderia dizer "gere um terreno semelhante às Terras Altas da Escócia", e o modelo de difusão produziria algo com as características geológicas corretas.

O modelo é executado no servidor durante a geração do mundo. A saída é um mapa de altura padrão, transmitido ao navegador como qualquer outro dado de terreno. O método de geração é invisível para o cliente.

TerraFusion: geometria e textura em conjunto

O TerraFusion gera em conjunto mapas de altura de terreno e texturas de superfície correspondentes a partir de esboços usando difusão latente
O TerraFusion gera o mapa de altura e a textura em conjunto a partir de um esboço desenhado à mão. A correlação entre geometria e material já vem incorporada — leitos de rios saem arenosos, faces de penhascos rochosas e terrenos planos gramados — sem qualquer pintura manual de splats.

O TerraFusion (2025, arXiv:2505.04050) vai além ao gerar conjuntamente mapas de altura e texturas de terreno. O principal insight: a geometria do terreno e a aparência da superfície estão correlacionadas (leitos de rios são arenosos, faces de penhascos são rochosas, áreas planas são gramadas). Gerá-las separadamente produz incompatibilidades.

O TerraFusion usa um modelo de difusão latente com VAEs separados para mapas de altura e texturas, treinado para modelar sua distribuição conjunta. O sistema oferece:

  • Geração incondicional: terreno plausível aleatório com texturas correspondentes
  • Geração condicionada por esboço: um criador desenha um mapa aproximado (vales aqui, cristas ali, penhascos ao longo desta borda), e o modelo gera geometria e texturas detalhadas que correspondem ao esboço

Para o mundo de um criador, isso é poderoso. O criador esboça o layout geral de seu lote, e o sistema preenche o espaço com um terreno geologicamente plausível e materiais de superfície apropriados. Sem pintura de mapas de altura, sem aplicação de splats de textura, sem atribuição manual de materiais.

MESA: de texto para terreno

O MESA gera imagens de terreno no estilo de imagens de satélite e mapas de elevação a partir de prompts de texto, treinado com dados globais do Copernicus
O MESA produz pares de imagens de satélite e DEMs a partir de prompts de texto. Treinado com o conjunto de dados global do Copernicus, ele compreende terrenos reais em todas as escalas e zonas climáticas — fiordes, estepes, terras agrícolas e cristas alpinas.

O MESA (2025, arXiv:2504.07210, Workshop da CVPR 2025) gera terrenos a partir de descrições textuais. Ele é treinado com dados globais de sensoriamento remoto do programa Copernicus, portanto foi exposto a todos os tipos de paisagem terrestre.

Um prompt como "um fiorde com paredes íngremes de granito que se abre para um litoral rochoso" produz um mapa de altura com a estrutura geológica apropriada. "Terras agrícolas onduladas, com colinas suaves e um amplo vale fluvial" produz algo completamente diferente.

O MESA apresenta o conjunto de dados de extensão Major TOM Core-DEM, que combina imagens de satélite com modelos digitais de elevação de todo o mundo. Esses dados de treinamento fornecem ao modelo uma compreensão de como são os terrenos reais em todas as escalas e zonas climáticas.

Geodiffussr: texturização de terreno orientada por texto

O Geodiffussr gera texturas de terreno a partir de descrições textuais respeitando os dados de elevação — neve nos picos, areia no litoral e floresta nas encostas
O Geodiffussr recebe um mapa de altura e um prompt de texto e gera texturas de superfície que respeitam a elevação. A neve aparece apenas acima de altitudes plausíveis; a vegetação rareia com a altitude; a água ocupa depressões. A geometria permanece inalterada.

O Geodiffussr (2025, arXiv:2511.23029) recebe um mapa de altura existente e gera texturas orientadas por descrições textuais, respeitando os dados de elevação. "Floresta de outono" produz folhagem laranja e dourada em inclinações moderadas, com rocha exposta em faces íngremes. "Litoral tropical" produz palmeiras em terrenos baixos e areia de coral ao nível do mar.

O sistema usa agregação de conteúdo multiescala para garantir que as atribuições de textura respeitem a elevação: a neve aparece apenas acima de uma altitude fisicamente plausível, corpos d'água ocupam depressões e a vegetação rareia com a altitude.

Para o mundo de um criador, isso significa que as texturas do terreno podem ser regeneradas a partir de um prompt de texto sem alterar a geometria. O criador esculpe o terreno desejado, depois descreve a atmosfera ("ermo vulcânico sombrio" ou "floresta temperada exuberante"), e o sistema gera materiais de superfície apropriados.

LOD dinâmico para terrenos no navegador

Renderizar um terreno grande em resolução máxima por toda parte é impossível em um navegador. Um mundo de 4 km x 4 km com resolução de 1 metro tem 16 milhões de vértices apenas no terreno. O LOD dinâmico reduz isso a uma contagem de vértices constante e administrável, independentemente do tamanho do mundo.

Clipmaps de geometria

A apresentação original dos clipmaps de geometria na SIGGRAPH 2004. Anéis concêntricos de terreno com resoluções reduzidas pela metade mantêm a contagem de vértices constante, independentemente do tamanho do mundo — e ainda são a base da maioria dos sistemas de LOD de terreno para navegador atuais.

Os clipmaps de geometria (Losasso e Hoppe, SIGGRAPH 2004, Artigo) continuam sendo o padrão de referência para LOD de terrenos baseados em mapas de altura. A ideia: renderizar o terreno como um conjunto de anéis quadrados concêntricos centrados na câmera. Cada anel cobre o dobro da área do anterior, mas com metade da resolução.

Perto da câmera (anel mais interno): resolução máxima, com espaçamento de 1 metro na grade. Um anel além: espaçamento de 2 metros, cobrindo 4 vezes a área. Anel seguinte: espaçamento de 4 metros, cobrindo 16 vezes a área. E assim por diante, ao longo de 6 a 8 níveis, até que o anel mais externo cubra toda a distância visível.

A contagem total de vértices é constante: aproximadamente N^2 * níveis, em que N é a largura do anel em vértices. Com N=256 e 8 níveis, isso representa cerca de 500 mil vértices no total. A renderização é a mesma, seja o mundo de 1 km ou de 100 km de largura.

Implementação no navegador: clipmaps de geometria funcionam no WebGL 2 porque exigem apenas atualizações padrão de buffers de vértices (sem shaders de computação). À medida que a câmera se move, a CPU atualiza os dados do mapa de altura de cada anel, amostrando o terreno na resolução apropriada. O shader de vértices lê os valores de altura de uma textura e desloca a grade plana.

Morphing: a transição entre níveis de LOD produz "saltos" visíveis se for tratada de maneira ingênua. O geomorphing (detalhado em uma seção própria abaixo) interpola as posições dos vértices entre os níveis ao longo de uma zona de transição no shader de vértices, produzindo transições suaves e sem saltos, sem o custo de chamadas de desenho adicionais.

CDLOD: clipmaps adaptativos com quadtree

O CDLOD (Strugar, 2014, Artigo) aprimora os clipmaps de geometria usando uma quadtree em vez de anéis concêntricos fixos. A quadtree se adapta ao terreno: áreas planas usam nós de baixa resolução, enquanto áreas com muitos detalhes (penhascos, cristas) recebem subdivisões mais finas.

Isso é importante para o mundo de um criador porque diferentes chunks têm diferentes níveis de complexidade. Um prado plano precisa de resolução mínima. Uma região montanhosa com penhascos e cavernas precisa do máximo de detalhes. O CDLOD aloca resolução onde ela é importante.

A travessia da quadtree pela CPU é leve (algumas centenas de nós) e determina quais patches de terreno devem ser desenhados e em qual resolução. A GPU renderiza cada patch como uma grade instanciada, com uniforms de LOD específicos para cada patch.

Árvores binárias concorrentes: tesselação em escala planetária

Tesselação adaptativa com CBT para terrenos em escala planetária: os triângulos são subdivididos perto da câmera e mesclados à distância, inteiramente na GPU. Menos de 0,2 ms em hardware de console.

Árvores Binárias Concorrentes (CBT) são uma estrutura de dados adequada à GPU para tesselação adaptativa de terrenos, apresentada por Benyoub e Dupuy (Intel, HPG 2024, Artigo, GitHub).

A ideia central: representar o terreno como uma árvore binária em que cada nó é um triângulo. A subdivisão adaptativa divide os triângulos próximos à câmera e mescla os triângulos distantes. A árvore binária fica inteiramente na memória da GPU como um array unidimensional (um heap binário), e as operações de subdivisão e mesclagem são executadas como shaders de computação.

O artigo de 2024 estende as CBTs de domínios quadrados de mapas de altura para malhas poligonais arbitrárias. Isso significa que é possível criar a tesselação de uma esfera (para renderização planetária) ou de uma malha-base arbitrária (para um mundo de jogo com limites não retangulares). A principal melhoria: usar a CBT como gerenciador de pool de memória, em vez de codificação implícita, permite níveis de subdivisão muito mais altos.

Desempenho: tesselação de terreno em escala planetária em menos de 0,2 ms em hardware equivalente ao de consoles. O algoritmo escala linearmente com a quantidade de processadores. Para WebGPU, isso oferece um caminho para renderizar terrenos em escala planetária no navegador, embora a implementação seja complexa.

LOD controlado pela GPU com WebGPU

O WebGPU permite um pipeline de terreno totalmente controlado pela GPU, eliminando a participação da CPU nas decisões de LOD:

  1. Passe de computação 1: descarte por frustum e oclusão. Um shader de computação testa a caixa delimitadora de cada patch de terreno em relação ao frustum de visualização e a um buffer de oclusão (o buffer de profundidade do quadro anterior, reduzido). Patches invisíveis são totalmente descartados.

  2. Passe de computação 2: seleção de LOD. Para os patches visíveis, calcula o tamanho no espaço da tela e seleciona o nível de LOD apropriado. Grava o nível de LOD e o ID do patch em um buffer de desenho indireto.

  3. Passe de computação 3: geração de malha (para terrenos volumétricos). Para chunks com dados SDF, executa marching cubes para gerar a malha na resolução de LOD selecionada.

  4. Desenho indireto. Uma única chamada drawIndexedIndirect() renderiza todos os patches de terreno. A GPU decide tudo: o que desenhar, em qual resolução e em qual ordem.

Esse pipeline tem custo constante de CPU (despachar shaders de computação e a chamada de desenho indireto), independentemente do tamanho ou da complexidade do mundo. A GPU cuida de todas as decisões por patch.

wgsl
@compute @workgroup_size(64)
fn lodSelection(@builtin(global_invocation_id) id: vec3<u32>) {
    let patchIdx = id.x;
    let bounds = patchBounds[patchIdx];

    if (!frustumTest(bounds, viewProjection)) { return; }
    if (occlusionTest(bounds, depthPyramid) == OCCLUDED) { return; }

    let screenSize = projectedSize(bounds, viewProjection, screenDimensions);
    let lod = clamp(u32(log2(maxScreenSize / screenSize)), 0u, MAX_LOD);

    let drawIdx = atomicAdd(&drawCount, 1u);
    drawArgs[drawIdx] = DrawArgs(patchIdx, lod, indexCount[lod], indexOffset[lod]);
}

Geomorphing: transições de LOD sem saltos

O maior artefato visual no LOD de terreno são os saltos: os vértices mudam repentinamente de posição quando um patch troca de nível de LOD. O geomorphing elimina isso interpolando suavemente as posições dos vértices entre os níveis de LOD ao longo de uma zona de transição.

A implementação fica inteiramente no shader de vértices. Cada vértice armazena tanto sua posição no LOD atual quanto sua posição no próximo LOD de menor resolução. Quando a distância da câmera cruza o limite de transição, um fator de morphing interpola as duas:

glsl
float morphFactor = smoothstep(lodNear, lodFar, distanceToCamera);
float morphedHeight = mix(fineLodHeight, coarseLodHeight, morphFactor);
gl_Position = viewProjection * vec4(worldPos.x, morphedHeight, worldPos.z, 1.0);

O artigo de Hoppe sobre clipmaps de geometria (GPU Gems 2, Capítulo 2) descreve a implementação completa para anéis de clipmap. A zona de morphing corresponde aos 20% externos de cada anel. Nessa zona, os vértices convergem suavemente para a resolução do anel seguinte. O efeito visual: a geometria do terreno "derrete" entre os níveis de detalhe em vez de mudar abruptamente. Em velocidades típicas de câmera, a transição é invisível.

A mesclagem no espaço da imagem (Scherzer et al., Artigo) é uma alternativa que mescla imagens renderizadas de dois níveis de LOD no espaço da tela. Isso lida com diferenças de LOD mais extremas (por exemplo, transições de malha para billboard), mas custa um passe de renderização adicional na zona de transição.

Descarte de vegetação controlado pela GPU

A vegetação (árvores, grama, rochas) costuma ser a maior fonte de chamadas de desenho em um mundo aberto. Uma abordagem ingênua desenha todas as instâncias de vegetação em todos os quadros. O descarte controlado pela GPU, agora disponível no Three.js por meio do WebGPU, elimina instâncias invisíveis antes que elas cheguem ao rasterizador.

O ComputeInstanceCulling do Three.js (Documentação) oferece descarte por frustum e LOD para malhas instanciadas, com ganhos de desempenho de 10 a 100 vezes para grandes quantidades de instâncias. O pipeline:

  1. Um shader de computação lê todas as esferas delimitadoras das instâncias
  2. Testa cada uma em relação ao frustum da câmera (teste de 6 planos)
  3. Aplica LOD baseado em distância: instâncias além de um limite mudam para um nível de detalhe menor ou são totalmente descartadas
  4. As instâncias restantes são compactadas em um buffer e desenhadas via drawIndirect A CPU não realiza nenhum trabalho por instância. Após a configuração inicial, o custo é de um despacho de computação mais uma chamada de desenho indireta por tipo de vegetação, independentemente da quantidade de instâncias.

Para vegetação mais densa, o IndirectBatchedMesh do Three.js (Documentação) agrupa vários tipos de geometria (árvores, arbustos, rochas) em um único buffer e os desenha com múltiplas chamadas indiretas. Uma única chamada de desenho para toda a vegetação de um chunk.

Combinado à dispersão baseada em mapas de densidade do nosso sistema de vegetação, isso significa: o mapa de densidade gera 50.000 posições de folhas de grama em um shader de computação, a etapa de culling elimina os 70% que estão fora da tela ou distantes demais, e uma única chamada de desenho indireta renderiza as 15.000 folhas restantes. Custo total de CPU: insignificante.

LOD para terreno volumétrico

Terrenos volumétricos (SDF + marching cubes) precisam de um sistema de LOD próprio porque a malha é gerada, não criada previamente. A abordagem:

Armazenamento de SDF em múltiplas resoluções. Armazene o SDF em várias resoluções em uma hierarquia semelhante a mipmaps. O nível 0 usa resolução máxima (voxels de 1 metro). O nível 1 usa voxels de 2 metros (8 vezes menos dados). O nível 2 usa voxels de 4 metros. Em cada nível, o SDF tem sua resolução reduzida usando a menor distância absoluta.

Marching cubes selecionado por LOD. Execute marching cubes no nível de SDF correspondente ao LOD desejado. Chunks vistos de perto usam o nível 0. Chunks distantes usam o nível 2 ou 3. O algoritmo Transvoxel trata a fronteira entre níveis diferentes.

Cache. As malhas geradas permanecem em cache até que o SDF seja alterado (edição do criador) ou o nível de LOD mude (movimento significativo da câmera). Para terrenos estáticos, a malha é gerada uma vez e reutilizada.

Arquitetura de streaming para terrenos

Formato dos dados de chunks

Cada chunk de terreno (64x64 metros) é transmitido como um pacote binário compacto:

ChunkPacket {
  header: {
    chunkX: i16, chunkZ: i16,
    version: u32,
    flags: u8  // hasHeightmap | hasVolumetric | hasVegetation
  }
  heightmap: {
    resolution: u8,      // 65x65 for full, 33x33 for half, 17x17 for quarter
    quantizedHeights: u16[resolution * resolution],  // delta-encoded, zlib compressed
    splatMap: u8[4 * resolution * resolution]         // RGBA blend weights, LZ4 compressed
  }
  volumetric?: {         // only present if flags.hasVolumetric
    sdfResolution: u8,   // typically 32 or 64
    sparseOctree: bytes  // run-length encoded sparse SDF
  }
  vegetation?: {         // only present if flags.hasVegetation
    treeDensityMap: u8[16 * 16],    // 4m resolution density grid
    grassDensityMap: u8[32 * 32],   // 2m resolution density grid
    rockDensityMap: u8[16 * 16]
  }
  creatorObjects: {
    count: u16,
    objects: PlacedObject[]   // assetId + transform + properties, ~40 bytes each
  }
}

Tamanhos típicos:

  • Chunk somente com mapa de altura (terreno plano): 2–4 KB compactado
  • Mapa de altura + vegetação: 4–8 KB
  • Mapa de altura + dados volumétricos + vegetação (chunk complexo): 20–100 KB
  • Vizinhança 5x5 com nível máximo de detalhes: 50–500 KB no total

Carregamento progressivo de chunks

Os chunks são carregados em ordem de prioridade com base na distância, na direção do movimento e no tipo de dados:

Prioridade 1 (imediata, <100ms): Geometria do mapa de altura para os chunks nos quais o jogador está prestes a entrar. A superfície do terreno aparece primeiro. Mesmo na resolução mais baixa (17x17 por chunk), o chão já está presente.

Prioridade 2 (rápida, <300ms): Splat maps e texturas do terreno. O chão ganha cor.

Prioridade 3 (streaming, <1s): Atualização para o mapa de altura em resolução máxima. Mapas de densidade de vegetação. O instanciamento por GPU gera árvores e grama.

Prioridade 4 (segundo plano, <3s): Dados SDF volumétricos para chunks com cavernas ou saliências. Marching cubes gera a malha em um Web Worker e transfere o buffer para a thread principal.

Prioridade 5 (sob demanda, <10s): Objetos posicionados por criadores. Texturas de alta resolução para estruturas. Objetos de detalhe, como flores, pedras pequenas e detritos.

Pré-carregamento preditivo

Não espere o jogador entrar em um chunk para começar a carregá-lo. Preveja para onde ele está indo com base na velocidade e carregue antecipadamente:

  • Caminhada (5 km/h): Pré-carregue 2 chunks à frente (128 m). Com a latência típica de banda larga, isso proporciona uma antecipação de 200–400 ms.
  • Corrida/montaria (15 km/h): Pré-carregue 4 chunks à frente. O anel de carregamento se desloca de acordo com a direção da velocidade.
  • Voo/viagem rápida: Pause a renderização durante a transição. Transmita os chunks de destino com prioridade máxima. Retome a renderização quando houver dados suficientes para o primeiro quadro.

O sistema de pré-carregamento monitora quais chunks estão no cache, quais estão em trânsito (solicitados, mas ainda não recebidos) e quais são necessários. Uma fila de prioridade ordena as solicitações pendentes por urgência. Cancele as solicitações de chunks dos quais o jogador se afastou.

Orçamento de memória e descarte

Uma aba do navegador recebe de 2 a 4 GB em computadores. O sistema de terreno precisa operar usando apenas uma fração disso (o restante fica para renderização, física, rede e heap do JavaScript).

Orçamento-alvo: 256 MB para todos os dados de terreno.

Com nossos tamanhos típicos de chunks:

  • Chunks em cache com nível máximo de detalhes: cerca de 100 (vizinhança 10x10), com 5–100 KB cada = 5–10 MB de dados brutos
  • Geometria do terreno na GPU: cerca de 50 MB (buffers de vértices e índices para o terreno visível)
  • Texturas do terreno: cerca de 100 MB (compactadas em KTX2 e agrupadas em atlas)
  • Buffers de instâncias de vegetação: cerca de 50 MB (posições, rotações e escalas para instanciamento por GPU)
  • Volumes SDF e malhas de marching cubes em cache: cerca de 50 MB

Os chunks fora do alcance visível são removidos primeiro da memória da GPU (texturas e buffers de vértices) e depois do cache da CPU. Os dados brutos do mapa de altura são os últimos a serem removidos porque são os mais baratos de manter e os mais importantes quando o jogador se vira.

Transições entre biomas e técnicas antirrepetição

Limites suaves entre biomas

Paisagens reais não têm limites rígidos entre biomas. Uma floresta não termina em uma linha para imediatamente virar deserto. Há um gradiente: a floresta densa passa a ter árvores dispersas, depois vira vegetação arbustiva e, por fim, vegetação desértica esparsa. Acertar esse efeito faz o mundo parecer contínuo, em vez de dividido em blocos.

O AutoBiomes (Kötter et al., Artigo) combina geração procedural de terrenos com uma simulação climática simplificada. Temperatura, umidade e elevação determinam o tipo de bioma em cada ponto. Entre os biomas, os pesos dos materiais e a densidade da vegetação são interpolados ao longo de uma zona de transição (normalmente com 50–100 metros de largura). A largura da transição varia de acordo com o par de biomas: entre floresta e campo, ela é ampla e gradual; entre penhasco e água, é estreita e abrupta.

Em um mundo de criadores, a atribuição de biomas é executada em uma grade de baixa resolução (uma amostra de bioma para cada área de 16x16 metros). O shader do terreno lê os valores do bioma para o fragmento atual e seus vizinhos, interpola os pesos dos materiais na zona de transição e mistura as texturas de acordo. A dispersão da vegetação usa os mesmos valores de densidade interpolados, de modo que a densidade das árvores diminui gradualmente na borda da floresta.

Controle do criador: permita que os criadores pintem substituições de bioma em seus lotes. O sistema gera biomas padrão a partir das propriedades do terreno, mas os criadores podem substituí-los. Ao pintar um “pântano” em uma área baixa, o material muda para água turva, musgo e árvores mortas. O mapa de pintura de biomas é uma grade de 16x16 IDs de bioma por chunk (256 bytes) que substitui a atribuição procedural.

Ladrilhamento hexagonal: eliminando a repetição de texturas

O artefato visual mais comum na renderização de terrenos é a repetição de texturas. Uma textura de grama de 1 metro repetida por um campo de 100 metros produz padrões de grade visíveis. Duas técnicas corrigem isso:

O ladrilhamento hexagonal (Mikkelsen, Demonstração) substitui a grade quadrada de ladrilhos por uma hexagonal. Cada ladrilho hexagonal amostra a textura com deslocamento e rotação aleatórios. Os limites hexagonais são mesclados para ocultar as emendas. O resultado é uma superfície que parece uniformemente aleatória, em vez de ladrilhada. Custo: cerca de 3 amostras de textura adicionais por fragmento. A técnica é amplamente usada em jogos comerciais e funciona em qualquer fragment shader.

A filtragem estocástica de texturas (Pharr et al., NVIDIA, 2024, Artigo) aplica a filtragem depois do sombreamento, e não antes, usando amostragem estocástica. O erro da amostragem estocástica é mínimo e bem tratado pela redução de ruído espaço-temporal. Isso produz resultados filtrados mais precisos e funciona com texturas compactadas ou esparsas. Para terrenos, elimina tanto os artefatos de repetição quanto os artefatos de filtragem que o ladrilhamento hexagonal às vezes pode introduzir nas transições.

Para um mundo no navegador, o ladrilhamento hexagonal é a opção prática (funciona em qualquer shader). A filtragem estocástica exige mais infraestrutura, mas produz resultados melhores quando há redução temporal de ruído disponível (como haveria em um caminho WebGPU com TAA).

Sistema de materiais do terreno

Mapeamento triplanar

Texturas com mapeamento UV padrão ficam terrivelmente esticadas em inclinações acentuadas porque as coordenadas UV são comprimidas. O mapeamento triplanar projeta texturas ao longo dos três eixos (X, Y, Z) e faz a mistura com base na normal da superfície:

glsl
vec3 blending = abs(normal);
blending = normalize(max(blending, 0.00001));
blending /= (blending.x + blending.y + blending.z);

vec4 xaxis = texture(material, worldPos.yz * scale);
vec4 yaxis = texture(material, worldPos.xz * scale);
vec4 zaxis = texture(material, worldPos.xy * scale);

vec4 color = xaxis * blending.x + yaxis * blending.y + zaxis * blending.z;

As faces de penhascos recebem a projeção X ou Z (sem esticamento). O terreno plano recebe a projeção Y. A mistura é suave e automática. Não é necessário abrir UVs.

O Babylon.js tem um material triplanar integrado. O Three.js exige um shader personalizado, mas a implementação tem cerca de 30 linhas de GLSL.

Para terrenos PBR, aplique o mapeamento triplanar a todos os canais: albedo, normal, rugosidade e oclusão de ambiente. Os mesmos pesos de mistura são aplicados a cada canal.

Atribuição de materiais baseada em inclinação e altitude

Em vez de pintar splat maps manualmente, atribua materiais de forma procedural com base nas propriedades do terreno:

glsl
float slope = acos(dot(normal, vec3(0, 1, 0)));
float altitude = worldPos.y;

float grassWeight = smoothstep(0.3, 0.0, slope) * smoothstep(2000.0, 1500.0, altitude);
float rockWeight = smoothstep(0.2, 0.5, slope);
float snowWeight = smoothstep(2500.0, 3000.0, altitude) * smoothstep(0.4, 0.1, slope);
float sandWeight = smoothstep(5.0, 0.0, altitude) * smoothstep(0.15, 0.0, slope);

Terrenos planos em baixa altitude recebem grama. Inclinações acentuadas recebem rocha. Grandes altitudes recebem neve (mas somente em superfícies planas o bastante para que ela se acumule). Áreas próximas ao nível do mar recebem areia. As transições são suaves e têm motivação física.

Em um mundo de criadores, disponibilize os limites de altitude e as zonas de mistura como parâmetros que podem ser pintados em cada chunk. Os criadores podem subir ou baixar a linha das árvores, ampliar a cobertura de neve ou transformar uma colina gramada em um deserto arenoso ajustando as regras de materiais de seu lote.

Mistura laplaciana de texturas otimizada para GPU

A mistura padrão de texturas (interpolação linear entre camadas) produz emendas visíveis ou resultados desbotados e com pouco contraste. A mistura por pirâmide laplaciana resolve isso, mas tradicionalmente exige pré-processamento caro.

Wronski (NVIDIA, 2025, JCGT) apresenta uma variante otimizada para GPU que funciona em shaders em tempo real, sem pré-processamento nem memória adicional. A técnica usa a cadeia padrão de mipmaps como aproximação da pirâmide laplaciana: amostra a textura tanto no nível de mip atual quanto em um nível menos detalhado, calcula a diferença (o laplaciano) e mistura as contribuições laplacianas de cada camada.

O resultado preserva características locais nítidas (folhas individuais de grama e rachaduras nas rochas), enquanto mantém uma mistura suave em escalas maiores. O custo é de algumas leituras adicionais de textura por fragmento. Em terrenos nos quais você mistura 4 ou mais camadas de material por pixel, isso produz resultados visivelmente melhores que a mistura linear, especialmente nas transições entre grama, rocha e areia.

Ruído fasorial para detalhes de erosão

Terrenos convencionais costumam parecer planos quando vistos de perto porque a simulação de erosão opera na resolução do mapa de altura (grade de 1 metro). Terrenos reais têm padrões de erosão em pequena escala (sulcos, ravinas e rachaduras causadas pelo intemperismo) na escala de centímetros.

Grenier et al. (2024, CGF) usam ruído fasorial para adicionar microdetalhes de terreno em tempo real. O ruído fasorial sintetiza padrões estruturados definindo um campo de fase estocástico que alimenta funções periódicas. Aplicado ao terreno, ele cria padrões de erosão com variação espacial que:

  • Transformam sulcos estreitos em ravinas maiores ao longo de várias escalas
  • Alinham-se automaticamente à inclinação do terreno (os padrões de erosão seguem a linha de maior declive)
  • Alcançam uma amplificação de até 32 vezes (adicionando detalhes com 32 vezes a resolução do mapa de altura)
  • São executados inteiramente em um fragment shader, com taxas de quadros interativas

Em um mundo no navegador, o ruído fasorial é executado no shader do terreno como uma camada de detalhes. O mapa de altura fornece a forma em grande escala. O ruído fasorial adiciona microerosão convincente no fragment shader sem aumentar a complexidade geométrica. Os parâmetros (frequência, amplitude e orientação do padrão) podem variar por bioma: sulcos profundos em rocha exposta, ondulações suaves em dunas de areia e textura áspera semelhante a casca de árvore em lama seca.

Texturização virtual para terrenos

Em grandes escalas, o atlas de texturas do terreno se torna difícil de gerenciar. Um mundo de 4 km x 4 km, com 1 texel por centímetro, precisaria de uma textura de 400.000 x 400.000 pixels. Obviamente impossível.

A texturização virtual (também chamada de megatextura, nome originado no Rage, da id Software) resolve isso tratando a textura do terreno como uma estrutura paginada. A textura completa existe conceitualmente, mas somente os ladrilhos visíveis na tela são carregados na memória da GPU. O pipeline:

  1. Passo de feedback: Renderize o terreno com um shader que indique qual bloco de textura cada pixel precisa (ID do bloco e nível de mip). Leia esses dados de volta na CPU (ou processe-os com um compute shader).
  2. Carregamento de blocos: Carregue os blocos solicitados da CDN ou gere-os proceduralmente a partir dos dados do splat map.
  3. Textura de indireção: Uma pequena textura mapeia as coordenadas dos blocos virtuais para coordenadas de blocos físicos em um atlas de texturas.
  4. Passo de renderização: O shader do terreno consulta a textura de indireção para encontrar o bloco físico correto e, em seguida, amostra a textura do material no atlas.

Os compute shaders do WebGPU podem realizar a análise de feedback e o gerenciamento da tabela de páginas inteiramente na GPU. A CPU gerencia apenas a entrada e saída dos blocos.

O resultado: um terreno com texturização única em qualquer resolução, sem uma explosão no consumo de memória de texturas. Blocos distantes da câmera são carregados em baixa resolução. Blocos próximos são carregados em alta resolução. O uso total de memória permanece dentro de um orçamento fixo (normalmente, um atlas de texturas de 128 a 256 MB).

Efeitos Dinâmicos no Terreno

Poças e Umidade

A chuva não apenas cai. Ela se acumula. Em depressões, forma poças. Nas superfícies, cria um brilho molhado. Em encostas íngremes, escoa. Simular isso faz com que o clima pareça conectado ao terreno, em vez de ser apenas uma sobreposição visual.

A abordagem baseada em shaders não simula a dinâmica dos fluidos. Ela usa o mapa de altura do terreno para determinar onde a água se acumula:

glsl
float concavity = heightCenter * 4.0 - heightLeft - heightRight - heightUp - heightDown;
float puddleDepth = max(0.0, concavity * rainIntensity - evaporationRate * timeSinceRain);
float wetness = smoothstep(0.0, 0.02, puddleDepth);

vec3 wetColor = baseColor * 0.7;
float wetRoughness = baseRoughness * 0.3;
vec3 finalColor = mix(baseColor, wetColor, wetness);
float finalRoughness = mix(baseRoughness, wetRoughness, wetness);

Áreas côncavas (laplaciano negativo do mapa de altura) acumulam água. Quanto maior a concavidade, maior a poça. Superfícies molhadas escurecem e ficam mais reflexivas (menor rugosidade). O efeito desaparece gradualmente depois que a chuva para.

Para reflexos completos nas poças, adicione um passo de reflexão planar na superfície da poça. Outra opção é usar reflexos em espaço de tela (SSR), que custam menos e já estão disponíveis nas pilhas de pós-processamento do Three.js e do Babylon.js.

As gotas de chuva nas superfícies das poças usam uma equação de onda 2D simples em uma textura de feedback (Saurel, 2026, Blog). Cada gota cria uma ondulação que se propaga para fora e se dissipa. A textura de onda modula o mapa de normais da poça, criando padrões de ondulação convincentes a 60 fps.

Pegadas e Deformação do Terreno

Quando um jogador caminha sobre terreno macio (areia, neve, lama), as pegadas aumentam a sensação de presença física. A técnica: manter uma pequena textura de deformação por chunk (64x64 pixels = 4 KB) que armazena deslocamentos de altura. Quando um personagem pisa em terreno macio, carimbe o formato de uma pegada na textura de deformação.

O vertex shader do terreno lê a textura de deformação e subtrai o deslocamento da altura. O fragment shader do terreno escurece a área da pegada (solo compactado é mais escuro) e aumenta a rugosidade (superfície remexida).

As pegadas desaparecem com o tempo (a neve volta a preenchê-las, a chuva apaga as marcas na lama) por meio da zeragem gradual da textura de deformação. A velocidade de desaparecimento depende do clima: rápida na chuva e lenta em condições secas.

Em um mundo multijogador, os dados das pegadas são efêmeros e locais. Cada cliente gera pegadas para os jogadores visíveis. A textura de deformação não precisa ser sincronizada entre os clientes (cada um vê sua própria versão das pegadas temporárias). Isso evita o custo de rede de transmitir cada passo.

Céu Procedural e Ciclo de Dia e Noite

O céu é a maior superfície visível em qualquer mundo aberto. Ele define a atmosfera de todo o terreno.

O Three.js tem um sistema de céu completo que inclui sol e lua procedurais, ciclo de dia e noite, nuvens, estrelas e reflexos de lente. O exemplo Sky integrado ao Three.js (também disponível em WebGPU) implementa o modelo analítico de céu de Preetham.

Para resultados fisicamente mais precisos, o webgpu-sky-atmosphere implementa o modelo atmosférico de Hillaire como um pós-processamento em WebGPU. Ele é compatível com múltiplas funções de fase de espalhamento e produz, a partir de princípios físicos, perspectiva aérea correta (terrenos distantes parecem mais nebulosos), cores do sol e do pôr do sol e gradientes do céu.

O TerrainView7 demonstra a renderização de planetas em escala completa no WebGPU com espalhamento atmosférico pré-calculado, provando que a renderização atmosférica fisicamente precisa funciona em um navegador.

Em um mundo de criação, os parâmetros do céu (posição do sol, cobertura de nuvens e densidade da névoa) são sincronizados entre todos os clientes a partir do relógio mundial do servidor. O shader do céu é executado localmente em cada cliente, produzindo iluminação consistente para todos os jogadores.

Iluminação do Terreno: Iluminação Indireta

A luz solar direta é tratada por mapas de sombras. Porém, a cor e o brilho do terreno na sombra (luz ambiente/indireta) são igualmente importantes para a qualidade visual. Sombras completamente pretas parecem erradas. Elas devem ser tingidas pela cor do céu (azul em um dia de céu limpo, cinza em um dia nublado).

Para um mundo executado no navegador, a abordagem prática é:

A iluminação indireta em espaço de tela com máscara de bits de visibilidade (Jimenez et al., 2023, Artigo) aprimora o SSAO padrão ao rastrear 32 setores direcionais de visibilidade por pixel. Isso captura não apenas o quanto um ponto está ocluído, mas também a direção da oclusão. Superfícies finas permitem corretamente a passagem da luz vinda do outro lado. O resultado é uma iluminação indireta que reage à geometria próxima sem exigir uma infraestrutura de iluminação global.

O custo é comparável ao do SSAO (1 a 2 ms). A melhoria visual é significativa: o terreno em cânions recebe luz refletida pelas paredes do cânion. As partes inferiores de saliências são iluminadas pelo reflexo do solo. O efeito se combina ao espalhamento atmosférico do shader do céu para produzir uma iluminação ambiente com base física.

Integração da Física do Terreno

Colliders de Campo de Altura do Rapier

O motor de física WASM do Rapier oferece colliders nativos de campo de altura otimizados para terrenos. Criar um collider de terreno é simples:

typescript
const heights = new Float32Array(65 * 65);
// Fill with heightmap data...
const groundCollider = RAPIER.ColliderDesc.heightfield(
  64, 64, heights, new RAPIER.Vector3(64.0, 100.0, 64.0)
);
world.createCollider(groundCollider);

O collider de campo de altura usa a grade estruturada para consultas eficientes na fase ampla. O raycast contra um campo de altura tem complexidade O(log n), em vez de O(n) para uma malha de triângulos. Em um chunk de 65x65, as consultas de colisão são resolvidas em microssegundos.

Para chunks com terreno volumétrico (sobreposições de SDF), gere uma malha de triângulos a partir da saída do marching cubes e use um collider de malha triangular. Isso é mais custoso do que um collider de campo de altura, mas lida com geometria arbitrária. Gere colliders de malha triangular apenas para os 3 a 5 chunks mais próximos do jogador. Chunks distantes não precisam de física.

Desempenho: O collider de campo de altura do Rapier para um chunk de 65x65 adiciona aproximadamente 0,1 ms por passo de física às consultas do controlador de personagem. Cinco chunks ativos com colliders de campo de altura: 0,5 ms. Um collider de malha triangular para um chunk volumétrico: 0,2 a 0,5 ms. Orçamento total para a física do terreno: menos de 1 ms, bem dentro do orçamento de 2 a 3 ms para a física do mundo inteiro.

Controlador de Personagem Sensível ao Terreno

O controlador de personagem precisa reagir às propriedades do terreno:

  • Limitação de inclinação: O personagem pode caminhar em inclinações de até 45 graus. Inclinações mais acentuadas fazem com que ele deslize. Isso usa a normal do terreno na posição do personagem (calculada de forma econômica a partir do gradiente do mapa de altura).
  • Resposta ao material da superfície: Caminhar sobre rocha produz sons de passos e uma velocidade de movimento diferentes de caminhar sobre areia ou lama. O splat map do terreno fornece o material da superfície em qualquer ponto.
  • Subida de degraus: O personagem pode subir saliências de até 0,5 metro. O KinematicCharacterController do Rapier cuida disso automaticamente com uma altura de degrau configurável.

Edição Interativa de Terreno no Navegador

Em um mundo de criação, o terreno não é apenas gerado. Ele é esculpido, modificado e remodelado pelos jogadores. As ferramentas de edição precisam ser responsivas (feedback visual instantâneo) e conectadas em rede (outros jogadores veem as alterações em poucos segundos).

Editor de SDF em WebGPU

O Editor de SDF em WebGPU de Reinder Nijhoff demonstra que a modelagem SDF completa já funciona no navegador. O editor oferece:

  • Seis formas primitivas (esfera, caixa, cone, cilindro, cápsula e toro) com posição, rotação e escala
  • Operações booleanas (união, subtração e interseção) com mesclagem suave e raios de mesclagem configuráveis
  • Grafos de cena hierárquicos com grupos e operações aninhadas
  • Renderização em tempo real usando vários estágios de compute shaders na GPU, particionamento espacial baseado em octree em 16.384 células de grade e extração de superfície por marching cubes ou surface nets
  • Antisserrilhamento temporal e oclusão de ambiente por meio de mapas de sombras

Cada primitiva é armazenada como 28 floats (112 bytes) em um único buffer da GPU. Essa representação compacta significa que uma edição de terreno complexa (dezenas de primitivas SDF definindo a entrada de uma caverna, um arco ou a face esculpida de um penhasco) ocupa menos de 5 KB e é sincronizada instantaneamente com outros jogadores.

Em um mundo de criação, o fluxo de edição com SDF é assim:

  1. O criador seleciona uma ferramenta de escultura (adicionar esfera, subtrair caixa, mesclagem suave)
  2. Clica e arrasta no mundo para posicionar e dimensionar a primitiva SDF
  3. O cliente executa imediatamente o marching cubes no SDF modificado para atualizar a malha local (feedback em <16 ms)
  4. A edição SDF (tipo da primitiva + transformação + modo de mesclagem, ~100 bytes) é enviada ao servidor
  5. O servidor valida a edição (está dentro do lote do criador e não cruza áreas protegidas) e a transmite aos jogadores próximos
  6. Os clientes dos outros jogadores aplicam a edição SDF e regeneram sua malha local

O tempo total de ida e volta para que uma edição fique visível aos demais é de 100 a 300 ms, dependendo da latência da rede. O criador vê sua edição instantaneamente porque ela é aplicada localmente antes da confirmação do servidor.

Edição de Mapa de Altura com Pincéis

Para a camada de mapa de altura (os 90% do terreno que não precisam de recursos volumétricos), funciona um modelo de edição mais simples. O criador pinta modificações de altura com um pincel:

  • Elevar/rebaixar: Adiciona ou subtrai altura dentro de um raio com atenuação
  • Suavizar: Calcula a média das alturas dentro de um raio, removendo características abruptas
  • Achatar: Define todas as alturas dentro de um raio para um valor-alvo
  • Pincel de erosão: Aplica localmente algumas etapas de erosão hidráulica dentro do raio do pincel

A edição do mapa de altura é um delta: um pequeno trecho de alterações de altura sobreposto ao terreno-base. O trecho de delta é minúsculo (uma grade de 32x32 com deslocamentos de altura de 16 bits = 2 KB) e é sincronizado com outros jogadores em uma única mensagem. Vários trechos de delta se acumulam por chunk e são mesclados periodicamente no servidor ao mapa de altura persistente do chunk.

Restrições de Edição Colaborativa

Quando vários criadores editam o mesmo chunk simultaneamente, o sistema precisa de regras:

  • Bloqueio espacial: Apenas um criador pode editar uma determinada sub-região de 8x8 metros por vez. O bloqueio é adquirido quando o criador inicia uma pincelada de edição e liberado quando ele solta o pincel. Os bloqueios expiram após 10 segundos de inatividade.
  • Edições sem sobreposição: Se dois criadores editarem partes diferentes do mesmo chunk, ambas as edições serão aplicadas sem conflito (elas modificam células diferentes do mapa de altura ou regiões SDF diferentes).
  • Edições sobrepostas: Se dois criadores editarem o mesmo local, o servidor serializa as edições na ordem de chegada. Ambos os clientes veem o mesmo resultado final após a reconciliação.

Isso é mais simples do que a abordagem CRDT completa usada para objetos posicionados, pois as edições de terreno são operações aditivas em um campo contínuo (alturas, distâncias SDF), e não estados de objetos discretos.

Geometria Virtual no Estilo Nanite em WebGPU

O Nanite do Unreal Engine 5 renderiza bilhões de triângulos criando um DAG de clusters (grafo acíclico direcionado) no momento da compilação e selecionando o LOD correto por cluster durante a execução, com base no erro em espaço de tela. Todo o pipeline é executado na GPU. Essa abordagem foi portada para o WebGPU.

Nanite WebGPU

Nanite WebGPU renderizando uma cena complexa com vários objetos em um navegador usando hierarquia de LOD de meshlets e rasterizador por software
Nanite WebGPU renderizando uma cena completa no Chrome com LOD de meshlets, rasterização por software em compute shaders WGSL e descarte por frustum e oclusão para cada meshlet. Nenhum plugin nativo — WebGPU puro.

O Nanite WebGPU de Scthe (mais de 1,1 mil estrelas no GitHub) é uma implementação completa para navegador da arquitetura principal do Nanite:

  • Hierarquia de LOD de meshlets criada offline usando a geração de clusters do meshoptimizer
  • Rasterizador por software implementado em compute shaders WGSL (operando dentro das limitações do WebGPU, em que a rasterização por hardware não consegue executar desenhos por cluster com eficiência)
  • Descarte por instância e por meshlet usando testes de frustum e oclusão
  • Impostores em billboard para objetos extremamente distantes
  • Suporte a texturas e normais por vértice O pipeline: as malhas são divididas em clusters de aproximadamente 128 triângulos. Clusters vizinhos são agrupados, e cada grupo é simplificado (usando meshoptimizer), preservando os limites compartilhados. Esse processo se repete recursivamente até que toda a malha seja reduzida a um único cluster. Em tempo de execução, um compute shader percorre o DAG e seleciona, para cada grupo, o cluster mais simplificado que produza menos de 1 pixel de erro na resolução atual da tela.

O THREE-Nanite é uma implementação emergente para Three.js que alcança de 20 a 40 fps em hardware gráfico integrado ao lidar com centenas de milhares de triângulos. Ela demonstra que a renderização no estilo Nanite é viável até mesmo em hardware de baixo desempenho para navegadores.

meshoptimizer: a base do pipeline de LOD

O meshoptimizer (de Arseny Kapoulkine) é a biblioteca por trás da maioria dos pipelines de LOD compatíveis com navegadores. A versão 1.0 (2025) oferece:

  • Simplificação de malhas com métricas de erro (quanto a forma mudou, usado para a seleção de LOD)
  • Geração de clusters para hierarquias de meshlets no estilo Nanite
  • Otimização do cache de vértices para uma ordenação de triângulos eficiente para a GPU
  • Otimização de overdraw para reduzir o custo do pixel shader
  • Quantização e compressão de vértices para downloads menores

O meshoptimizer 1.0 (lançado em dezembro de 2025) inclui um novo arquivo de cabeçalho único, clusterlod.h, que implementa diretamente o LOD contínuo no estilo Nanite. Ele constrói uma hierarquia de clusters que são progressivamente agrupados e simplificados, podendo ser usada como está ou como referência para um pipeline personalizado. Esse é exatamente o primitivo de DAG de clusters de que o pipeline de terreno precisa para o LOD de malhas de SDF/marching cubes.

Para nosso pipeline de terreno, o meshoptimizer processa a saída de marching cubes do terreno SDF, transformando-a em malhas otimizadas e agrupadas em clusters com hierarquias de LOD. O processamento offline é executado no servidor. O navegador recebe malhas previamente agrupadas e realiza a seleção de LOD orientada pela GPU em tempo de execução.

A combinação do meshoptimizer para geração de LOD com computação WebGPU para seleção em tempo de execução oferece ao terreno no navegador o mesmo padrão arquitetural do Nanite, adaptado às restrições da web.

Design de níveis orientado pelo terreno

O terreno não é apenas uma superfície sobre a qual caminhar. Sua forma orienta o movimento dos jogadores, direciona a atenção e cria o ritmo emocional da exploração. Os melhores mundos abertos usam o terreno como ferramenta de design.

Linhas de visão e pontos de referência

O capítulo sobre orientação do Level Design Book documenta como a elevação do terreno controla o que os jogadores veem e para onde vão. Uma crista esconde o que existe além dela, despertando curiosidade. Um vale canaliza o movimento em direção ao seu ponto mais baixo. Um ponto de referência alto (torre, pico de montanha, árvore incomum), visível à distância, oferece aos jogadores um objetivo para o qual caminhar.

Para um mundo de criadores, isso significa que a geração de terreno deve produzir elementos naturais de orientação. As linhas de crista devem interromper as linhas de visão, criando "momentos de revelação" quando um jogador chega ao topo de uma colina e avista uma nova área. Os vales devem convergir para locais interessantes. Devem existir pontos elevados onde os criadores possam posicionar marcos visíveis de longe.

Exploração movida pela curiosidade

Uma pesquisa da Universidade Purdue (Artigo) identifica quatro gatilhos para a exploração espacial:

  1. Alcançar pontos extremos (o pico mais alto, a borda mais distante, a caverna mais profunda). O terreno deve ter extremos claros que recompensem quem os alcança.
  2. Desvendar obstruções visuais (o que há atrás daquele penhasco? Dentro daquela caverna?). Um terreno que bloqueia a visão motiva o movimento para descobrir o que está escondido.
  3. Objetos fora de contexto (uma estrutura na natureza selvagem, uma luz na escuridão). Objetos posicionados pelos criadores em contraste com o terreno natural atraem a atenção.
  4. Compreender conexões espaciais (como este vale se conecta àquela costa?). Um terreno que cria uma geografia legível incentiva a leitura do mapa e o planejamento de rotas.

PlotMap: posicionamento de POIs assistido por IA

O PlotMap (arXiv:2309.15242) automatiza a disposição de pontos de interesse usando requisitos narrativos (esta missão precisa de uma vila perto de um rio, aquela missão precisa de uma ruína no topo de uma colina) e encontrando locais no terreno que atendam às restrições espaciais. Para um mundo de criadores, um sistema semelhante poderia sugerir onde posicionar estruturas com base nas propriedades do terreno: "este topo de colina tem boas linhas de visão para uma torre de vigia", "este vale protegido seria adequado para uma vila".

Água corrente e cachoeiras

Rios e cachoeiras são elementos do terreno que combinam apelo visual com som ambiente e possibilidades de jogabilidade (água como barreira, recurso ou caminho).

Renderização de rios

Em mundos abertos, os rios costumam ser renderizados como faixas texturizadas que acompanham a superfície do terreno. A malha da faixa é gerada a partir da spline do rio (armazenada como pontos de controle) e projetada sobre o mapa de altura do terreno. O shader do rio aplica:

  • UVs alinhadas ao fluxo que se deslocam na direção do rio, criando a aparência de água corrente
  • Espuma nas margens, onde o rio encontra a borda (baseada em profundidade, semelhante à espuma do litoral)
  • Variação de velocidade baseada na largura do canal (trechos estreitos fluem mais rápido, enquanto trechos largos ficam mais lentos)
  • Transparência com cor baseada em profundidade (águas rasas são claras; águas profundas são escuras)

Para um mundo no navegador, os dados do rio são compactos: uma spline (20 a 50 pontos de controle por segmento de rio, aproximadamente 400 bytes), além dos parâmetros de largura e velocidade do fluxo. O cliente gera localmente a malha do rio projetando a spline sobre a superfície do terreno.

Renderização de cachoeiras

Onde um rio despenca por um penhasco, um sistema de partículas de cachoeira substitui a superfície plana do rio. A abordagem híbrida da pesquisa sobre simulação de água em tempo real (EG) funciona assim: regiões que não podem ser representadas por um campo de altura (cachoeiras, respingos) são convertidas em partículas de névoa, respingos e espuma que trocam massa e momento com a simulação de fluido.

Para um mundo no navegador, as cachoeiras são mais simples: detecte onde a spline do rio cruza uma descontinuidade de altura do terreno, gere um sistema de partículas nesse ponto com velocidade descendente e adicione um respingo de espuma na base. As partículas são quads instanciados pela GPU com texturas alfa em movimento. São 500 partículas por cachoeira, em uma única chamada de desenho. O som da água caindo usa a Web Audio API com atenuação por distância.

Impostores para elementos distantes do terreno

Árvores, rochas, construções e outros elementos do terreno ficam minúsculos à distância. Renderizá-los como malhas 3D completas desperdiça ciclos da GPU. Impostores substituem objetos distantes por imagens planas pré-renderizadas voltadas para a câmera.

Atlas de impostores octaédricos

Um impostor octaédrico captura a aparência de um objeto 3D de vários ângulos de visualização e armazena essas imagens em um atlas de texturas. Em tempo de execução, o shader amostra o atlas com base na direção atual da visualização, interpolando entre os dois ângulos capturados mais próximos.

Um atlas hemioctaédrico (apenas com vistas do hemisfério superior, já que raramente se olha para árvores de baixo para cima) oferece o dobro da resolução angular de um atlas octaédrico completo com o mesmo tamanho de textura. O sistema de impostores da Unity relata uma redução do tempo de quadro de 111 ms para 5,78 ms ao trocar 1.600 instâncias de árvores de malhas reais (140 mil triângulos cada) por impostores.

Para um mundo no navegador, o pipeline de impostores é:

  1. No servidor: renderizar cada asset de 16 a 32 ângulos de visualização, capturando cor, normal e profundidade
  2. Empacotar tudo em uma textura de atlas (um atlas por asset, aproximadamente 256x256 pixels, <100 KB como KTX2)
  3. Em tempo de execução: instâncias além da distância de impostor (normalmente entre 100 e 200 m) são renderizadas como billboards que amostram o atlas
  4. Fazer uma transição gradual entre a malha e o impostor ao longo de uma zona de transição de 20 m para ocultar a troca

Billboard Splatting (BBSplat)

O Billboard Splatting (2024, arXiv:2411.08508) leva essa abordagem mais longe usando primitivas planas texturizadas treináveis. Em vez de vistas pré-renderizadas, o BBSplat otimiza as posições e texturas dos billboards para representar da melhor forma possível o objeto 3D de qualquer ângulo. Isso alcança uma compressão até 17 vezes maior em comparação com o 3D Gaussian Splatting, mantendo a aparência dependente do ponto de vista. Para elementos distantes do terreno em um mundo no navegador, o BBSplat poderia reduzir o armazenamento de impostores por asset e, ao mesmo tempo, melhorar a cobertura angular.

Ferramentas profissionais de terreno e o que elas ensinam

Antes de criar um pipeline de terreno do zero, vale a pena entender o que as ferramentas profissionais offline fazem. Essas ferramentas representam décadas de pesquisa em geração de terrenos transformadas em fluxos de trabalho de produção.

O Gaea (QuadSpinner) é acelerado por GPU e oferece feedback quase instantâneo sobre as alterações. Ele permite compilações em blocos de até 2 milhões de pixels por lado, exportação automática de malhas com LOD e um grafo baseado em nós no qual cada nó representa um processo físico (erosão, sedimentação, soerguimento, intemperismo térmico). Os nós de erosão do Gaea produzem terrenos que parecem esculpidos à mão porque modelam processos físicos específicos, em vez de ruído genérico. O principal insight: o Gaea não usa um único algoritmo de erosão. Ele oferece nós separados para erosão fluvial (escavação por rios), erosão térmica (desmoronamento de penhascos), erosão costeira (ação das ondas) e erosão eólica (formação de dunas de areia). Combiná-los em um grafo produz terrenos com as características geológicas de um clima específico.

O World Machine adota uma abordagem semelhante baseada em grafos, com foco na macroestrutura do terreno. Seu "gerador de layout" permite que artistas esbocem a forma aproximada dos elementos do terreno (montanha aqui, vale ali, litoral ao longo desta borda), e o sistema preenche o restante com detalhes fisicamente plausíveis. Esse é exatamente o fluxo de trabalho que queremos para os criadores: esboçar a intenção e obter a geologia.

O World Creator se diferencia pela visualização em tempo real durante a edição e pela geração integrada de rios, que analisa o terreno e calcula automaticamente as trajetórias de fluxo com base em análise de drenagem.

O que aproveitamos dessas ferramentas: A abordagem de grafo de nós para combinar processos físicos é mais poderosa do que qualquer algoritmo isolado. Nosso pipeline de geração no servidor deve permitir o encadeamento: base de ruído > soerguimento tectônico > erosão hidráulica > intemperismo térmico > erosão costeira > vegetação. Os criadores controlam os parâmetros em cada etapa. O pipeline é executado no servidor em segundos e produz mapas de altura, splat maps e mapas de densidade de vegetação.

SoilMachine: geomorfologia de código aberto

SoilMachine: simulador modular de geomorfologia de código aberto mostrando terreno com erosão hidráulica, térmica e eólica acopladas
O SoilMachine acopla erosão hidráulica, térmica e eólica em um único modelo de terreno em camadas. A estrutura de dados multicamada permite recursos que mapas de altura não conseguem representar: cavernas, saliências, morros-testemunho e distribuições de água subterrânea.

O SoilMachine é um simulador modular de geomorfologia de código aberto que acopla vários sistemas de erosão (hidráulica, térmica e eólica) ao transporte e à deposição de sedimentos. Desenvolvido em C++ com computação na GPU, ele oferece uma implementação de referência da abordagem de erosão com múltiplos processos usada por ferramentas profissionais.

A biblioteca relacionada soillib (C++20, licença MIT) fornece os primitivos subjacentes de simulação geomorfológica como uma biblioteca reutilizável. E o hydro-gen implementa erosão hidráulica baseada tanto em grade (águas rasas) quanto em partículas (gotas de chuva), usando compute shaders OpenGL com ajuste de parâmetros em tempo real.

Essas ferramentas de código aberto poderiam ser adaptadas para nosso pipeline de geração no servidor. As implementações em compute shaders podem ser traduzidas diretamente para WebGPU caso algum dia queiramos executar a erosão no navegador para oferecer feedback em tempo real aos criadores.

Materiais de terreno multicamada

O terreno real não é uma única superfície. Ele é composto por camadas: rocha matriz na base, solo por cima e neve ou areia acumulando-se sobre as superfícies. As camadas dinâmicas alteram a aparência do terreno conforme as estações, o clima e as ações dos criadores.

Representação por campo de altura em camadas

Em vez de um único mapa de altura, use várias camadas de altura por célula da grade:

Cell {
  bedrock_height: f16,    // permanent rock surface
  soil_height: f16,       // accumulated soil/sediment above bedrock
  snow_height: f16,       // dynamic snow accumulation
  water_height: f16       // standing water depth
}

Total: 8 bytes por célula (em comparação com 2 bytes para um único mapa de altura). Para um chunk de 65x65, isso representa 34 KB antes da compressão. Ainda é compacto.

A superfície visual é bedrock + soil + snow. O shader do terreno lê todas as camadas e mistura os materiais de acordo: onde o solo é fino, a rocha fica exposta. Onde a neve se acumulou, a superfície fica branca. Onde a água se acumula, surgem poças ou lagos.

Acúmulo dinâmico

A neve se acumula em superfícies planas voltadas para cima durante uma nevasca. A taxa de acúmulo depende da normal da superfície (encostas íngremes não retêm neve), da temperatura (dependente da altitude) e da proteção (áreas sob saliências permanecem limpas). Uma passagem de compute shader atualiza a camada de neve uma vez por ciclo meteorológico (a cada poucos segundos).

O acúmulo de areia funciona de forma semelhante, com deposição impulsionada pelo vento. O vento transporta partículas de superfícies expostas e as deposita atrás de obstáculos e em áreas protegidas.

Para um mundo de criadores, o acúmulo dinâmico faz com que o terreno pareça diferente conforme o clima. A neve cobre o mundo durante uma nevasca e derrete durante um período de tempo aberto. A chuva enche depressões com água. Isso faz com que o mundo pareça responsivo sem que os criadores precisem fazer nada.

Erosão multicamada

O artigo de 2024 "3D Real-Time Hydraulic Erosion Simulation using Multi-Layered Heightmaps" (EG) amplia a erosão para funcionar entre camadas. A água erode o solo mais rapidamente do que a rocha matriz. O sedimento é depositado como uma nova camada de solo. A simulação mantém a integridade das camadas (a rocha matriz permanece abaixo do solo), ao mesmo tempo que permite elementos complexos, como saliências (onde a rocha matriz se projeta sobre o solo erodido abaixo). Desempenho: aproximadamente 6 ms por etapa de simulação em uma RTX 3070 com resolução de 2048x2048. Isso é rápido o suficiente para geração no servidor, mas lento demais para simulação no navegador a cada quadro. A representação em camadas funciona para a geração de terrenos estáticos, enquanto o acúmulo dinâmico de neve/água é executado como um shader mais leve a cada quadro.

Renderização de Grama, Rochas e Detalhes

A paisagem precisa de mais do que geometria e texturas de terreno. Ela precisa de folhas de grama que balancem com o vento, rochas espalhadas pelas encostas e pequenos detalhes, como flores, seixos e galhos caídos, que façam as vistas de perto parecerem naturais.

Grama Instanciada por GPU

Um milhão de folhas de grama renderizadas com instanciamento por GPU em uma única chamada de desenho. A mesma técnica funciona em Three.js e WebGPU: transformações por instância, animação de vento no shader de vértices e um mapa de densidade para distribuir as folhas a partir dos dados do terreno.

A renderização de grama no navegador é uma técnica bem consolidada no Three.js e funciona por meio de instanciamento por GPU. A abordagem da demonstração de grama de al-ro renderiza 100.000 folhas de grama com uma única chamada de desenho usando InstancedBufferGeometry.

Cada folha de grama é um quad simples (4-8 triângulos). Os atributos por instância definem posição, altura, direção da curvatura, variação de cor e fase do vento. O shader de vértices:

  1. Lê a transformação por instância
  2. Aplica a animação de vento usando ondas senoidais vinculadas à posição no mundo e ao tempo
  3. Curva a folha com base na intensidade do vento (mais curvatura na ponta, nenhuma na base)
  4. Aplica um gradiente de cor (mais escuro na base e mais claro na ponta para simular dispersão subsuperficial)

O tutorial de grama volumosa da Codrops (2025, Tutorial) demonstra uma abordagem de texturização em camadas: renderizar o plano do solo várias vezes com deslocamentos crescentes, com cada camada amostrando uma textura de ruído para criar a aparência de um volume denso de grama. Isso é mais barato do que instanciar folhas individuais para uma cobertura muito densa, mas menos realista de perto.

Em um mundo de criador, a densidade da grama vem do mapa de densidade da vegetação de cada chunk. A GPU distribui as posições das folhas a partir do mapa de densidade durante a renderização. Nenhum dado individual por folha é armazenado ou transmitido. O mapa de densidade é uma grade de 32x32 por chunk (1 KB), e a GPU gera milhares de instâncias de folhas a partir dela.

Detalhes Procedurais de Rochas e Penhascos

Paredões e terrenos rochosos precisam de detalhes geométricos que o mapa de altura ou SDF básico não consegue fornecer com uma resolução razoável. Duas abordagens se complementam:

Reconstrução de superfície com mesh shader na GPU (Raad et al., Eurographics 2025, Artigo) gera geometria procedural durante a renderização a partir de uma malha de controle de baixa resolução. O mesh shader lê uma superfície de terreno básica e adiciona deslocamentos, fissuras e saliências sem armazenar a geometria detalhada na memória. Isso reduz o uso de VRAM e permite LOD dinâmico.

Distribuição de rochas instanciadas posiciona malhas de rochas pré-fabricadas em encostas íngremes e bordas de penhascos usando instanciamento por GPU. Um compute shader lê a normal e a inclinação do terreno e distribui instâncias de rochas onde a inclinação ultrapassa um limite. Cada instância é uma pequena malha (200-500 triângulos) com rotação e escala aleatórias. Com instanciamento, 10.000 rochas distribuídas acrescentam um custo de renderização insignificante.

Estradas e Caminhos

Estradas, trilhas e caminhos posicionados pelos criadores precisam se ajustar ao terreno e modificar o material da superfície, substituindo a grama por terra ou pedra.

A abordagem usada por todos os principais motores de jogos é definir o caminho como uma spline (uma série de pontos de controle). Projete a spline sobre a superfície do terreno. Gere uma malha em faixa que acompanhe a spline e fique ligeiramente acima do terreno. Aplique uma textura de estrada à faixa. No shader do terreno, mescle o material do terreno com o material da estrada dentro da largura da spline usando uma textura projetada ou decalque.

Em um mundo de navegador, o criador desenha um caminho sobre o terreno. O cliente gera pontos de controle e os envia ao servidor (algumas dezenas de valores vec3). O servidor armazena a spline. Todos os clientes renderizam localmente a faixa da estrada projetando a spline sobre sua malha de terreno. Os dados da estrada são mínimos (pontos da spline do caminho, talvez 200 bytes), mas o impacto visual é grande: caminhos conectando as construções dos criadores fazem o mundo parecer habitado.

Sombras do Terreno

As sombras do terreno são essenciais para a legibilidade (compreender o relevo) e a atmosfera (o clima de cada horário do dia). Em um mundo aberto, o sol projeta sombras sobre todo o terreno visível.

Mapas de Sombras em Cascata (CSM)

O CSM divide o frustum de visualização em 3-4 faixas de distância (cascatas). Cada cascata renderiza um mapa de sombras da perspectiva do sol com uma resolução apropriada para sua distância. Cascata próxima: alta resolução (sombras detalhadas sob árvores e construções). Cascata distante: baixa resolução (sombras amplas de montanhas).

Tanto o Three.js quanto o Babylon.js oferecem suporte a CSM. A principal otimização para o terreno é renderizar apenas o terreno no mapa de sombras, e não folhas individuais de grama ou pequenos detalhes. A grama recebe sombras usando o mapa de sombras do terreno, não o seu próprio.

Orçamento de desempenho: 3-4 cascatas de sombras com 1024x1024 cada. Renderizar o terreno nos mapas de sombras custa 0,5-1 ms (a geometria do terreno já está na memória da GPU). Amostrar 4 cascatas no shader do terreno acrescenta 0,2-0,3 ms.

Autossombreamento do Terreno a Partir do Mapa de Altura

Para terrenos muito extensos, nos quais o CSM se torna caro, pré-calcule um mapa de horizonte: para cada célula do terreno, armazene o ângulo máximo de elevação em 8 direções da bússola. Durante a renderização, compare o ângulo do sol com o mapa de horizonte para determinar se um ponto está na sombra. É assim que Skyrim trata o autossombreamento de terrenos distantes (além do alcance do CSM).

O mapa de horizonte é calculado no servidor a partir do mapa de altura (alguns segundos de processamento) e transmitido como uma textura de 128x128 por chunk (16 KB compactados). O impacto visual é significativo: os vales entre montanhas escurecem de forma realista mesmo a distâncias de visualização extremas.

Compactação de Dados de Terreno para Transmissão

A rede é o gargalo de um mundo no navegador. Cada byte economizado nos dados do terreno reduz o tempo de carregamento.

Compactação do Mapa de Altura

Mapas de altura brutos de 16 bits são bem compactados porque células adjacentes têm valores semelhantes. O pipeline:

  1. Codificação delta: Armazene a diferença entre cada célula e seu valor previsto (a média das vizinhas). Os valores delta são pequenos e se concentram perto de zero.
  2. Quantização: Para chunks distantes, reduza a precisão de 16 bits para 12 ou 8 bits. A 500 metros de distância, a precisão de altura de 8 bits (resolução de 0,4 m em uma faixa de altura de 100 m) é indistinguível da de 16 bits.
  3. Codificação por entropia: Aplique compactação zlib ou brotli ao fluxo codificado por delta. Taxa de compactação típica: 4-8x.

Resultado: um chunk de 65x65 com 16 bits passa de 8,4 KB brutos para 1-2 KB compactados. Com precisão reduzida de 8 bits: 0,5-1 KB.

Transmissão Progressiva do Mapa de Altura

Envie primeiro o terreno em baixa resolução e depois o refine. Um mapa de altura de 17x17 (o mínimo para um chunk de 64 m com espaçamento de 4 m entre células) tem 578 bytes brutos e menos de 200 bytes compactados. O terreno fica visível instantaneamente. Em seguida, transmita o refinamento de 33x33 (que adiciona amostras de linhas/colunas ímpares). Depois, a resolução completa de 65x65. Cada nível acrescenta detalhes sem substituir os dados anteriores.

Isso corresponde aos anéis de LOD do clipmap de geometria: terrenos distantes usam a versão de baixa resolução (17x17), os de distância intermediária usam a média (33x33) e os próximos usam a completa (65x65). A prioridade de transmissão corresponde ao LOD de renderização.

Compactação de Volumes SDF

Volumes SDF esparsos são compactados drasticamente porque a maioria dos voxels está distante da superfície (espaço vazio). Opções:

Codificação por comprimento de sequência: Codifique sequências de valores idênticos (voxels vazios). Volumes SDF típicos têm mais de 95% de espaço vazio, portanto a RLE alcança compactação de 10-50x.

Octree esparsa: Armazene apenas os nós da octree que contêm voxels atravessados pela superfície. O espaço vazio não possui nós. Um volume SDF de 64^3 com um único túnel de caverna pode ter apenas 2.000-5.000 nós ocupados (em comparação com 262.144 voxels no total), cada um armazenado em 1-2 bytes.

Compactação progressiva orientada por entropia (2024, HAL) aplica-se a dados espaciais 3D dividindo recursivamente o espaço com planos otimizados por entropia e quantização adaptativa. Isso produz um fluxo de refinamentos otimizado para os compromissos entre taxa e distorção, sendo especialmente vantajoso nas baixas taxas de bits da transmissão em rede.

Juntando Tudo: O Pipeline de Terreno no Navegador

A visão geral estratégica no início deste artigo apresenta um rápido modelo de decisão e um plano de implementação em fases. Esta seção fornece todos os detalhes técnicos dos pipelines de geração no servidor e renderização no navegador.

Pipeline de Geração (Servidor)

O pipeline de geração é executado como um grafo direcionado de processos físicos, inspirado na abordagem de grafo de nós do Gaea e do World Machine. Cada etapa recebe a saída da etapa anterior e a refina. Os criadores controlam os parâmetros em cada etapa.

EtapaEntradaProcessoSaídaTempo
1. Terreno básicoSemente ou prompt de textoTerrain Diffusion / MESA / ruído + fBmMapa de altura de 16 bits1-5 s
2. ErosãoMapa de alturaPotência analítica de fluxo + erosão térmicaMapa de altura erodido, mapa de acúmulo de fluxo, mapa de sedimentos0,5-2 s
3. RiosMapa de altura erodido, mapa de fluxoExtração da rede de drenagem, escavação de canaisSplines de rios, mapa de nível da água0,5 s
4. CostaMapa de altura próximo ao nível do marErosão por ondas no estilo NEWTSFormações costeiras (penhascos, praias, farilhões)1-3 s
5. VolumetriaMapa de altura + intenção do criadorErosão Arenite / geração de cavernas / esculturas SDFVolumes SDF esparsos para os chunks afetados1-60 s
6. MateriaisMapa de altura + mapas de erosãoTerraFusion / Geodiffussr / regras proceduraisMapas de splat, texturas do terreno1-5 s
7. VegetaçãoMapa de altura + mapa de fluxo + materiaisSimulação de competição do ecossistemaMapas de densidade por bioma e por chunk1-3 s
8. Mapas de horizonteMapa de altura finalÂngulo máximo de elevação em 8 direçõesTextura de autossombra por chunk2-5 s
9. Divisão em chunksTodas as saídasRecortar, codificar por delta, compactar, gerar hashPacotes de chunks na CDN5-10 s
Total15-90 s

Um novo mundo de 4x4 km é gerado em 15-90 segundos. Edições do criador (escultura, alterações de parâmetros) reexecutam somente as etapas afetadas nos chunks afetados, geralmente terminando em menos de 5 segundos.

Pipeline de Renderização (Navegador)

EtapaCaminho WebGPUAlternativa WebGL 2Orçamento por quadro
1. TransmissãoFila de prioridades, pré-carregamento preditivoIgualN/D (assíncrono)
2. Terreno por mapa de alturaQuadtree CDLOD controlada pela GPU, descarte por compute, desenho indiretoClipmaps de geometria, atualizações de anéis pela CPU0,5-1 ms
3. Malha volumétricaMarching cubes por compute + TransvoxelMalhas pré-geradas em Web Worker, 2-3 LODs em cache0,5-2 ms
4. Transições de LODGeomorfismo no shader de vérticesIgualIncluído acima
5. MateriaisPBR triplanar + mesclagem laplaciana + detalhes por ruído fasorial + texturização virtualPBR triplanar + mesclagem linear + mapas de splat pré-calculados1-1,5 ms
6. VegetaçãoComputeInstanceCulling + IndirectBatchedMesh, cobertura do solo em ladrilhos hexagonaisDescarte de frustum pela CPU + InstancedMesh1-1,5 ms
7. ÁguaFaixas de rios alinhadas ao fluxo, espuma da margem baseada em profundidadeIgual (reflexos mais simples)0,5 ms
8. SombrasCSM de 3-4 cascatas + autossombras por mapa de horizonteCSM de 2 cascatas0,5-1 ms
9. AtmosferaModelo de céu Hillaire + neblina volumétrica + partículas climáticasCéu Preetham + neblina por distância0,5 ms
10. Efeitos dinâmicosAcúmulo de poças, deformação por pegadas, neve/chuvaAcúmulo de poças, partículas de chuva0,3 ms
Total do terreno3,5-6,5 ms

A 60 fps (16,6 ms por quadro), o sistema de terreno usa 21% do orçamento do quadro no WebGPU e 39% no WebGL 2. O restante fica disponível para avatares dos jogadores, objetos dos criadores, interface, rede e pós-processamento.

Por Que Isso Funciona em um Navegador

Todo o pipeline foi projetado considerando três limitações dos navegadores:

Memória (máximo de 2-4 GB): O orçamento de 256 MB para o terreno é suficiente porque os chunks do mapa de altura têm 2-8 KB cada (codificados por delta), os volumes SDF são esparsos (100-500 KB por chunk volumétrico), a vegetação é gerada em tempo de execução a partir de mapas de densidade de 1 KB e as texturas usam compactação KTX2 (150 KB por 1024x1024). A qualquer momento, o mundo visível no navegador ocupa entre 50 e 200 MB no total.

Sem acesso ao disco: Tudo é transmitido pela rede. O carregamento progressivo permite que o jogador veja o terreno em <100 ms (mapa de altura em baixa resolução), o terreno texturizado em <300 ms e todos os detalhes em ❤️ s. O pré-carregamento baseado na velocidade oculta os tempos de carregamento durante a exploração normal.

A GPU varia drasticamente: O caminho WebGPU atende a desktops de alto desempenho. A alternativa WebGL 2 atende a todo o restante, incluindo dispositivos móveis. Os mesmos dados de chunks alimentam os dois caminhos. A diferença está na técnica de renderização, não no formato dos dados. Um Chromebook executando WebGL 2 vê o mesmo mundo que uma RTX 4090 executando WebGPU, apenas com menos detalhes e menor distância de visualização.

Artigos de Pesquisa

Representação de Terreno e Geração de Malhas

"Marching Cubes: Um Algoritmo de Construção de Superfícies 3D em Alta Resolução" -- Lorensen e Cline (SIGGRAPH 1987). DOI. O algoritmo fundamental para extrair malhas triangulares de dados volumétricos. Ainda é o método de extração de isosuperfícies mais utilizado 38 anos depois. Implementações paralelas em GPU são executadas em tempo real em compute shaders do WebGPU. "Contorno Dual de Dados de Hermite" -- Ju, Losasso, Schaefer, Warren (SIGGRAPH 2002). DOI. Produz malhas que preservam detalhes acentuados (bordas de penhascos, cantos de rochas) que o marching cubes arredonda. Requer normais de superfície além dos valores de distância.

"Contorno Dual Neural" -- Chen et al. (2022). arXiv:2202.01999. Substitui o posicionamento de vértices por mínimos quadrados no contorno dual por um preditor treinado. Oferece melhor qualidade de superfície para elementos naturais complexos.

"O Algoritmo Transvoxel" -- Lengyel (2009, atualizado em 2024). transvoxel.org. Transições de LOD contínuas para terrenos de voxels. Elimina fissuras nos limites entre resoluções usando 73 tipos de células de transição. Livre de patentes e projetado para aplicações em tempo real.

LOD e renderização de terrenos

"Geometry Clipmaps: Renderização de Terrenos Usando Grades Regulares Aninhadas" -- Losasso e Hoppe (SIGGRAPH 2004). Artigo. Renderização de terrenos com custo constante usando anéis concêntricos de LOD. Processa terrenos de 40 GB em taxas interativas. É a base da maioria dos renderizadores de terreno para navegadores.

"CDLOD: LOD Híbrido para Renderização de Terrenos" -- Strugar (2014). Artigo. Aprimoramento dos geometry clipmaps com adaptação por quadtree. Aloca a resolução com base na complexidade do terreno, em vez de considerar apenas a distância.

"Pipelines de Renderização Orientados por GPU" -- Ubisoft (SIGGRAPH 2015), Wihlidal e Hoppe. Formalizou a abordagem orientada por GPU, na qual compute shaders realizam o culling, a seleção de LOD e a geração de chamadas de desenho. É o padrão arquitetural do nosso pipeline de terrenos com WebGPU.

Geração física de terrenos

"Erosão Analítica Baseada em Física para Geração Rápida de Terrenos" -- Cordonnier et al. (2024). HAL. Erosão analítica baseada na lei da potência de cursos d'água que evita simulação iterativa. Gera terrenos fisicamente plausíveis em milissegundos.

"Simulação e Visualização Rápidas de Erosão Hidráulica na GPU" -- Mei, Decaudin, Hu (2007). HAL. Erosão hidráulica paralelizada na GPU usando simulação de águas rasas. É a base da maioria das implementações de erosão em motores de jogos.

"Arenite: Um Simulador de Arenito Baseado em Física" -- SIGGRAPH 2025. Projeto. Erosão multifísica que gera arcos, chaminés de fada e alcovas a partir da simulação de tensões e erosão. É executada em menos de 5 minutos em GPUs para desktop.

"Simulação Eficiente de Fluxos de Detritos para Erosão de Terrenos Íngremes" -- Purdue CGVLAB (2024). Artigo. Fluxos de detritos e erosão de encostas íngremes acelerados por GPU, produzindo formações realistas de terrenos montanhosos.

"Erosão Flexível de Terrenos" -- IRIT-STORM (2024). Springer. Erosão baseada em partículas que funciona com campos de altura, grades de voxels, superfícies implícitas e materiais em camadas por meio de uma interface unificada. Permite usar um único sistema de erosão para representações híbridas de terreno.

Detalhes e texturização de terrenos

"Mesclagem Laplaciana de Texturas Otimizada para GPU" -- Wronski (NVIDIA, 2025). JCGT. Mesclagem de pirâmides laplacianas em tempo real para materiais de terreno sem pré-processamento. Preserva detalhes acentuados enquanto elimina artefatos nas emendas. Exige apenas algumas amostragens de textura adicionais por fragmento.

"Aprimoramento de Terrenos em Tempo Real com Padrões Procedurais Controlados" -- Grenier et al. (2024). CGF. Detalhes de microerosão baseados em ruído fasorial com resolução até 32 vezes maior que a do mapa de altura. Os padrões alinhados à inclinação são executados inteiramente em um fragment shader.

Tesselação adaptativa

"Árvores Binárias Concorrentes para Componentes de Jogos em Grande Escala" -- Benyoub e Dupuy (Intel, HPG 2024). Artigo. Estrutura de dados de árvore binária otimizada para GPU, destinada à tesselação adaptativa de terrenos. Renderiza geometria em escala planetária em menos de 0,2 ms. Foi ampliada de domínios quadrados para malhas poligonais arbitrárias.

Geração de cavernas e ambientes subterrâneos

"PLUME: Motor de Modelagem Procedural de Camadas Subterrâneas" -- 2024. arXiv:2508.20926. Framework de código aberto para gerar ambientes realistas de cavernas e tubos de lava usando regras procedurais em camadas. Originalmente criado para robótica de exploração espacial.

Síntese neural de terrenos

"InfiniteDiffusion: Unindo Fidelidade Aprendida e Utilidade Procedural para a Geração de Terrenos de Mundo Aberto" -- Goslin (2025, SIGGRAPH 2026). arXiv:2512.08309. Geração de terrenos infinitos e consistentes por seed usando modelos hierárquicos de difusão com codificação laplaciana. É 9 vezes mais rápida que a referência em GPUs de consumo.

"TerraFusion: Geração Conjunta de Geometria e Textura de Terrenos" -- 2025. arXiv:2505.04050. Difusão latente para a síntese simultânea de mapas de altura e texturas, condicionada por esboços.

"MESA: Geração de Terrenos Orientada por Texto" -- Workshop da CVPR 2025. arXiv:2504.07210. Geração de terrenos a partir de texto usando dados de sensoriamento remoto do Copernicus para treinamento.

"Geodiffussr: Texturização Generativa de Terrenos com Fidelidade de Elevação" -- 2025. arXiv:2511.23029. Geração de texturas de terreno orientada por texto que respeita os dados de elevação usando flow matching.

"Sketch2Terrain: Mapeamento de Esboços de Terreno em Tempo Real Orientado por IA" -- 2025. Projeto. Conversão de esboços em terrenos em realidade aumentada. Melhoria de eficiência de 38% em relação ao mapeamento manual.

Simulação de vegetação e ecossistemas

"Distribuição Procedural de Vegetação em Tempo Real Baseada em GPU para Terrenos Virtuais de Grande Escala" -- SBGames 2018. Artigo. Distribuição de vegetação baseada em quadtree usando fatores bióticos e abióticos na GPU.

"Geração Procedural e Renderização de Florestas" -- 2022. Artigo. Geração de árvores com sistemas-L combinada com simulação de competição em ecossistemas para obter uma distribuição florestal realista.

"Geração Procedural em Tempo Real com Work Graphs de GPU" -- AMD GPUOpen 2024. Artigo. Work graphs de GPU que geram mais de 79 mil instâncias de vegetação em menos de 4 ms.

Tecnologia de GPU para navegadores

"Renderizador GSWT" -- SIGGRAPH Asia 2025. GitHub. Renderizador WebGPU + Rust/Wasm que usa Wang Tiles com Gaussian Splatting para criar terrenos 3D infinitos com LOD dinâmico e streaming.

"Computação em GPU no Navegador com Velocidade Nativa: Marching Cubes com WebGPU" -- Usher (2024). Blog. Demonstra que a computação com WebGPU alcança desempenho de velocidade nativa em algoritmos paralelos de geração de malhas.

Renderização de voxels e cenas de grande escala

"Aokana: Um Framework de Renderização de Voxels Orientado por GPU para Jogos de Mundo Aberto" -- 2025. arXiv:2505.02017. DAG esparso de voxels com LOD e streaming para cenas com dezenas de bilhões de voxels. Reduz o uso de memória em 9 vezes e renderiza 4,8 vezes mais rápido que as melhores técnicas anteriores. Projetado para integração com motores de jogos.

Geometria procedural e reconstrução de superfícies

"Reconstrução Procedural de Superfícies em Tempo Real Usando Mesh Shaders de GPU" -- Raad et al. (Eurographics 2025). Artigo. Gera superfícies geométricas detalhadas a partir de malhas de controle simplificadas durante a renderização usando mesh shaders. Permite LOD dinâmico sem armazenar geometria de alta resolução na memória.

Sombras de terrenos

"Otimização de Sombras de Terrenos" -- AMD GPUOpen. Blog. Otimização prática de CSM para terrenos de grande escala. Aborda a divisão de cascatas, a renderização de mapas de sombras eficiente para GPU e otimizações específicas para terrenos.

Geometria virtual e otimização de malhas

"Nanite WebGPU" -- Scthe (2024). GitHub, Demo. Implementação completa no navegador da arquitetura Nanite da UE5: hierarquia de LOD de meshlets, rasterizador por software em WGSL, culling por meshlet e impostores em billboard.

"Bilhões de Triângulos em Minutos" -- Kapoulkine (2025). Blog. Meshoptimizer v1.0 para geração hierárquica de LOD em clusters. Processa com eficiência malhas enormes em DAGs de clusters no estilo Nanite.

"Billboard Splatting (BBSplat)" -- 2024. arXiv:2411.08508. Primitivas planares texturizadas e treináveis para síntese de novas perspectivas, alcançando compressão 17 vezes maior que o Gaussian Splatting 3D.

Iluminação de terrenos e iluminação global

"Iluminação Global em Once Human" -- GDC 2025. Sessão. GI híbrida para um mundo aberto de 16 km: probes compactados por rede neural (proporção de 69:1), resolução de vazamentos entre interiores e exteriores baseada em ML e reações dinâmicas dos probes.

"GI com AMD FidelityFX Brixelizer" -- GDC 2024. Artigo. Cascatas esparsas de campos de distância baseadas em computação, com probes no espaço da tela. Não requer ray tracing por hardware.

"Cascatas de Radiância" -- 2024. Blog. Iluminação global sem ruído em tempo real usando estruturas de radiância em cascata, sem acumulação temporal.

Design de níveis e exploração

"PlotMap: Design Automatizado de Layouts para Criar Mundos de Jogo" -- 2023. arXiv:2309.15242. Posicionamento de pontos de interesse assistido por IA, atendendo a restrições espaciais narrativas no terreno.

"Gatilhos de Exploração Espacial" -- Purdue University (FDG 2022). Artigo. Quatro padrões de design que incentivam a exploração pelos jogadores: pontos extremos, obstruções visuais, objetos fora de contexto e conexões espaciais.

Compactação e streaming de dados

"Compactação Progressiva de Nuvens de Pontos 3D Orientada por Entropia" -- SGP 2024. Artigo. Compactação progressiva otimizada por taxa-distorção, usando particionamento recursivo do espaço com quantização adaptativa. Produz fluxos de refinamento adequados ao streaming em redes com largura de banda variável.

Edição interativa

"Editor de SDF com WebGPU" -- Nijhoff (2026). Projeto. Modelagem SDF completa no navegador, com marching cubes em tempo real, operações booleanas, mesclagem suave e particionamento espacial por octree. 112 bytes por primitiva.

Geração de rios e zonas costeiras

"Bacias de Drenagem Fluvial Procedurais" -- Patel (Red Blob Games). Projeto. Geração de rios que prioriza a drenagem usando a classificação de arestas de malhas de Voronoi/triângulos. Cria hierarquias fluviais antes de atribuir a elevação do terreno.

"NEWTS1.0: Modelo Numérico de Erosão Costeira por Ondas e Escarpas Transgressivas" -- MIT (2024). Artigo. Modelo simplificado de erosão costeira que usa recuo uniforme e erosão provocada por ondas. Gera promontórios, baías, pilares marinhos e arcos compatíveis com a geomorfologia real.

Leitura complementar

Experimente agoraColoque uma paisagem gerada dentro de um jogo

O terreno fica melhor quando você pode caminhar por ele.

Criar de graça →É grátis, roda no seu navegador, nada para instalar.