Estoy aprendiendo algunos conceptos básicos de OpenGL, pero me pregunto por qué hay una llamada glNormal
para establecer la normalidad de los vértices.
Si creo un triángulo simple como este:
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(0,1,0);
glEnd();
¿No deberían definirse las normales implícitamente por el tipo de primitivo geométrico? Si no establezco un valor normal, ¿OpenGL lo calculará?
Respuestas:
Llamar
glNormal
varias veces entre ellas leglBegin/End
permite establecer una normal por vértice en lugar de por primitiva.Para una malla más compleja que consta de múltiples triángulos, desearía que la normal en un vértice dependa de los otros triángulos de la geometría circundante y no solo de la normal del triángulo al que pertenece.
Aquí hay un ejemplo de la misma geometría con:
(0,0,1)
):El modelo de sombra predeterminado (
GL_SMOOTH
) hace que las normales de los vértices de la cara se interpolen a través de la cara. Para las normales por vértice, esto da como resultado una esfera sombreada suave, pero para las normales por cara , termina con el aspecto facetado característico.fuente
No, GL no calcula una norma para usted. No puede saber cuál debería ser lo normal. Sus primitivas no significan nada fuera de la rasterización (y algunos otros lugares). GL no sabe qué caras (triángulos) comparten un vértice (calcular esto en tiempo de ejecución es muy costoso sin usar diferentes estructuras de datos).
Debe preprocesar una "sopa de triángulos" de una malla para encontrar vértices comunes y calcular valores normales. Esto debe hacerse antes de que el juego corra por velocidad.
También hay casos como bordes duros en los que geométricamente hay un vértice compartido en la esquina, pero desea que las normales sean separadas para que se ilumine correctamente. En el modelo de representación GL / D3D, necesita dos vértices separados (en la misma posición) para esto, cada uno con una normalidad separada.
Necesitará todo esto para UV y mapeo de texturas también.
fuente
La respuesta corta es que en realidad no tiene que establecer una normalidad en absoluto. Los vectores normales solo se usan si está realizando iluminación OpenGL (o tal vez algún otro cálculo que pueda depender de ellos), pero si eso no se aplica a usted (o si está utilizando algún otro método para iluminar, por ejemplo, mapas de luz ), entonces puede omitir todas las llamadas glNormal.
Así que supongamos que está haciendo algo donde especificar glNormal tiene sentido y veamos un poco más.
glNormal se puede especificar por primitivo o por vértice. Con normales por primitivas todo lo que significa es que todas las normales para cada vértice en la cara primitiva en la misma dirección. A veces esto es lo que quiere, pero a veces no lo es; donde las normales por vértice son útiles es que permiten que cada vértice tenga su propia orientación.
Tome el ejemplo clásico de una esfera. Si cada triángulo en una esfera tuviera la misma normalidad, entonces el resultado final sería bastante facetado. Probablemente eso no sea lo que quieres, en su lugar quieres un sombreado suave. Entonces, lo que debe hacer es promediar las normales para cada triángulo que comparte un vértice común y obtener un resultado sombreado suave.
fuente
Ejemplo mínimo que ilustra algunos detalles de cómo
glNormal
funciona con un rayo difuso.Los comentarios de la
display
función explican qué significa cada triángulo.Teoría
En OpenGL, cada vértice tiene su propio vector normal asociado.
El vector normal determina qué tan brillante es el vértice, que luego se usa para determinar qué tan brillante es el triángulo.
Cuando una superficie es perpendicular a la luz, es más brillante que una superficie paralela.
glNormal
establece el vector normal actual, que se usa para todos los vértices siguientes.El valor inicial de lo normal antes de que todos estemos
glNormal
es0,0,1
.Los vectores normales deben tener la norma 1, ¡o los colores cambian!
glScale
¡También altera la duración de las normales!glEnable(GL_NORMALIZE);
hace que OpenGL establezca automáticamente su norma en 1 para nosotros. Este GIF lo ilustra maravillosamente.Bibliografía:
fuente
Necesita glNormal para implementar algunas funciones dependientes del codificador. Por ejemplo, es posible que desee crear normales para preservar los bordes duros.
fuente