• No se han encontrado resultados

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

N/A
N/A
Protected

Academic year: 2022

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

Copied!
32
0
0

Texto completo

(1)

Color

(2)

Teoría del color

• 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 combinación de todos los colores. Un objeto blanco refleja todas la luz que le llega

390nm 720 nm

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

(3)

Las tres componentes del color

• El ojo humano tiene tres tipos de células receptoras de luz

– el primer tipo se excita más con fotones de longitud de onda rojiza – el segundo tipo se excita más con fotones de longitud de onda verde – el tercer tipo se excita más con fotones de longitud de onda azulada

• El cerebro mezcla la combinación de las tres y devuelve un solo color resultado

• De esta forma, cualquier color que vemos es en realidad una combinación de ondas con longitudes dentro del espectro visible

(4)

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

Azul (0,0,1)

R

B

Rojo (1,0,0) Verde (0,1,0)

Magenta (1,0,1) Blanco (1,1,1)

Cian (0,1,1)

Amarillo (1,1,0)

Negro (0,0,0) Grises (x,x,x)

(5)

Sombreado de polígonos

• Para definir el color activo (con el que se pintan los vértices) se usa:

void glColor3f (GLfloat rojo, GLfloat verde, GLfloat azul) void glColor3ub (GLfloat rojo, GLfloat verde, GLfloat azul)

• Si todos los vértices tienen el mismo color, todo el polígono es constante

• Si cada vértice tiene un color diferente, el color del interior del polígono dependerá del modo de sombreado elegido:

– Modo plano: el color del polígono es el del último vértice

glShadeModel (GL_FLAT)

– Modo interpolado: el color del

polígono se deduce a partir del color de cada vértice

glShadeModel (GL_SMOOTH)

G

R

B

(6)

// Activa el sombreado suave glShadeModel (GL_SMOOTH);

// Dibuja el triángulo glBegin (GL_TRIANGLES);

// Vértice rojo

glColor3ub (255, 0, 0);

glVertex3f (100, 0, 0);

// Vértice verde

glColor3ub (0, 255, 0);

glVertex3f (0, 100, 0);

// Vértice azul

glColor3ub (0, 0, 255);

glVertex3f (0, 0, 100);

glEnd();

G

R

B

• Cambiando a modo de

sombreado plano, el triángulo quedaría entero de color azul

(7)

Bits de color

• Si el sistema operativo no puede mostrar 24 bits color, éste busca los colores más

adecuados --> no es preciso cambiar el código!

• Lógicamente, la calidad de la imagen será diferente

24 bits

8 bits

• Si el número de bits color es pequeño, podemos indicarle a OpenGL que use tramas para aproximar el color real:

glEnable (GL_DITHER);

8 bits con dithering

(8)

Modo indexado de color

• OpenGL también 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 más rápido (sólo se utiliza un valor por pixel) – permite animaciones de paleta

– permite usar el color para indicar otra magnitud

• Desventajas

– no permite efectos de iluminación

(9)

Ejemplo: navegador 3D en color

(10)

void PanelVista_Paint(TObject *Sender) {

switch (ModoColor) {

case 2: // modo sólido

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 alámbrico

glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

glDisable(GL_CULL_FACE);

glDisable(GL_DEPTH_TEST);

glClear(GL_COLOR_BUFFER_BIT);

}

// Transformación de vista glPushMatrix();

gluLookAt (...);

// dibujamos los objetos RenderWorld();

glPopMatrix();

}

(11)

Iluminación

(12)

Luz ambiente

• Es la luz que no viene de ninguna dirección particular

• Aunque provenga de una fuente, después de múltiples 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

(13)

Materiales

• En el mundo real, los objetos tienen color por sí mismos

• El color del material se define según 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)

(mr, mg, mb)

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

(14)

Luz ambiente con OpenGL

• Para indicar a OpenGL que ha de realizar los cálculos de iluminación:

glEnable (GL_LIGHTING)

• Para seleccionar el modelo de iluminación 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_AMBIENT

GL_DIFFUSE

GL_SPECULAR GL_BACK

GL_FRONT_AND_BACK

GL_FRONT

(15)

// Activar los cálculos de iluminación 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.5)

(1, 0.5, 0)

Ejemplo con luz ambiente

(16)

Otra forma de definir el material

• Si un objeto tiene diferentes materiales, sería muy tedioso declarar muchos vectores RGBA y llamar a glMaterialfv en cada polígono

• Otra opción más cómoda 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();

(17)

Luz difusa

• La fuente tiene una localización y una dirección particular

• Una vez toca la superficie del objeto, se refleja en todas direcciones

Luz

incidente Ni

(18)

Luz especular

• También es direccional, pero el reflejo se produce en una

dirección concreta

• Produce un punto brillante en la superficie que ilumina --> reflejo especular

Luz

incidente Ni

Reflexión difusa

Reflexión especular ideal

(19)

Fuentes de luz con OpenGL

• Soporta hasta 8 fuentes de luz independientes

• La iluminación del polígono dependerá de los ángulos A y B

