Unity Spain

Post Antiguos => General (Antiguo) => Mensaje iniciado por: Jose134 en Agosto 30, 2017, 09:20:51 PM

Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: Jose134 en Agosto 30, 2017, 09:20:51 PM
Hola a todos, tengo un codigo que genera varios meshes pero me ha surgido un problema y es que algunas caras miran en la direccion incorrecta y por tanto solo se ven si te situas dentro del mesh.
 
Creia que el problema estaba en las normales pero tras arreglarlas sigue ocurriendo, tambien he leido que puede ser por el orden en el que se definen los vertices de los triangulos pero tras varios intentos me siguen dando problemas.
 
Les dejo algunas imagenes y el codigo.
 
(Rosa = normals; Verde = edges (solo estan representados los que estan a la altura del suelo); Negro = vertices)
 

 
 
 
Calculo de vertices y normales
 

//Generates the vertices and the normals
var vertices = new Vector3[sector.Count * 2];
var normals = new Vector3[vertices.Length];
for (int i = ; i < sector.Count; i += 2)
{
//Calculates the vertices of a whole face
     vertices[i * 2]     = new Vector3(sector[i].x, , sector[i].y);
    vertices[i * 2 + 1] = new Vector3(sector[i + 1].x, , sector[i + 1].y);
    vertices[i * 2 + 2] = new Vector3(sector[i].x, 10, sector[i].y);
    vertices[i * 2 + 3] = new Vector3(sector[i + 1].x, 10, sector[i + 1].y);
    //Takes calculated vertices to make an edge of the mesh's face
    var a = vertices[i * 2];
    var b = vertices[i * 2 + 1];
    var ab = b - a;
    //Calculate the two possible normals for the face
    var n1 = new Vector3(-ab.z, ab.y, ab.x);
    var n2 = new Vector3(ab.z, ab.y, -ab.x);
    n1.Normalize();
    n2.Normalize();
    //Calculates the distance from the Vertice + Normal Vector to the sector defining point
    var d1 = Vector3.Distance(a + n1, new Vector3(point.x, , point.y));
    var d2 = Vector3.Distance(a + n2, new Vector3(point.x, , point.y));
    //Chose which normal to use in function of the distances
    var n = d1 > d2 ? n1 : n2;
    //Sets the calculated normal
    normals[i * 2] =     n;
    normals[i * 2 + 1] = n;
    normals[i * 2 + 2] = n;
    normals[i * 2 + 3] = n;
}

 
 
 
Calculo de tris
 

//Calculates the triangles
var triangles = new int[vertices.Length / 4 * 6];
for (int i = ; i < vertices.Length; i += 4)
{
triangles[i / 4 * 6]     = i + 3;
    triangles[i / 4 * 6 + 1] = i + 1;
    triangles[i / 4 * 6 + 2] = i;
    triangles[i / 4 * 6 + 3] = i + 3;
    triangles[i / 4 * 6 + 4] = i;
    triangles[i / 4 * 6 + 5] = i + 2;
}

 
 
 
Alguna idea de por que ocurre esto? Como lo podria arreglar?
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: lightbug en Agosto 30, 2017, 09:58:13 PM
Cita de: Jose134 date=1504120851Alguna idea de por que ocurre esto? Como lo podria arreglar?
   


EN teoria y de lo que recuerdo de lo que hice de ."obj" las normales son otra cosa y no depende de los vertices ni de los indices (o triangulos como llama Unity), es decir que si invertis las normales de tu codigo todo se da vuelta? hace un -n para ver que pasa.
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: Jose134 en Agosto 30, 2017, 10:11:23 PM
Cita de: lightbug date=1504123093EN teoria y de lo que recuerdo de lo que hice de ."obj" las normales son otra cosa y no depende de los vertices ni de los indices (o triangulos como llama Unity), es decir que si invertis las normales de tu codigo todo se da vuelta? hace un -n para ver que pasa.
   


no puedo comprobar que las caras salgan exactamente invertidas al usar -n ya que los meshes son mas o menos aleatorios y cambian cada vez que ejecuto el programa pero he probado y creo que no influye. La mayoria de las caras se pueden ver si miras hacia el eje Z positivo y apenas se ve ninguna cuando miras desde atras y esto no cambia al usar -n por lo que supongo que no influye en la direccion de las caras.
 
 
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: juguefre en Agosto 30, 2017, 10:13:29 PM
La solución rápida es hacer los poligonos double sided, así se ven desde ambos lados.
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: Jose134 en Agosto 30, 2017, 10:20:53 PM
Cita de: juguefre date=1504124009hacer los poligonos double sided, así se ven desde ambos lados.
   




