Estou criando uma malha processual baseada em uma curva e o tamanho da malha fica menor ao longo da curva, como você vê abaixo.
E o problema é que a UV fica em zigue-zague quando o tamanho muda (funciona perfeitamente quando o tamanho da malha é o mesmo em toda a curva).
Vertices.Add(R);
Vertices.Add(L);
UVs.Add(new Vector2(0f, (float)id / count));
UVs.Add(new Vector2(1f, (float)id / count));
start = Vertices.Count - 4;
Triangles.Add(start + 0);
Triangles.Add(start + 2);
Triangles.Add(start + 1);
Triangles.Add(start + 1);
Triangles.Add(start + 2);
Triangles.Add(start + 3);
mesh.vertices = Vertices.ToArray();
//mesh.normals = normales;
mesh.uv = UVs.ToArray();
mesh.triangles = Triangles.ToArray();
Como posso consertar isso?
unity
procedural-generation
mesh
uv-mapping
fkkcloud
fonte
fonte
id
ecount
? O queUVs.ToArray()
faz? Como você está carregando os vértices e as coordenadas de textura no cartão?id
é o índice do segmento atual de todas as barras transversais ao longo da faixa, de onde existemcount
no total.List<T>.ToArray()
retorna uma matriz digitada de todas as entradas na lista (então aqui, aVector2[]
). Esses buffers de dados são disponibilizados para o sistema de renderização, atribuindo-os àMesh
instânciamesh
nas últimas linhas. Mas nada disso é a parte particularmente interessante do código: como os pontos de vértice são escolhidos. Esses detalhes seriam mais úteis para ver. ;)count
realmente significava vértices em vez de polígonos, ou vice-versa. Apenas garantir que tudo o que pensamos esteja acontecendo realmente está acontecendo.Respostas:
O mapeamento UV típico é chamado de transformação afim . Isso significa que o mapeamento de cada triângulo entre o espaço 3D e o espaço da textura pode incluir rotação, tradução, redimensionamento / squash e inclinação (ou seja, qualquer coisa que possamos fazer com uma multiplicação de matriz homogênea)
A questão das transformações afins é que elas são uniformes em todo o domínio - a rotação, a translação, a escala e a inclinação que aplicamos à textura perto do vértice A é a mesma que aplicamos perto do vértice B, dentro de qualquer triângulo. Linhas paralelas em um espaço serão mapeadas para linhas paralelas no outro, nunca convergindo / divergindo.
Mas o afilamento gradual que você está tentando aplicar não é uniforme - ele está mapeando linhas paralelas na textura para linhas convergentes na malha. Isso significa que a escala da textura medida na banda está mudando continuamente à medida que avançamos na faixa. Isso é mais do que as transformações afins do mapeamento UV 2D podem representar com precisão: a interpolação de coordenadas uv 2D entre vértices adjacentes obterá uma escala consistente ao longo de toda a borda, até a borda diagonal que deve estar diminuindo de escala à medida que se move pela faixa. Essa incompatibilidade é o que cria esse ziguezague de guerra.
Esse problema surge a qualquer momento que queremos mapear um retângulo para um trapézio - lados paralelos para lados convergentes: simplesmente não há transformação afim que faz isso, por isso temos que aproximá-lo por partes, levando a costuras visíveis.
Para a maioria dos propósitos, você pode minimizar o efeito adicionando mais geometria. Aumentar o número de subdivisões ao longo do comprimento da faixa e dividi-la em dois ou mais segmentos ao longo de sua largura, com as diagonais dos triângulos dispostos em um padrão de espinha de peixe, pode tornar o efeito muito menos perceptível. Ele sempre estará presente até certo ponto, enquanto estivermos usando transformações afins.
Mas há uma maneira de contornar isso. Podemos usar o mesmo truque que usamos na renderização 3D para desenhar trapézios em perspectiva, dadas paredes e pisos retangulares: usamos coordenadas projetivas !
Texturas afins:
Texturização projetiva:
Para fazer isso, precisamos adicionar uma terceira coordenada uv (uvw) e modificar nossos shaders.
Dado um fator de escala em cada ponto (digamos, igual à largura da sua faixa nesse ponto), você pode construir a coordenada uvw projetiva em 3D a partir da coordenada uv 2D 2D normal da seguinte maneira:
Para aplicar essas coordenadas uvw 3D à sua malha, você precisará usar a sobrecarga Vector3 Mesh.SetUVs (int channel, List uvs)
E certifique-se de alterar a estrutura de entrada do seu sombreador para esperar uma coordenada de textura 3D (mostrada aqui usando o sombreador apagado padrão):
Você também precisará recortar a macro TRANSFORM_TEX no sombreador de vértices, pois espera um uv 2D:
Por fim, para retornar a uma coordenada de textura 2D para amostragem de textura, basta dividir pela terceira coordenada no seu shader de fragmento :
Como fizemos essa coordenada uvw 3D a partir da coordenada 2D desejada multiplicando pelo mesmo número, as duas operações cancelam e voltamos à coordenada 2D desejada original, mas agora com interpolação não linear entre os vértices. : D
É importante fazer essa divisão por fragmento e não no shader de vértice. Se for feito por vértice, voltaremos a interpolar linearmente as coordenadas resultantes ao longo de cada aresta e perdemos a não linearidade que estávamos tentando introduzir com a coordenada projetiva!
fonte