Como o Unity3D reduz um vértice .obj importado conta?

8

Eu tenho uma pergunta sobre como o Unity3D lida com a importação de arquivos .obj. Estou importando este bule de chá: http://groups.csail.mit.edu/graphics/classes/6.837/F03/models/teapot.obj

O número de vértices que este bule possui é 3644. Eu sei que a classe Mesh do Unity precisa replicar esses vértices para cada face compartilhada pelo mesmo vértice. Eu tentei isso com um cubo importado de um .obj e usando Debug.Log () para imprimir o número de vértices, descobri que havia 24 vértices na matriz de vértices da malha.

No entanto, com o bule de chá, o arquivo original tinha 3644 vértices; portanto, no Unity, a contagem de vértices deve ser 18960. Em vez disso, quando imprimo o comprimento da matriz de vértices da malha, ele imprime 3260 (ainda menos que o arquivo original).

O objetivo final disso é que estou tentando modificar um script de Importador de OBJ do Wiki do Unity, para que o número de vértices resultantes desse script seja o mesmo que o importador nativo do Unity. Referência: http://wiki.unity3d.com/index.php?title=ObjImporter Nota: Imprimi a contagem de vértices usando esse importador e o resultado foi 18960.

Alguém tem uma idéia de como essa redução de vértice pode ser alcançada?

VitorOliveira
fonte
Algoritmos complexos, não tenho certeza do que a unidade usa, mas você pode encontrá-los online.
MickLH

Respostas:

5

Existem vários fatores que contribuem para como a geometria é salva e processada em diferentes mídias (programas, formatos de arquivo, APIs). Eu implementei vários programas de análise de geometria comercial, por isso tenho alguma experiência com isso.

Primeiro, tenho certeza de que isso não tem nada a ver com o Unity, que simplifica qualquer coisa. Mas, caso isso ocorra, existem vários algoritmos de dizimação que podem ser implementados, mas tenho certeza de que não é esse o caso, pois um mecanismo de jogo não deve alterar a forma (propriedades geométricas de uma malha), mas geralmente pode modificar sua conectividade para combinar com sua estrutura ideal.

Alguns desses fatores são:

O que torna um vértice único?

Isso pode variar bastante, dependendo de como o programa, API ou formato de arquivo lida com um vértice. Um vértice pode ser único se tiver uma posição única, mas em outros casos é único se tiver algum atributo exclusivo. Por exemplo, se dois vértices compartilham a mesma posição, mas têm normais diferentes, eles devem ser "duplicados" no caso do OpenGL, isso é especialmente evidente no caso do cubo que você mencionou.

insira a descrição da imagem aqui Bordas duras ou lisas.

As normais podem determinar se uma aresta é considerada rígida ou suave, se um vértice contribui para a aresta rígida, ele precisa ser duplicado para que as APIs de renderização atuais possam entender como renderizar (sombrear) essa face corretamente.

insira a descrição da imagem aqui

Índices

Muitos formatos de arquivo permitem que um vértice de face tenha vários índices para a posição do vértice / texCoords / normals, esse não é o caso das APIs de renderização atuais. Um bom exemplo disso é o arquivo Obj, isso forçará o Unity a reconstruir os índices e, muitas vezes, duplicar muitos atributos para corresponder aos índices de vértices.

Conectividade

Muitos dos vértices que estão realmente conectados e são únicos são salvos várias vezes, isso tem a ver com o modo como o gravador de arquivo original processou e salvou a malha. O Unity reduzirá o número de vértices duplicados (lembre-se de que ele possui um atributo diferente e não é exclusivo), para torná-lo mais eficiente para armazenamento e processamento sem sacrificar a qualidade.

Isso também tem a ver com quantos lados de polígono o arquivo original permite; o Obj, por exemplo, permite polígonos do lado N, algo que qualquer mecanismo de jogo sensato não deseja, por isso acaba triangulando a malha e recalculando muitos de seus atributos que geralmente altere o número de vértices.

concept3d
fonte
Oh, entendi agora! No importador .obj que usei, os vértices são sempre duplicados para cada face em que são usados, e é por isso que sempre encontro arestas duras no meu bule de chá (não o mencionei antes porque pensei que era um problema diferente). Ótima resposta!
VitorOliveira
2

Os formatos Obj são estranhos, em particular porque as posições, normais e coordenadas de textura são separadas e cada face pode escolher qualquer índice de cada fluxo. Quando você se refere à contagem de vértices, pensa que as posições de vértices e contagem de normais não são as mesmas e não pode realmente se referir a toda a contagem.

Durante o carregamento, todos esses três atributos devem ser mesclados para que uma posição de vértice possa terminar duplicada porque a face associada a essa posição de vértice está associada a duas normais . Isso também pode acontecer no sentido inverso, para que a maioria dos carregadores tenha um passo para otimizar o objeto, mas no caso do seu cubo, a otimização não funcionará, pois o cubo possui arestas duras e cada vértice possui uma normal (ou coordenada de textura) diferente. É por isso que você contou 6 posições de vértice, mas a unidade duplicou essas posições, resultando em 24 vértices.

Para carregar uma malha, você pode duplicar posições / normais ou coordenadas de textura, para otimizar isso não é algo simples. Tudo se resume a escolher o número mínimo de duplicatas desses três fluxos.

Raxvan
fonte
Essa resposta foi um ótimo complemento do que concept3d disse e me ajudou a entender esse problema. Portanto, acho que por enquanto meu importador .obj sempre terá arestas rígidas, mas se eu quiser melhorá-lo, devo procurar algoritmos para me ajudar a saber quais vértices devem ser duplicados ou não, para ter um modelo com arestas suaves com o mínimo ( ou pelo menos otimizado) contagem de vértices.
VitorOliveira