A B

• Estos ángulos se usan en conjunción con la iluminación y las

propiedades de los materiales para obtener el color de cada vértice

• A partir del color de los vértices, se interpola el interior de los polígonos

(20)

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 automáticamente:

glEnable (GL_NORMALIZE)

• Las normales pueden calcularse de varias maneras

– promediando entre las normales de los polígonos adyacentes – a partir de la expresión analítica de la superficie

(21)

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_DIFFUSE

GL_AMBIENT GL_LIGHT7

GL_LIGHT0

GL_LIGHT1

• Para indicar la posición de la fuente de luz:

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

• Para activar la fuente de luz:

glEnable (Glenum luz)

(22)

GLfloat LuzAmbiente[4] = {0.2, 0.2, 0.2, 1.0};

GLfloat LuzDifusa[4] = {1.0, 1.0, 0.0, 1.0};

GLfloat PosLuz[4] = {-50, 50., 100, 1.0};

GLfloat Material[4] = {1.0, 0.5, 0.5, 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(...);

Ejemplo con una fuente de luz difusa

(23)

Luz especular con OpenGL

• Se usa para simular superficies metálicas

• Para indicar el color de la fuente de luz:

void glLightfv (Glenum luz, GL_SPECULAR, GLfloat color[4])

• Para indicar el exponente de reflexión especular:

void glLightf (Glenum luz, GL_SHININESS, GLfloat coef)

donde 0<coef<128

coef=128 coef=32 coef=2

(24)

GLfloat LuzAmbiente[4] = {0.2, 0.2, 0.2, 1.0};

GLfloat LuzEspecular[4] = {1.0, 1.0, 0.0, 1.0};

GLfloat PosLuz[4] = {-50, 50., 100, 1.0};

GLfloat Material[4] = {1.0, 0.5, 0.5, 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(...);

Ejemplo con una fuente de luz especular

(25)

Combinando los tres tipos

• La luz en cada vértice se calcula con la siguiente ecuación:

( )

+ +

+

=

luces

n e

e d

d a

a a

A

k I k I k I k

I

I cos θ cos α

N

Luz ambiente global Luz ambiente Luz difusa Luz especular

+

(26)

Objetos emisores de luz

• Además 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])

( )

+ +

+ +

=

luces

n e

e d

d a

a a

A

e

I k I k I k I k

I

I cos θ cos α

Luz emitida

• Este término no afecta al resto de objetos

• En ese caso, habría que crear una fuente de luz en la misma posición del objeto

(27)

Posición 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 polígono

• 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])

N N

Si w!=0, la posición de la fuente es

(a,b,c,w) (coord. Homogéneas)

N

N N

Si w=0, la dirección de la luz viene dada por el vector <a,b,c>

(28)

Atenuación de una fuente

• En la realidad, la intensidad de una fuente decrece con la distancia d

• OpenGL usa un factor de atenuación dado por la ecuación:

2

1

d k d

k f k

q l

c

at

= + +

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 atenuación no afecta a:

– el valor de emisión de los objetos – la luz ambiente global

– las fuentes direccionales

(29)

Focos de luz

• Con un foco de luz, decidimos en qué dirección se radia la luz

• Para indicar la dirección

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 atenuación de la luz al alejarnos de la dirección central

void glLightfv (Glenum luz, GL_SPOT_EXPONENT, GLfloat exp)

GL_SPOT_CUTOFF

GL_SPO

T_DIRE

CTION

(30)

Moviendo las luces

• Las fuentes de luces también 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();

(31)

Ejemplo: navegador 3D con iluminación

(32)

void PanelVista_Paint(TObject *Sender) {

switch (ModoColor) {

case 3: // modo iluminación 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();

}

Referencias

Documento similar

Colores primarios como el rojo, azul y amarillo se corresponden con el vértigo, el mareo la acrofobia, y la limerencia, así como trastornos del sueño; y los secundarios como el

Indica en el calendario días de la semana, colorea de rojo día de hoy, azul ayer y verde mañana.. Marcan con una X los días que corresponde a fin

El traje para adiestrador se fabrica en muchas tallas (indicadas en estándares europeos) y diferentes combinaciones de colores: negro con azul, rojo, amarillo, verde claro, verde

Asignaturas marcadas en color rojo no se reconocen; asignaturas marcadas en color verde sí se reconocen; asignaturas marcadas en blanco, los alumnos pueden hacer

al utilizado con uno o más propósitos médicos, que tiene como característica principal que no requiere formar parte del hardware del dispositivo médico para cumplir

9 Andrés ha anotado el color de los pantalones que hoy han llevado los chicos y chicas de su clase. Rojo, rojo, azul, verde, negro, marrón, marrón, rojo, azul, gris, negro,

Por ejemplo, si buscas el complementario del violeta ya sabes que este color está formado por rojo y azul. Por lo tanto su complementario es el amarillo pues es el

En su natal Caracas, donde se formó Bello como latinista, no pudo tener la oportunidad de aprender griego. Cuando nació, ya hacía 14 años que los jesuitas habían sido