Podrias explicar como hacerlo por favor? tiene unity algun metodo que haga esto automaticamente? y en caso de que no lo tenga, como lo podria programar yo mismo?
 
 
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: lightbug en Agosto 30, 2017, 10:22:24 PM
Cita de: juguefre date=1504124009La solución rápida es hacer los poligonos double sided, así se ven desde ambos lados.
   


Si es una solucion, aunque tambien se renderizan de los dos lados, no se ti se sale gratis la verdad, pero si no importa esta perfecta. Lo feo de esto cuando te acostumbras a usar los poligonos "single" sided (se dice asi?) es que es mas facil de trabajar en la escena que un doble sided sobre todo si son lugares o pasillos pequeños.
 
Cita de: Jose134 date=1504124453Podrias explicar como hacerlo por favor? tiene unity algun metodo que haga esto automaticamente? y en caso de que no lo tengo, como lo podria programar yo mismo?
   


creo que en el meshRenderer dice la opcion doubleSided
 
 
 
Cita de: Jose134 date=1504123883no puedo comprobar que las caras salgan exactamente invertidas al usar -n ya que los meshes son mas o menos aleatorios y cambian cada vez que ejecuto el programa pero he probado y creo que no influye. La mayoria de las caras se pueden ver si miras hacia el eje Z positivo y apenas se ve ninguna cuando miras desde atras y esto no cambia al usar -n por lo que supongo que no influye en la direccion de las caras.
   


Si invertir el "n" no influye como es que lo sabes si es todo aleatorio? (muy raro pense que esto era determinante) Si queres estar totalmente seguro hace un triangulo, version n y version -n, solo para estar seguro. Otra es invertir los triangulos, el orden con el que los formas.
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: Jose134 en Agosto 30, 2017, 11:10:08 PM
Cita de: lightbug date=1504124544creo que en el meshRenderer dice la opcion doubleSided
   


No veo esa opcion pero ahora investigare un poco mas sobre lo del doubleSided
 
Cita de: lightbug date=1504124544Si invertir el "n" no influye como es que lo sabes si es todo aleatorio? (muy raro pense que esto era determinante) Si queres estar totalmente seguro hace un triangulo, version n y version -n, solo para estar seguro. Otra es invertir los triangulos, el orden con el que los formas.
   


No es 100% aleatorio, las lineas verdes que se veian en las imagenes eran sectores achicados de un diagrama de voronoi, a partir de ahi queria hacer un mesh que formara las paredes de esos sectores. Lo que es aleatorio son los puntos que definen el diagrama de voronoi y por tanto la posicion de los vertices en los ejes X y Z (en el eje Y siempre es 0 o 10)
 
 
 
He hecho pruebas generando varios meshes de triangulos y parece que lo que afecta son los triangulos del mesh, los que hice definiendo los vertices en el sentido de las agujas del reloj se ven desde delante y los que hice en sentido contrario desde atras. En el caso de las normales afectaron a la iluminacion, los que usan Vector3.forward se ven mas oscuros que los que usan -Vector3.forward
 

 
 
 
Supongo que la siguiente pregunta es como determino el orden de los vertices en los triangulos para que cada cara mire hacia donde debe?
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: juguefre en Agosto 30, 2017, 11:11:41 PM
Cita de: lightbug date=1504124544no se ti se sale gratis la verdad
   


No es gratis pero es una solución rápida, y luego puede buscar una solución mas optima aunque dado la naturaleza "random" del mesh yo creo que le toca quedarse con double sided.
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: Braltor en Agosto 31, 2017, 01:41:30 AM
puedes revisar triangulo x triangulo en el array del mesh y calcular la normal: https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal (https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal)
 
si no esta en la misma direccion q las otras le das vuelta al orden de los vertices
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: lightbug en Agosto 31, 2017, 03:06:00 AM
Cita de: juguefre date=1504127501No es gratis pero es una solución rápida, y luego puede buscar una solución mas optima aunque dado la naturaleza "random" del mesh yo creo que le toca quedarse con double sided.
   


SI estaba pensando lo mismo, si fuera una malla conocida podes hacerlo pero como hay cosas Random, podrias tambien pero es un quilombo. Seguramente el DoubleSided sea lo mejor.
 
