Como orientar uma superfície normal para uma superfície cúbica


7

A pergunta imediata é: no HLSL, como posso orientar uma superfície normal gerada no espaço UV para poder aplicá-la a uma face de cubo?

O projeto geral é que estou tentando construir um gerador de planeta procedural. Estou usando um cubo projetado para uma esfera em que cada face é um quad-tree. O projeto intermediário é que eu quero gerar um mapa normal para o terreno. Acho que a melhor maneira de fazer isso (e entender o que estou fazendo) é gerar primeiro os normais para a versão do cubo e depois trabalhar as transformações para deformar esses normais na esfera.

Idealmente, o método não envolveria código de ramificação com base na face em que estou trabalhando (ou seja, se estamos no lado superior do cubo, então U = X e V = Y). Em outras palavras, o que eu estou esperando é um pouco de magia matemática como "Oh, basta cruzar o terreno normal pelo produto escalar do cubo com a face normal e blá blá blá".

20/09/10 ETA:

Eu sei como calcular normais para uma superfície plana. Meu problema subsequente é duplo:

  1. Como eu giro o mapa normal para que ele seja orientado corretamente em cada uma das faces do cubo?
  2. como distorço o mapa normal plano para envolver a esfera?

Encontrei uma solução que usa uma matriz jacobiana, mas não consigo fazê-la funcionar. Mesmo quando todas as normais estão apontando para cima (ou seja, uma superfície plana), o código HLSL envolvendo o jacobiano atrapalha totalmente a iluminação - então isso não me faz confiar na minha implementação da solução.


multiplicar o terreno normal por uma matriz 3x3, diferente para cada face do cubo?
moonshadow

Você não estenderia seu vetor do centro à superfície até que ele atinja o cubo, como em outros tipos de mapeamento de cubos? Ou estou faltando alguma coisa aqui?
Drxzcl 9/09/10

Esta questão não se refere diretamente ao desenvolvimento de jogos, e você provavelmente obteria melhores respostas no Stack Overflow stackoverflow.com
Ricket

Isso se refere a gráficos em tempo real, que é uma grande parte do desenvolvimento do jogo, então eu acho que é relevante.
BigSandwich

São gráficos, ao invés de programação. Então, aqui parece bom. E sombra da lua, Ranieri: Eles não se sairiam melhor como respostas?
The Duck Comunista

Respostas:


3

Suas normais devem estar no espaço tangente, para que você possa aplicá-las em qualquer superfície para a qual possa criar um espaço tangente (trivial para esferas). Basicamente, o mapa normal descreve como o normal difere do normal real em um pequeno pedaço no superfície. O espaço tangente é o que você provavelmente tenta obter com sua matriz jacobiana - para uma esfera, você pode criar um sistema de coordenadas do espaço tangente em qualquer ponto, usando o normal no ponto e dois vetores perpendiculares - apenas oriente-os consistentemente ( por exemplo, ao longo de você ev) e pronto. Você pode então converter seu vetor de luz recebido no espaço tangente (ou vice-versa) e iluminar com o novo normal. A vantagem é que seu mapa normal funcionará em qualquer objeto com um espaço tangente definido e mapeamento UV.

No cubo, seu espaço tangente para cada face é simplesmente o próprio rosto (ou seja, se você tem uma face com um -Z normal, por exemplo, e seu espaço tangente acima é + Y, basta girar esse normal usando uma matriz que mapeia -Z a + Y.)


Tenho uma vaga noção do que é o espaço tangente, mas não sei como seguir seu conselho e fazer qualquer coisa com ele. Mas isso provavelmente é inteiramente minha culpa. Quanto ao segundo parágrafo - eu estava tentando evitar o código de ramificação no HLSL, porque meu entendimento amador diz que o código de ramificação é uma coisa muito ruim no HLSL. Embora pareça inevitável.
Klay

Não há ramificação: suponho que você tenha um cubo com um mapa normal em cada uma das faces. Agora você basicamente desdobra esse cubo em uma esfera ... a coisa mais fácil que você pode fazer é colocar uma esfera dentro do seu cubo e traçar raios contra o cubo e dobrar o normal então. Supondo que sua frequência normal seja uniforme em uma superfície esférica (isto é, não uniforme em uma superfície de cubo), isso deve fornecer um mapa normal pronto para uso para uma esfera. Embora eu ainda não entenda por que você tem esse cubo? Você não pode trabalhar uma esfera imediatamente?
Anteru 2/11/10

A razão pela qual estou usando o mapa de cubos é porque é muito mais fácil fazer a renderização em nível de detalhe com seis quadríceps subsequentemente mapeados para uma esfera do que fazer cálculos LOD na própria superfície da esfera.
Klay

Além disso, a parte da sua resposta em que você diz "apenas oriente-os consistentemente" pode ser o cerne do problema. Não sei como orientar minhas coordenadas uv de forma consistente nas seis faces do cubo sem recorrer a algo como [se cubeFace == top, então u = x e v = z ...] etc., o que leva à ramificação I ' estou falando. mas apesar de tudo, ainda não consigo visualizar o processo geral. Desculpe por ser tão densa.
Klay

0

"Eu sei como calcular valores normais para uma superfície plana." Exatamente como você está fazendo isso? Tanto quanto eu sei, você não deveria ter que fazer nada para mapeá-lo para uma esfera que não seja mapear corretamente seus UVs para a superfície da esfera. Os mapas normais estão sempre em um plano "plano" porque a textura em si é "plana". A forma do objeto ao qual você aplica o mapa normal não deve importar.


O algoritmo mostra os pontos circundantes e multiplica cruzadas (ou é o produto escalar?) As inclinações para obter o vetor perpendicular às inclinações. Pelo menos, essa é minha vaga lembrança - estou no trabalho e não posso verificar isso no caixa eletrônico.
Klay

Além disso, se eu entendi direito, parece que preciso "inserir" a curvatura da esfera no próprio mapa normal para que a iluminação esteja correta. Mais uma vez, peço desculpas por ser tão densa, mas algum tipo de diagrama e / ou pseudocódigo pode ajudar.
Klay
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.