Escuché que debería usar normales en lugar de colores, porque los colores están en desuso. (¿Es eso verdad?) Los normales tienen algo que ver con el reflejo de la luz, pero no puedo encontrar una explicación clara e intuitiva. ¿Qué es una normal?¿Qué es una normal en OpenGL?
Respuesta
A normal en general es un vector unitario cuya dirección es perpendicular a una superficie en un punto específico. Por lo tanto, te dice en qué dirección se enfrenta una superficie. El caso de uso principal para las personas normales son los cálculos de iluminación, donde debe determinar el ángulo (o prácticamente a menudo su coseno) entre la normal en un punto superficial dado y la dirección hacia una fuente de luz o una cámara.
Muchas cosas ahora están en desuso, incluidas las normales y los colores. Eso solo significa que tienes que implementarlos tú mismo. Con las normales puedes sombrear tus objetos. Depende de usted hacer los cálculos, pero hay muchos tutoriales sobre, por ejemplo, Gouraud/Phong sombreado.
Editar: Hay dos tipos de normales: normales de cara y normales de vértice. Las normales de la cara apuntan lejos del triángulo, las normales de los vértices apuntan hacia el vértice. Con las normales de los vértices puede lograr una mejor calidad, pero también hay muchos usos para los normales de las caras, p. se pueden usar en detección de colisiones y volúmenes ocultos.
Este, al igual que la mayor parte de la información que he podido encontrar, me dice una un poco más acerca de para qué se usan las normales, pero todavía no estoy seguro de qué es * normal *. Me sorprende escuchar que están en desuso, pero no sabría por qué o cómo los implementaría, ya que no estoy seguro de cuáles son. –
Toma una hoja de papel y traza una línea. Luego dibuja la segunda línea que es perpendicular a la primera. La segunda línea es la primera normal. Ahora imagina que la primera línea es la superficie de un triángulo. Los bordes de la primera línea son vértices. – SurvivalMachine
Las normas son vectores de longitud de unidad. Entonces, un normal (1, 0, 0) apunta hacia la derecha. Cuando envía vértices para representar, también puede enviar normales. Luego haces el cálculo de iluminación en el sombreador. – SurvivalMachine
glNormal
mínima ejemplo
glNormal
es un método OpenGL 2 obsoleto, pero es fácil de entender, por lo que vamos a ver en ella. La alternativa del sombreador moderno se analiza a continuación.
Este ejemplo ilustra algunos detalles de cómo glNormal
trabaja con un rayo difuso.
Los comentarios de la función display
explican el significado de cada triángulo.
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
/* Triangle on the x-y plane. */
static void draw_triangle() {
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
}
/* A triangle tilted 45 degrees manually. */
static void draw_triangle_45() {
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
}
static void display(void) {
glColor3f(1.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
/*
Triangle perpendicular to the light.
0,0,1 also happens to be the default normal if we hadn't specified one.
*/
glNormal3f(0.0f, 0.0f, 1.0f);
draw_triangle();
/*
This triangle is as bright as the previous one.
This is not photorealistic, where it should be less bright.
*/
glTranslatef(2.0f, 0.0f, 0.0f);
draw_triangle_45();
/*
Same as previous triangle, but with the normal set
to the photorealistic value of 45, making it less bright.
Note that the norm of this normal vector is not 1,
but we are fine since we are using `glEnable(GL_NORMALIZE)`.
*/
glTranslatef(2.0f, 0.0f, 0.0f);
glNormal3f(0.0f, 1.0f, 1.0f);
draw_triangle_45();
/*
This triangle is rotated 45 degrees with a glRotate.
It should be as bright as the previous one,
even though we set the normal to 0,0,1.
So glRotate also affects the normal!
*/
glTranslatef(2.0f, 0.0f, 0.0f);
glNormal3f(0.0, 0.0, 1.0);
glRotatef(45.0, -1.0, 0.0, 0.0);
draw_triangle();
glPopMatrix();
glFlush();
}
static void init(void) {
GLfloat light0_diffuse[] = {1.0, 1.0, 1.0, 1.0};
/* Plane wave coming from +z infinity. */
GLfloat light0_position[] = {0.0, 0.0, 1.0, 0.0};
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
}
static void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 7.0, -1.0, 1.0, -1.5, 1.5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 200);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
Teoría
En OpenGL 2 cada vértice tiene su propio vector normal asociado.
El vector normal determina cómo brillante el vértice es, que luego se utiliza para determinar cómo brillante del triángulo es.
OpenGL 2 utiliza la Phong reflection model, en el que la luz se separa en tres componentes: ambiente, difusas y especulares. De ellos, los componentes difusas y especulares se ven afectados por la normalidad:
- si la luz difusa es perpendicular a la superficie, que hace es más brillante, sin importar donde el observador es
- si la luz especular llega a la superficie , y rebota de la derecha en el ojo del observador, que se convierte en el punto brigher
glNormal
establece el vector normal actual, que se utiliza para todos los siguientes vértices.
El valor inicial para la normalidad antes de todos glNormal
es 0,0,1
.
vectores normales mosto tienen norma 1, o bien cambian de color! 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. This GIF ilustra eso maravillosamente.
Por qué es útil tener normales por vértices en lugar de por caras
Ambas esferas a continuación tienen el mismo número de polígonos. El que tiene normales en los vértices se ve mucho más suave.
OpenGL 4 fragment shaders
En la API de OpenGL más nuevos, que pasan los datos normales de dirección para la GPU como un trozo arbitraria de datos: la GPU no sabe que representa las normales .
Luego escribe un sombreador de fragmentos manuscrito, que es un programa arbitrario que se ejecuta en la GPU, que lee los datos normales que le pasa, e implementa el algoritmo de iluminación que desee. Puede implementar Phong de manera eficiente si así lo desea, calculando manualmente algunos productos de puntos.
Esto le da total flexibilidad para cambiar el diseño del algoritmo, que es una de las principales características de las GPU modernas. Ver: https://stackoverflow.com/a/36211337/895245
Ejemplos de esto se pueden encontrar en cualquiera de los tutoriales "modernos" de OpenGL 4, p. https://github.com/opengl-tutorials/ogl/blob/a9fe43fedef827240ce17c1c0f07e83e2680909a/tutorial08_basic_shading/StandardShading.fragmentshader#L42
Bibliografía
Buena explicación, sin embargo glNormal es parte de la implementación anterior de OpenGL y debe evitarse. – Matth
@MatthUnderpants gracias por sus comentarios, ¿cuál es la mejor manera de hacerlo ahora? –
Es mediante el uso del sombreador de vértices y luego pasar los datos al sombreador de fragmentos. Te aconsejo que leas en este fantástico tutorial: www.learnopengl.com – Matth
- 1. ¿Cómo aplicar un mapa normal en OpenGL?
- 2. qué es un archivo normal en unix
- 3. ¿Qué es exactamente una superficie en OpenGL ES o Direct3D?
- 4. ¿Qué es 'glBufferData' en OpenGL ES?
- 5. OpenGL u OpenGL ES
- 6. ¿Puedo especificar por cara normal en OpenGL ES y lograr sombreado no liso/plano?
- 7. Dibujando una esfera en OpenGL ES
- 8. ¿Qué debo aprender: Quartz u OpenGL ES?
- 9. Diferencia en iOS OpenGL ES y Android OpenGL ES
- 10. OpenGL ES y sombreadores compatibles con OpenGL
- 11. Elija OpenGL ES 1.1 u OpenGL ES 2.0?
- 12. Por qué unir es más rápido que la concatenación normal
- 13. Transición de OpenGL ES 1.1 a OpenGL ES 2.0
- 14. ¿Por qué WinAPI es tan diferente de la C "normal"?
- 15. ¿Por qué es mejor administrar explícitamente matrices en OpenGL?
- 16. Convolviendo una imagen con OpenGL ES en iPhone: ¿es posible?
- 17. ¿Qué versiones de GLSL puedo usar en OpenGL ES 2.0?
- 18. ¿Qué es CLI/C++ exactamente? ¿Cómo difiere de C++ "normal"?
- 19. ¿Qué hace glLoadIdentity() en OpenGL?
- 20. ¿Qué es gl_ModelViewMatrix y gl_ModelViewProjectionMatrix en OpenGL moderno?
- 21. Render multiplataforma en OpenGL ES
- 22. ¿Es OpenGL compatible con versiones anteriores de OpenGL ES?
- 23. OpenGL niebla contra OpenGL ES niebla
- 24. Manera eficiente de dibujar en OpenGL ES
- 25. ¿En qué situaciones es una buena idea preferir GDI en lugar de DirectX/OpenGL
- 26. OpenGL ES - glReadPixels
- 27. ¿Qué es uint_fast32_t y por qué debería usarse en lugar del int normal y uint32_t?
- 28. openGL ES retina support
- 29. Diferencia entre OpenGL ES 2.0 y OpenGL 4
- 30. Proyectar una textura en OpenGL
Gracias por el enlace. ¿Por qué se necesita una normal, si debería ser obvio a qué dirección se enfrenta una superficie? ¿Las superficies a menudo no se ven perpendiculares, o es solo un cálculo que OpenGL no quiere manejar? –
Incluso si es obvio dónde se encuentra la superficie, aún necesita proporcionar esa información para poder hacer cálculos de iluminación, y las normales son la forma estándar de hacerlo.Para un simple sombreado plano de una malla triangular, puede calcular fácilmente las normales a partir de los vértices del triángulo. –
Para obtener sombreados más realistas, las normales suelen variar suavemente. Esto a menudo se logra al interpolar las normales a través de la superficie, ya sea mediante la interpolación entre las normales de la cara o las normales de los vértices. Las normales de cara son fáciles de obtener (como la caja sombreada plana), pero difíciles de interpolar. Las normales de los vértices son fáciles de interpolar (ver [sombreado de Phong] (http://en.wikipedia.org/wiki/Phong_shading)) pero no tan fáciles de calcular para una malla. Es por eso que las normales de vértice a menudo se calculan de antemano y se suministran con la malla. –