You are on page 1of 32

Color

Teora del color


El color es una longitud de onda de luz, visible para el ojo humano

390nm

720 nm

El color que vemos en los objetos es resultado de la luz reflejada por su superficie El negro es la ausencia de color. Un objeto negro no refleja nada El blanco es la combinacin de todos los colores. Un objeto blanco refleja todas la luz que le llega

Las tres componentes del color


El ojo humano tiene tres tipos de clulas receptoras de luz
el primer tipo se excita ms con fotones de longitud de onda rojiza el segundo tipo se excita ms con fotones de longitud de onda verde el tercer tipo se excita ms con fotones de longitud de onda azulada

El cerebro mezcla la combinacin de las tres y devuelve un solo color resultado De esta forma, cualquier color que vemos es en realidad una combinacin de ondas con longitudes dentro del espectro visible

Espacio de color
Es un espacio 3D cuyas dimensiones son las componentes R, G y B Variando cada eje entre 0 y 1 obtenemos el cubo de color, que incluye todos los colores visibles al ojo humano G

Verde (0,1,0)

Amarillo (1,1,0)

Blanco (1,1,1) Cian (0,1,1)


s( se ri ,x) ,x x

Negro (0,0,0)

Rojo (1,0,0)

R
Azul (0,0,1) Magenta (1,0,1)

Sombreado de polgonos
Para definir el color activo (con el que se pintan los vrtices) se usa:
void glColor3f (GLfloat rojo, GLfloat verde, GLfloat azul) void glColor3ub (GLfloat rojo, GLfloat verde, GLfloat azul)

Si todos los vrtices tienen el mismo color, todo el polgono es constante Si cada vrtice tiene un color diferente, el color del interior del polgono depender del modo de sombreado elegido: G
Modo plano: el color del polgono es el del ltimo vrtice glShadeModel (GL_FLAT) Modo interpolado: el color del polgono se deduce a partir del color de cada vrtice glShadeModel (GL_SMOOTH)

// Activa el sombreado suave glShadeModel (GL_SMOOTH); // Dibuja el tringulo glBegin (GL_TRIANGLES); // Vrtice rojo glColor3ub (255, 0, 0); glVertex3f (100, 0, 0); // Vrtice verde glColor3ub (0, 255, 0); glVertex3f (0, 100, 0); // Vrtice azul glColor3ub (0, 0, 255); glVertex3f (0, 0, 100); glEnd();

Cambiando a modo de sombreado plano, el tringulo quedara entero de color azul

24 bits

Bits de color
Si el sistema operativo no puede mostrar 24 bits color, ste busca los colores ms adecuados --> no es preciso cambiar el cdigo! Lgicamente, la calidad de la imagen ser diferente

8 bits

Si el nmero de bits color es pequeo, podemos indicarle a OpenGL que use tramas para aproximar el color real:
glEnable (GL_DITHER);

8 bits con dithering

Modo indexado de color


OpenGL tambin permite trabajar directamente con la paleta de color, en lugar de usar las componentes RGB Para establecer el color activo se usa:
void glIndexi (GLint indice);

Ventajas del modo indexado:


es ms rpido (slo se utiliza un valor por pixel) permite animaciones de paleta permite usar el color para indicar otra magnitud

Desventajas
no permite efectos de iluminacin

Ejemplo: navegador 3D en color

