Tengo una clase que genera una forma 3D basada en las entradas del código de llamada. Las entradas son cosas como longitud, profundidad, arco, etc. Mi código genera la geometría perfectamente, sin embargo, me encuentro con problemas al calcular las normales de superficie. Cuando está iluminado, mi forma tiene una coloración / textura muy extraña de las normales de superficie incorrectas que se están calculando. De toda mi investigación, creo que mis matemáticas son correctas, parece que algo está mal con mi técnica o método.
En un nivel alto, ¿cómo se hace para calcular mediante programación las normales de superficie para una forma generada? Estoy usando Swift / SceneKit en iOS para mi código, pero una respuesta genérica está bien.
Tengo dos matrices que representan mi forma. Uno es una matriz de puntos 3D que representa los vértices que componen la forma. La otra matriz es una lista de índices de la primera matriz que mapea los vértices en triángulos. Necesito tomar esos datos y generar una tercera matriz que es un conjunto de normales de superficie que ayudan a iluminar la forma. (ver SCNGeometrySourceSemanticNormal
en SceneKit` )
La lista de vértices e índices siempre es diferente dependiendo de las entradas a la clase, por lo que no puedo calcular previamente ni codificar las normales de la superficie.
Respuestas:
Simplemente no quieres resultados totalmente suaves. Si bien el método comentado por Nathan Reed: "Calcular cada vértice para que se vea normal, sumarlos, normalizar suma", generalmente funciona, a veces falla espectacularmente. Pero eso no tiene importancia aquí, podemos usar ese método agregándole una cláusula de rechazo.
En este caso, simplemente desea que ciertas partes no se suavicen contra otras partes. Quieres bordes duros selectivos. Entonces, por ejemplo, la parte superior y la parte inferior planas están separadas de la banda triangular en el costado, al igual que cada área plana.
Imagen 1 : El resultado que deseas.
En efecto, solo desea promediar los vértices del área curva, todos los demás pueden usar lo normal que obtienen solo de su triángulo. Por lo tanto, es mejor pensar en la malla como 9 regiones separadas que se manejan sin las otras.
Imagen 2 : Imagen que muestra la estructura de malla y las normales.
Ciertamente puede deducir esto automáticamente al no incluir las normales que están fuera de cierto ángulo de los vértices primarios normales. Pseudocódigo:
Eso funciona, pero puedes evitar todo esto en el momento de la creación porque entiendes que los planos separados funcionan de manera diferente. Por lo tanto, solo los lados curvos necesitan fusión de dirección normal. Y, de hecho, puede calcularlos directamente desde la forma matemática subyacente.
fuente
Veo principalmente tres formas de calcular las normales para una forma generada.
Normales analíticas
En algunos casos, tiene suficiente información sobre la superficie para generar las normales. Por ejemplo, la normalidad de cualquier punto en una esfera es trivial de calcular. En pocas palabras, cuando conoce la derivada de la función, también conoce la normalidad.
Si su caso es lo suficientemente estrecho como para permitirle usar valores normales analíticos, probablemente le darán el mejor resultado en términos de precisión. Sin embargo, la técnica no escala demasiado bien: si también necesita manejar casos en los que no puede usar valores normales analíticos, puede ser más fácil mantener la técnica que maneja el caso general y descartar el analítico por completo.
Vértex normales
El producto cruzado de dos vectores da un vector perpendicular al plano al que pertenecen. Entonces obtener la normalidad de un triángulo es sencillo:
Además, en el ejemplo anterior, la longitud del producto cruzado es proporcional al área dentro de abc . Por lo tanto, la normal suavizada en un vértice compartido por varios triángulos se puede calcular sumando los productos cruzados y normalizándolos como un último paso, ponderando cada triángulo por su área.
Si está trabajando con quads, hay un buen truco que puede usar: para un quad abcd , use
crossProduct(c - a, d - b)
y manejará muy bien los casos en que el quad es en realidad un triángulo.Iñigo quilez escribió algunos artículos breves sobre el tema: normalización inteligente de una malla y normal y área de polígonos de n lados .
Normales de derivadas parciales
Las normales se pueden calcular en el sombreador de fragmentos a partir de las derivadas parciales. La matemática detrás es la misma, excepto que esta vez se hace en el espacio de la pantalla. Este artículo de Angelo Pesce describe la técnica: normales sin normales .
fuente