Pular para o conteúdo
Materiais · TécnicaIntermediário

Mapeamento triplanar

Texturizar uma malha sem UVs projetando a textura ao longo dos três eixos do mundo e misturando pela normal.

PosiçãoNormalTexturaSuperfície

Cards

Um exemplo ao vivo para ajustar, aprender e copiar.

Como funciona

Uma textura precisa de coordenadas, e normalmente a malha as traz: UVs, desdobradas à mão. Algumas geometrias não têm UVs que prestem. Terreno procedural, cavernas de voxels e rochas esculpidas mudam de forma demais para serem desdobradas, e um penhasco desdobrado uma vez ainda estica a textura onde quer que uma face fique íngreme. O mapeamento triplanar tira as coordenadas da posição.

Três projeções

O jeito mais simples de texturizar pela posição é descartar um eixo: texture(t, p.xz) pinta a textura de cima para baixo no chão, como um projetor de slides acima da cena. Isso fica certo no chão plano e horrível num penhasco, onde o mesmo texel escorre pela face vertical inteira, porque a face está quase paralela à projeção.

O triplanar faz isso três vezes, uma ao longo de cada eixo: p.zy para as faces que olham ao longo de x, p.xz para as que olham para cima ou para baixo, p.xy para as que olham ao longo de z. Cada projeção fica nítida exatamente onde as outras escorrem. A normal da superfície diz em qual confiar: uma face cuja normal aponta quase toda para cima fica com a projeção de cima, uma parede virada para x fica com a projeção de x, e uma encosta no meio do caminho mistura as duas.

Os pesos

Os pesos da mistura vêm dos componentes da normal. abs(normal) mede quanto a face olha ao longo de cada eixo, seja qual for o lado para onde ela está virada. Dois ajustes tornam isso usável:

  • Afiar. Os componentes crus fazem a transição numa faixa larga, e ali duas imagens diferentes se sobrepõem como uma dupla exposição borrada. Elevá-los a uma potência estreita a faixa; de 4 a 8 é o comum, e acima disso a costura vira uma linha visível.
  • Normalizar. Divida pela soma para os pesos somarem 1. A normal é um vetor unitário, mas os componentes dela não somam 1 (a 45°, dois deles valem 0,71 cada), então sem isso a mistura fica mais clara nos cantos e nas arestas.

O que custa e o que quebra

Três leituras de textura em vez de uma, para cada textura do material: um material triplanar com mapas de cor, normal e rugosidade faz nove leituras. As coordenadas vêm da posição, então o espaço de coordenadas importa. Em espaço de mundo, as texturas se alinham entre objetos separados e nunca esticam quando um objeto é escalado, mas escorregam quando o objeto se move. Em espaço de objeto, elas se movem junto com ele, mas se repetem de um jeito diferente em cada cópia escalada. Faces opostas dividem a mesma projeção, então uma das duas vê a textura espelhada, o que some na rocha mas aparece em texto e tijolos.

Mapas de normal pedem mais cuidado que a cor. Cada projeção tem o seu próprio referencial tangente, então a normal amostrada precisa ser levada para espaço de mundo em cada projeção antes de as três serem misturadas, e não misturada antes. O mapeamento biplanar de Inigo Quilez reduz as leituras para duas, ficando só com os dois maiores pesos, em troca de um pouco mais de aritmética.

As engines já trazem isso pronto. O StandardMaterial3D do Godot tem uma opção Triplanar para cada canal de UV, em espaço de objeto a menos que World Triplanar esteja ligado, e o VisualShader tem um nó TextureParameterTriplanar. O nó Image Texture do Blender faz isso como projeção Box, com um valor Blend que é a mesma largura de transição. Escrever à mão é o que permite mudar a mistura, usar texturas diferentes por eixo (musgo nas faces de cima, rocha nua nos lados) ou cair para duas leituras.

Leitura complementar