Cita de: Jose134 date=1504127408las lineas verdes que se veian en las imagenes eran sectores achicados de un diagrama de voronoi
   


Guat is dat?
 
(https://media.giphy.com/media/SDxzM5LAVq5Tq/giphy.gif)
 
 
 
EDIT: Me confundi, lo de doubleSided era el castShadow del meshRenderer, si queres doubleSided vas a tener que emplear algun shader, estoy seguro de que hay miles por ahi, incluso en el assetStore o quien dice ya Built-in en Unity
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: leocub58 en Agosto 31, 2017, 06:42:40 PM
Cita de: lightbug date=1504141560EDIT: Me confundi, lo de doubleSided era el castShadow del meshRenderer, si queres doubleSided vas a tener que emplear algun shader, estoy seguro de que hay miles por ahi, incluso en el assetStore o quien dice ya Built-in en Unity
   


https://forum.unity3d.com/threads/double-sided-material.21778/ (https://forum.unity3d.com/threads/double-sided-material.21778/)
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: juguefre en Agosto 31, 2017, 10:59:23 PM
Cita de: Jose134 date=1504124453Podrias explicar como hacerlo por favor? tiene unity algun metodo que haga esto automaticamente? y en caso de que no lo tenga, como lo podria programar yo mismo?
   
   
       
   


Creo que seria muy útil en tu caso que generaras 2 polígonos usando tus 3 vértices, cada uno en dirección opuesta al otro.
 
El punto es que el double sided calcula el polígono 2 veces, básicamente cuenta cada polígono como si fuera 2 polígonos, siendo así y como tu mesh es generado automáticamente mejor usas doble polígono en lugar de double sided shader, la ventaja es que cada uno de tus polígonos usara su propia normal y la iluminación de cada polígono sera "correcta", el impacto en rendimiento es el mismo y lo puedes hacer desde tu script.

 
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: lightbug en Septiembre 01, 2017, 12:34:48 AM
Cita de: juguefre date=1504213163Creo que seria muy útil en tu caso que generaras 2 polígonos usando tus 3 vértices, cada uno en dirección opuesta al otro.
   
   
      El punto es que el double sided calcula el polígono 2 veces, básicamente cuenta cada polígono como si fuera 2 polígonos, siendo así y como tu mesh es generado automáticamente mejor usas doble polígono en lugar de double sided shader, la ventaja es que cada uno de tus polígonos usara su propia normal y la iluminación de cada polígono sera "correcta", el impacto en rendimiento es el mismo y lo puedes hacer desde tu script.

       
   


Asi lo hace sketchup por ej, cuando le das que exporte double sided lo que hace te duplica todo. Igual cuando tenes un shader soble sided no tenes ese problema con la iluminacion, el resultado final es identico, mira (luz celeste ilumina las caras que salen con cualquier shader, luz roja las caras a duplicar):
 

 
-> Se ven diferentes iluminados (sobretodo el del shader) porque olvide de setear los mismos parametros de los dos , pero al final son iguales (o pueden serlo mejor dicho).
 
La razon por la que seguiria usando el mesh doble vs el shader es porque podes tener el shader que quieras, cuando haces el doble de la maya lo seguis teniendo, con el shader (en este caso descargué uno por free del asset store ,identico al standard de Unity) estas limitado al tipo que sea (si es que tenes algunos nada mas version two-sided), en el asset store no estaban todos version two-sided, aunque si sabes de shaders los podes copiar y hacerlos doble sided, pero ya no tiene sentido hacerlos todos asi.
 
La desventaja que se me ocurre de duplicar el mesh es que tenes el doble de indices, no tanto por el tema de memoria hoy en dia no es mucho drama, pero si un arreglo mas grande que pasar de CPU a GPU (si no fuera estico el mesh), mientras que el shader lo calcula todo (los nuevos indices duplicados) en el mismo GPU, esto habria que medirlo bien pero estoy seguro que para grandes mesh de millones de triangulos se nota una diferencia y muy notable, no diria que "el impacto en el rendimiento es el mismo". Aunque si la mesh es estatica no hay ningun problema de rendimiento, quizas de memoria. (hablando de un caso exagerado)
 
Es decir que ambos tienen lo suyo, igual por practicidad me quedo con el mesh doble toda la vida, pero esta clarisimo que lo mejor es setear bien las normales/triangulos y olvidarse de todo lo doble Sided, pero bueno si no queda otra... hasta yo por vago exporto todo dobleSided, ni da para setear en sketchup las normales
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: juguefre en Septiembre 01, 2017, 01:34:28 AM
@lightbug
 
La diferencia entre doble sided shader y doble mesh es la iluminación.
 
Imagina una pared creada con un solo polígono que usa double sided shader, la pared separa una habitación y un pasillo, en el pasillo hay una luz tenue pero en la habitación no hay ninguna luz, ahora dependiendo de hacia donde este orientada la normal del polígono sera la iluminación.
 
Si la normal esta hacia la habitación el polígono sera oscuro (no hay luz en el cuarto).
 
Si la normal esta hacia el pasillo el polígono estará iluminado.
 
Hasta aquí todo perfecto PERO la iluminación sera la misma para ambos lados. Resultando en esto:
 
Si la normal esta hacia la habitación los DOS lados del polígono serán oscuros sin importar que haya una luz en el pasillo.
 
Si la normal esta hacia el pasillo los DOS lados del polígono estarán iluminados sin importar que en la habitación no haya luz.
 
Esto es por que el shader usa una sola normal para calcular la luz en ambos lados del polígono.
 
Con doble mesh tienes 1 normal cada polígono y el calculo de la luz es mas preciso resultando en el lado de la habitación siendo oscuro mientras el lado del pasillo es iluminado (como se supone que debería ser).
 
Es obvio que la misma solución no se puede aplicar a múltiples casos diferentes. Se pueden presentar casos donde double shaded es la solución apropiada en lugar de double mesh.
 
 
 
 
 
 
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: lightbug en Septiembre 01, 2017, 02:27:18 AM
Cita de: juguefre date=1504222468Hasta aquí todo perfecto PERO la iluminación sera la misma para ambos lados.
   


Justamente eso lo probe, puse una sola luz de un lado y mire ambos y responden correctamente, no pasa lo que decis, tambien para la luz en el otro lado, ya que el shader (este en particular) usa otras normales(invertidas quizas) y no comparte la misma.
 
Si tenes dudas probalo vos mismo:
 
https://www.assetstore.unity3d.com/en/#!/content/23087 (https://www.assetstore.unity3d.com/en/#!/content/23087)
 
Cita de: juguefre date=1504222468Esto es por que el shader usa una sola normal para calcular la luz en ambos lados del polígono.
   
   
      Con doble mesh tienes 1 normal cada polígono y el calculo de la luz es mas preciso resultando en el lado de la habitación siendo oscuro mientras el lado del pasillo es iluminado (como se supone que debería ser).
   


Eso dependera sola y exclusivamente de como esté hecho el shader double-sided, yo he hecho manualmente con glsl un doble-sided y es totalmente posible y amigable con las luces, podes hacerlo de la manera que decis, compartiendo normales, o invertirlas para el "lado doble" (como deberia ser), dependerá solo del shader, no de si es single sided o double sided.
 
 
 
Cita de: juguefre date=1504222468Es obvio que la misma solución no se puede aplicar a múltiples casos diferentes. Se pueden presentar casos donde double shaded es la solución apropiada en lugar de double mesh.
   


Si por supuesto, toda comparacion tiene un punto de inflexión.
 
 
 
EDIT: Si lo probas fijate que hay algo raro con las normales, como el normal map las modifica cuando le das mucho "Normal Intensity" del otro lado parece que pasa algo de luz, pero en si no debería (no pasa si no tenes normal map) ...  un punto mas a favor de doble mesh.
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: juguefre en Septiembre 01, 2017, 04:40:49 AM
@lightbug apenas tenga un tiempo libre lo reviso a fondo, no seria raro que ahora funcione así como dices pero en "mis tiempos" funcionaba tal como lo describí jajaja
Título: Caras de mesh generado miran en dirección incorrecta
Publicado por: lightbug en Septiembre 01, 2017, 11:41:46 PM
Cita de: juguefre date=1504233649@lightbug apenas tenga un tiempo libre lo reviso a fondo, no seria raro que ahora funcione así como dices pero en "mis tiempos" funcionaba tal como lo describí jajaja
   


Si tal cual a mi siempre me parecio que funcionaba asi por eso nunca le preste mucha atencion a los shaders estos, pense que venian fallados de movida , igual tiene ese problemita con la normal y la luz que parece que pasa al otro lado, y ni hablar de que si tenes una pared muy finita (una sola cara) iluminada el mismo Bias de la luz hace que pase al otro lado. Yo los usaria si fuera una cortina o una bandera, para cosas asi son barbaros.