Estoy creando una malla de procedimiento basada en una curva y el tamaño de la malla se hace más pequeño a lo largo de la curva, como puede ver a continuación.
Y el problema es que el UV se zigzaguea a medida que cambia el tamaño (funciona perfectamente cuando el tamaño de la malla es el mismo en toda la 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();
¿Cómo puedo arreglar esto?
unity
procedural-generation
mesh
uv-mapping
fkkcloud
fuente
fuente
id
ycount
? ¿QuéUVs.ToArray()
hacer? ¿Cómo carga los vértices y las coordenadas de textura en la tarjeta?id
es el índice del segmento actual de todas las barras transversales a lo largo de la tira, de donde haycount
en total.List<T>.ToArray()
devuelve una matriz escrita de todas las entradas en la lista (así que aquí, aVector2[]
) Estos almacenamientos intermedios de datos se ponen a disposición del sistema de representación asignándolos a laMesh
instanciamesh
en las últimas líneas. Pero nada de esto es la parte particularmente interesante del código: cómo se eligen los puntos de vértice. Esos detalles serían más útiles para ver. ;)count
realidad significaba vértices en lugar de polígonos, o viceversa. Solo asegurarme de que todo lo que creemos que está sucediendo realmente está sucediendo.Respuestas:
El mapeo UV típico es lo que se llama una transformación afín . Eso significa que el mapeo de cada triángulo entre el espacio 3D y el espacio de textura puede incluir rotación, traslación, escala / aplastamiento y sesgo (es decir, cualquier cosa que podamos hacer con una multiplicación de matriz homogénea)
Lo que pasa con las transformaciones afines es que son uniformes en todo su dominio: la rotación, la traslación, la escala y la inclinación que aplicamos a la textura cerca del vértice A es la misma que aplicamos cerca del vértice B, dentro de cualquier triángulo. Las líneas que son paralelas en un espacio se asignarán a líneas paralelas en el otro, nunca convergentes / divergentes.
Pero la reducción gradual que está tratando de aplicar no es uniforme: está mapeando líneas paralelas en la textura a líneas convergentes en la malla. Eso significa que la escala de la textura medida a través de la banda está cambiando continuamente a medida que avanzamos por la franja. Eso es más de lo que las transformaciones afines del mapeo UV 2D pueden representar con precisión: la interpolación de coordenadas uv 2D entre vértices adyacentes obtendrá una escala consistente a lo largo de todo el borde, incluso el borde diagonal que debería reducirse a medida que avanza por la franja. Esa falta de coincidencia es lo que crea este zigzag chirriante.
Este problema surge cada vez que queremos mapear un rectángulo a un trapecio: lados paralelos a lados convergentes: simplemente no hay transformación afín que haga esto, por lo que tenemos que aproximarlo por partes, lo que lleva a costuras visibles.
Para la mayoría de los propósitos, puede minimizar el efecto agregando más geometría. Aumentar el número de subdivisiones a lo largo de la tira y dividir la tira en dos o más segmentos a lo largo de su ancho, con las diagonales de los triángulos dispuestos en un patrón de espiga, puede hacer que el efecto sea mucho menos notable. Sin embargo, siempre estará presente en cierta medida siempre que estemos usando transformaciones afines.
Pero hay una forma de evitarlo. Podemos usar el mismo truco que usamos para el renderizado 3D para dibujar trapecios en perspectiva dados los muros y pisos rectangulares: ¡usamos coordenadas proyectivas !
Texturas afines:
Texturas proyectivas:
Para hacer esto, necesitamos agregar una tercera coordenada uv (uvw) y modificar nuestros sombreadores.
Dado un factor de escala en cada punto (digamos, igual a la amplitud de su tira en ese punto), puede construir la coordenada uvw proyectiva 3D a partir de su coordenada uv 2D normal de esta manera:
Para aplicar estas coordenadas 3D uvw a su malla, necesitará usar Mesh.SetUVs de sobrecarga de Vector3 (int channel, List uvs)
Y asegúrese de cambiar la estructura de entrada de su sombreador para esperar una coordenada de textura 3D (que se muestra aquí usando el sombreador apagado predeterminado):
También deberá cortar la macro TRANSFORM_TEX en el sombreador de vértices, ya que espera un uv 2D:
Finalmente, para volver a una coordenada de textura 2D para el muestreo de textura, simplemente divida por la tercera coordenada en su sombreador de fragmentos :
Como hicimos esta coordenada uvw 3D a partir de nuestra coordenada 2D deseada multiplicando por el mismo número, las dos operaciones se cancelan y volvemos a nuestra coordenada 2D original deseada, pero ahora con interpolación no lineal entre los vértices. :RE
Es importante hacer esta división por fragmento y no en el sombreador de vértices. Si se hace por vértice, entonces volvemos a interpolar las coordenadas resultantes linealmente a lo largo de cada borde, ¡y hemos perdido la no linealidad que estábamos tratando de introducir con la coordenada proyectiva!
fuente