void PanelVista_Paint(TObject *Sender) { switch (ModoColor) { case 2: // modo slido glPolygonMode(GL_FRONT,GL_FILL); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); break; case 1: // modo almbrico glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); } // Transformacin de vista glPushMatrix(); gluLookAt (...); // dibujamos los objetos RenderWorld(); glPopMatrix(); }

Iluminacin

Luz ambiente
Es la luz que no viene de ninguna direccin particular Aunque provenga de una fuente, despus de mltiples rebotes por la escena ha perdido la direccionalidad Los objetos iluminados por esta luz la reciben de igual manera en todas sus superficies y en todas direcciones

Materiales
En el mundo real, los objetos tienen color por s mismos El color del material se define segn las longitudes de onda que refleje Bajo una luz blanca, los objetos aparecen con sus colores naturales
(1.0, 1.0, 1.0) (0.5, 0.2, 1.0)

(0.5, 0.2, 1.0)

En general, la luz emitida es el resultado de la luz que llega, escalada por los coeficientes del material

(lr, lg, lc)

(lr*mr, lg*mg, lb*mb)

(mr, mg, mb)

Luz ambiente con OpenGL


Para indicar a OpenGL que ha de realizar los clculos de iluminacin:
glEnable (GL_LIGHTING)

Para seleccionar el modelo de iluminacin ambiente activo:


void glLightModelfv (GL_LIGHT_MODEL_AMBIENT, GLfloat params[4])

Para establecer el material activo:


void glMaterialfv (Glenum cara, Glenum nombre, GLfloat params[4]) GL_BACK GL_SPECULAR GL_FRONT_AND_BACK GL_DIFFUSE GL_FRONT GL_AMBIENT

Ejemplo con luz ambiente


// Activar los clculos de iluminacin glEnable (GL_LIGHTING); // Seleccionar la luz ambiente GLfloat LuzAmbiente[4] = {1.0, 1.0, 0.0, 1.0}; glLightModelfv (GL_LIGHT_MODEL_AMBIENT, LuzAmbiente); // Seleccionar el material GLfloat MaterialAmbiente[4] = {1.0, 0.5, 0.5, 1.0}; glMaterialfv (GL_FRONT, GL_AMBIENT, MaterialAmbiente); // Dibujar el objeto glBegin (..) ... ... glEnd();

(1, 1, 0)

(1, 0.5, 0)

(1, 0.5, 0.5)

Otra forma de definir el material


Si un objeto tiene diferentes materiales, sera muy tedioso declarar muchos vectores RGBA y llamar a glMaterialfv en cada polgono Otra opcin ms cmoda es usar:
void glColorMaterial (Glenum cara, Glenum nombre)

Ahora, las llamadas a glColor en realidad sirven para definir el material

GLfloat mrojo[4]= {1,0,0,1}; GLfloat mverde[4]={0,1,0,1}; glBegin (..) glMaterialfv(GL_FRONT, GL_AMBIENT, mrojo); ... glMaterialfv(GL_FRONT, GL_AMBIENT, mverde); ... glEnd();

glColorMaterial(GL_FRONT, GL_AMBIENT); glBegin (..) glColor3f(1,0,0); ... glColor3f(0,1,0); ... glEnd();

Luz difusa
La fuente tiene una localizacin y una direccin particular Una vez toca la superficie del objeto, se refleja en todas direcciones

Luz incidente

Ni

Luz especular
Tambin es direccional, pero el reflejo se produce en una direccin concreta Produce un punto brillante en la superficie que ilumina --> reflejo especular

Luz incidente

Ni
Reflexin especular ideal Reflexin difusa

Fuentes de luz con OpenGL


Soporta hasta 8 fuentes de luz independientes La iluminacin del polgono depender de los ngulos A y B

Estos ngulos se usan en conjuncin con la iluminacin y las propiedades de los materiales para obtener el color de cada vrtice A partir del color de los vrtices, se interpola el interior de los polgonos

Vectores normales
Para obtener los ngulos hay que conocer la normal a la superficie Para especificar la normal activa:
void glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz) void glNormal3fv (GLfloat n[3])
N=<nx, ny, nz>

Las normales deben tener longitud 1 Si queremos que OpenGL normalize los vectores automticamente:
glEnable (GL_NORMALIZE)

Las normales pueden calcularse de varias maneras


promediando entre las normales de los polgonos adyacentes a partir de la expresin analtica de la superficie

Luz difusa con OpenGL


Para trabajar con luz difusa hay que crear una fuente de luz Para indicar el color de la fuente de luz:
void glLightfv (Glenum luz, Glenum nombre, GLfloat color[4]) GL_LIGHT0 GL_LIGHT1 GL_LIGHT7 GL_AMBIENT GL_DIFFUSE

Para indicar la posicin de la fuente de luz:


void glLightfv (Glenum luz, GL_POSITION, GLfloat pos[4])

Para activar la fuente de luz:


glEnable (Glenum luz)

Ejemplo con una fuente de luz difusa


GLfloat GLfloat GLfloat GLfloat LuzAmbiente[4] LuzDifusa[4] PosLuz[4] Material[4] = = = = {0.2, {1.0, {-50, {1.0, 0.2, 1.0, 50., 0.5, 0.2, 0.0, 100, 0.5, 1.0}; 1.0}; 1.0}; 1.0};

glEnable (GL_LIGHTING); // Seleccionar el material glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Material); // Fuente de luz glLightfv (GL_LIGHT0, GL_AMBIENT, LuzAmbiente); glLightfv (GL_LIGHT0, GL_DIFFUSE, LuzDifusa); glLightfv (GL_LIGHT0, GL_POSITION, PosLuz); glEnable (GL_LIGHT0); glBegin (..) // Dibujar el objeto glNormal3f(...); glVertex3f(...); ... glNormal3f(...);

Luz especular con OpenGL


Se usa para simular superficies metlicas Para indicar el color de la fuente de luz:
void glLightfv (Glenum luz, GL_SPECULAR, GLfloat color[4])

Para indicar el exponente de reflexin especular:


void glLightf (Glenum luz, GL_SHININESS, GLfloat coef)
donde 0<coef<128

coef=128

coef=32

coef=2

Ejemplo con una fuente de luz especular


GLfloat GLfloat GLfloat GLfloat LuzAmbiente[4] LuzEspecular[4] PosLuz[4] Material[4] = = = = {0.2, {1.0, {-50, {1.0, 0.2, 1.0, 50., 0.5, 0.2, 0.0, 100, 0.5, 1.0}; 1.0}; 1.0}; 1.0};

glEnable (GL_LIGHTING); // Seleccionar el material glMaterialfv (GL_FRONT, GL_SPECULAR, Material); glMaterialf (GL_FRONT, GL_SHININESS, 32); // Fuente de luz glLightfv (GL_LIGHT0, GL_AMBIENT, LuzAmbiente); glLightfv (GL_LIGHT0, GL_POSITION, PosLuz); glEnable (GL_LIGHT0); glBegin (..) // Dibujar el objeto glNormal3f(...); glVertex3f(...); ... glNormal3f(...);

Combinando los tres tipos


La luz en cada vrtice se calcula con la siguiente ecuacin:

I = I Aka + (I a ka + I d kd cos + I e ke cosn )


luces
Luz ambiente global Luz ambiente Luz difusa Luz especular

Objetos emisores de luz


Adems de la luz que refleja un objeto, ste puede emitir luz propia Para indicar el color de luz emitida por un objeto:
void glMaterialfv (Glenum cara, GL_EMISSION, GLfloat color[4])

I = I e + I Aka + (I a ka + I d kd cos + I e ke cos )


n luces
Luz emitida

Este trmino no afecta al resto de objetos En ese caso, habra que crear una fuente de luz en la misma posicin del objeto

Posicin de una fuente


Si la fuente de luz est muy lejana -> fuente de luz direccional
los rayos de luz son todos paralelos el ngulo con la normal es constante en todo el interior de un polgono

Para indicar si la fuente es direccional o posicional:


GLfloat pos[4] = {a, b, c, w}; void glLightfv (Glenum luz, GL_POSITION, GLfloat pos[4]) Si w!=0, la posicin de la fuente es (a,b,c,w) (coord. Homogneas) Si w=0, la direccin de la luz viene dada por el vector <a,b,c>

N N N

Atenuacin de una fuente


En la realidad, la intensidad de una fuente decrece con la distancia d OpenGL usa un factor de atenuacin dado por la ecuacin:

1 f at = kc + kl d + k q d 2
glLightf (GLenum luz, GL_CONSTANT_ATTENUATION, GLfloat kc) glLightf (GLenum luz, GL_LINEAR_ATTENUATION, GLfloat kl) glLightf (GLenum luz, GL_QUADRATIC_ATTENUATION, GLfloat kq)

El factor de atenuacin no afecta a:


el valor de emisin de los objetos la luz ambiente global las fuentes direccionales

Focos de luz
Con un foco de luz, decidimos en qu direccin se radia la luz Para indicar la direccin
void glLightfv (Glenum luz, GL_SPOT_DIRECTION, GLfloat dir[3])

Para indicar el ngulo de apertura del cono


void glLightfv (Glenum luz, GL_SPOT_CUTOFF, GLfloat grados)

Para indicar la atenuacin de la luz al alejarnos de la direccin central


void glLightfv (Glenum luz, GL_SPOT_EXPONENT, GLfloat exp)

GL_SPOT_CUTOFF

GL_

SPO

T_D IRE C

TIO N

Moviendo las luces


Las fuentes de luces tambin son transformadas por la matriz de modelado
GLfloat Pos[4]={0,0,75,1}, Dir[3]={0,0,-1}; // limpio pantalla y dibujo la esfera azul glPushMatrix(); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glLightfv(GL_LIGHT0,GL_POSITION,Pos); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,Dir); glTranslatef(Pos[0],Pos[1],Pos[2]); glColor3ub(255,0,0); auxSolidCone(4.0f,6.0f); glDisable(GL_LIGHTING); glColor3ub(255,255,0); auxSolidSphere(3.0f); glEnable(GL_LIGHTING); glPopMatrix();

Ejemplo: navegador 3D con iluminacin

void PanelVista_Paint(TObject *Sender) { switch (ModoColor) { case 3: // modo iluminacin glEnable (GL_LIGHTING); glLightfv (GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, Luz); glLightfv (GL_LIGHT0, GL_POSITION, LuzPos); glEnable (GL_LIGHT0); glEnable (GL_COLOR_MATERIAL); glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE); } glPushMatrix(); glLightfv (GL_LIGHT1, GL_DIFFUSE, FocoLuz); glLightfv (GL_LIGHT1, GL_POSITION, FocoPos); glLightfv (GL_LIGHT1, GL_SPOT_DIRECTION, FocoDir); glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.00001); glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 20); glEnable (GL_LIGHT1); gluLookAt (...); RenderWorld(); glPopMatrix(); }

You might also like