6.1.5  Especificando Colores

COLOR:
CUERPO_DEL_COLOR |
color CUERPO_DEL_COLOR | (Esto significa que el identificador color o colour CUERPO_DEL_COLOR colour puede opcionalmente preceder a alguna especificación de color) CUERPO_DEL_COLOR: VECTOR_DE_COLOR | GRUPO_DE_PALABRAS_RESERVADAS_DE_COLOR | IDENTIFICADOR_DE_COLOR VECTOR_DE_COLOR: rgb <Vector_de_3_Términos> | rgbf <Vector_de_4_Términos> | rgbt <Vector_de_4_Términos> | [ rgbft ] <Vector_de_5_Términos> GRUPO_DE_PALABRAS_RESERVADAS_DE_COLOR: [ OBJETO_IDENTIFICADOR_DE_COLOR ]... OBJETO_IDENTIFICADOR_DE_COLOR: IDENTIFICADOR_DE_COLOR | red Cantidad_de_Rojo | blue Cantidad_de_Azul | green Cantidad_de_Verde | filter Cantidad_de_Filtro | transmit Cantidad_de_Transmisión

Nota: IDENTIFICADORES_DE_COLOR son identificadores que han sido previamente declarados para tener valores de color. Los vectores de 3, 4, Y 5 componentes normalmente son vectores literales pero pueden ser expresiones de vector o valores en coma flotante que se tienen en cuenta como vectores. Ver "Promoción de operadores" y las secciones siguientes.

A veces POV-Ray necesita que se le especifique algún color. Los colores constan de 5 valores o componentes del color. Los tres primeros se llaman red, green y blue. Estos especifican la intensidad de los colores primarios rojo, verde y azul respectivamente utilizando un sistema de color aditivo similar al utilizado por el color de fósforo rojo, verde y azul de un monitor en color.

El 4º componente, llamado filter especifica la cantidad de transparencia filtrada de una sustancia. Algunos ejemplos en el mundo real de transparencia filtrada son las vidrieras o el papel celofán. La luz que pasa a través de estos objetos se tinta del color según el material va absorviendo selectivamente algunas frecuencias de luz mientras deja pasar otras. El color del objeto es sustraido de la luz que pasa a través de él, por eso a esto se le llama transparencia sustractiva

El 5º componente, llamado transmit, indica la cantidad de luz sin filtrar que se transmite a través de la superficie. Algunos ejemplos en el mundo real de transparencia sin filtrar son la ropa con transparencias, redes de malla fina y povo en una superficie. En estos ejemplos, todas las frecuencias de luz pueden asar a través de pequeños agujeros en la superficie. Aunque la cantidad de luz pasando a través se ve disminuida, el color de la luz que atraviesa no cambia.

El color del objeto junto con el color transmitido a través del objeto constituyen el 100% del color final. Por eso, si transmit se pone a 0.9, el color transmitido aportará el 90% y el color del objeto será solo de un 10%. Esto también es válido fuera del rango 0-1, por ejemplo, si transmit se pone a 1.7, el color transmitido aporta un 170% y el color del objeto aportará un menos 70%. Utilizando los valores de transmit fuera del rango 0-1 se pueden crear efectos especiales interesantes, pero no se corresponden con ningún fenómeno visto en el mundo real. Un ejemplo:

#version 3.5;
global_settings {assumed_gamma 1.0}
camera {location -2.5*z look_at 0 orthographic}
box {
0,1
texture {
pigment {
gradient y
colour_map {
[0, red 1]
[1, blue 1]
}
}
finish{ambient 1}
}
texture {
pigment {
gradient x
colour_map {
[0, rgb 0.5 transmit -3]
[1, rgb 0.5 transmit 3]
}
}
finish{ambient 1}
}
translate <-0.5,-0.5,0>
scale <3,2,1>
}

Cuando utilizas los valores de transmit para efectos especiales, puedes visualizarlo de esta manera: El valor transmit significa "contraste". 1.0 no realiza ningún cambio en el contraste, 0.5 es la mitad del contraste, 2.0 es el doble del contraste y así todo. Se podría decir que transmit "escala" los colores. El color del objeto es el "valor central". Todos los colores se acercarán al "valor central" si transmit está entre 0 y 1, y todos los colores se apartarán del "valor central" si transmit es mayor que 1. Si transmit es negativo los colores se invertirán con respecto al "valor central". Normalmente se usa rgb 0.5 como "valor central", pero se pueden utilizar otros valores para otros efectos. Realmente el "valor central" es un color, y los colores distintos del gris se pueden utilizar para crear efectos interesantes. Los componentes rojo, verce y azul se procesan individualmente.

Nota: Las primeras versiones de POV-Ray usaban el identificador alpha para especificar la transparencia filtrada. Como esa palabra se utiliza a veces para describir la transparencia no filtrada, alpha ya no se utiliza.

Cada uno de los cinco componentes de un color son valores en coma flotante y normalmente se encuentran en un rango entre 0.0 y 1.0. De todas maneras se puede utilizar cualquier valor, incluso negativo.

Muchas veces el identificador color es opcional y puede ser omitido. También se soporta la ortografía británica o canadiense, colour. Los colores se pueden especificar utilizando vectores, palabras clave con coma flotante o identificadores. También puedes crear expresiones de color bastante complejas con combinaciones de cualquiera de los antes mencionados, utilizando varios operadores familiares. La sintaxis para especificar un color ha evolucionado desde la primera vez que se publicó POV-Ray. Se ha mantenido la sintaxis original basada en palabras clave y se ha añadido un atajo como notación vectorial. Tanto la sintaxis nueva como la vieja son aceptables, aunque la sintaxis vectorial es más facil de utilizar cuando se crean expresiones de color.

La sintaxis para combinar colores literales en expresiones de color es casi idéntica a la que se utiliza para vectores y expresiones en coma flotante. En la sintaxis para las expresiones vectoriales, algunos de los objetos de la sintaxis están definidos en la sección para expresiones en coma flotante. Ver "Expresiones en Coma Flotante" para estas definiciones. En las siguientes subsecciones hay explicaciones detalladas de las cuestiones de la especificación de color.

6.1.5.1  Vectores de Color

La sintaxis para un vector de color es ...

VECTOR_DE_COLOR:
rgb <Vector_de_3_Términos> |
rgbf <Vector_de_4_Términos> |
rgbt <Vector_de_4_Términos> |
[ rgbft ] <Vector_de_5_Términos>

... Donde los vectores son cualquier expresión válida de 3, 4 o 5 componentes. Por ejemplo

 color rgb <1.0, 0.5, 0.2>

Esto especifica un color cuyo componente rojo es de 1.0 o del 100% de su intensidad. El componente verde es de 0.5 o del 50% de su intensidad y el componente azul es de 0.2 o del 20% de su intensidad. Aunque los componentes de filtro y de transmisión no están explícitamente especificados, existen en este vector y están establecidos con su valor por defecto, que es 0 o sin transparencia en ambos casos.

El identificador rgbf requiere un vector de cuatro componentes. El 4º componente es el filtro y el componente transmit se queda por defecto en cero. De la misma manera, el identificador rgbt necesita cuatro componentes donde el 4º valor se mueve hacia el lugar del 5º componente que es transmit, por lo cual filter se queda como cero.

El identificador rgbtf permite especificar los cinco componentes. Internamente, en las expresiones se utilizan siempre los cinco componentes

En algunas circunstancias, si la expresión del vector es de 5 componentes o hay un identificador de color en la expresión, el identificador rgbtf es opcional.

6.1.5.2  Palabras Reservadas para el Color

El método antiguo de especificación de color aun se puede utilizar y muchos usuarios lo prefieren.

GRUPO_DE_IDENTIFICADORES_DE_COLOR:
[ OBJETO_DE_IDENTIFICADOR_DE_COLOR ]...
OBJETO_DE_IDENTIFICADOR_DE_COLOR:
IDENTIFICADOR_DE_COLOR |
red Cantidad_de_Rojo | blue Cantidad_de_Azul | green Cantidad_de_Verde |
filter Cantidad_de_Filtro | transmit Cantidad_de_Transmisión

Aunque el identificador color es opcional en un principio, es bastante común verlo de esta manera. Esto va seguido de cualquiera de las cinco palabras clave opcionales red, green, blue, filter, o transmit. Cada uno de estos identificadores de componentes va seguido de una expresión en coma flotante. Por ejemplo

 color red 1.0 green 0.5

Esto especifica un color cuyo componente rojo es de 1.0 o del 100% de su intensidad y el componente verde es de 0.5 o del 50% de su intensidad. Aunque el azul, el filtro y la transmisión no están explícitamente especificados, existen y están establecidos con 0, que es su valor por defecto. Los identificadores de los componentes se pueden poner en cualquier orden, y si alguno de los componentes no se especifica, su valor por defecto será cero. Un IDENTIFICADOR_DE_COLOR también se puede especificar pero debe ser siempre el primero del grupo. Para más detalles ver "Errores Frecuentes en el Uso del Color"

6.1.5.3  Identificadores de Color

Los identificadores de color se pueden declarar para hacer más legibles los archivos de escena y también para parametrizar esta, consiguiendo así que cambiando una sola declaración se cambien varios valores. Un identificador se declara de la siguiente manera.

DECLARACIÓN_DE_COLOR:
#declare IENTIFICADOR = COLOR; |
#local IDENTIFICADOR = COLOR;

Donde IDENTIFICADOR es el nombre del identificador, que puede ser de hasta 40 caracteres de largo, y COLOR es cualquier especificación válida.

Nota: Debe haber un punto y coma al final de la declaración. Si se omite se genera un aviso (warning) y algunas macros pueden no funcionar correctamente. Ver " #declare vs. #local" Para obtener más información en el ámbito de los identificadores.

Aquí hay varios ejemplos ...

 #declare Blanco = rgb <1,1,1>;
#declare Cian = color blue 1.0 green 1.0;
#declare Raro = rgb <Foo*2,Bar-1,Bob/3>;
#declare GrisClaro = Blanco*0.8;
#declare CianClaro = Cian red 0.6;

Como muestra el ejemplo de GrisClaro, no se necesita ningún identificador de color cuando se crea alguna expresión de color basada en colores previamente declarados. El último ejemplo muestra como se puede utilizar un identificador de color con el estilo de la sintaxis de las palabras clave. Asegúrate de escribir el identificador antes que cualquier otro componente con palabras reservadas.

Como con los vectores y los valores de coma flotante, se pueden redefinir los colores a lo largo de una escena, pero la necesidad de hacer esto es bastante rara.

6.1.5.4  Operadores de Color

Los vectores de color se pueden combinar en expresiones de la misma manera que los valores de un vector o los valores en coma flotante. Las operaciones se realizan en base componente-a-componente. Por ejemplo rgb <1.0,0.5,0.2>*0.9 da el mismo resultado que rgb<1.0,0.5,0.2>*<0.9,0.9,0.9> o rgb<0.9,0.45,0.18>. Otras operaciones también se realizan en una base componente-a-componente similar.

Se puede utilizar el operador punto para extraer un único componente de un color. Suponiendo que el identificador Matiz ha sido previamente definido como un color, entonces Matiz.red es el valor en coma flotante del componente rojo de Matiz. De la misma manera, Matiz.green, Matiz.blue, Matiz.filter y Matiz.transmit extraen el valor en coma flotante de los otros componentes del color. Matiz.gray devuelve el valor en gris del vector de color.

6.1.5.5  Errores Frecuentes en el Uso del Color

La variedad y complejidad de los métodos de especificación de color pueden dar lugar a algunos errores comunes. He aquí algunas cosas a tener en cuenta cuando se especifica un color:

Cuando se usa una transparencia de filtro (filter) los colores que vienen a través del objeto se multiplican por los componentes del color primario. Por ejemplo, si una luz gris como rgb<0.9,0.9,0.9> pasa a traves de un filtro como rgbf<1.0,0.5,0.0,1.0> el resultado es rgb<0.9,0.45,0.0>. Osea, se deja pasar el rojo en un 100%, el verde se corta por la mitad de 0.9 a 0.45 y el azul se queda totalmente bloqueado. A veces los usuarios especifican de forma incorrecta un objeto con:

 color filter 1.0

Pero esto implica que los valores de rojo, verde y azul son cero. Solo acabas de especificar un filtro totalmente negro y por tanto ninguna luz pasa a través. La manera correcta es cualquiera de las dos siguientes:

 color red 1.0  green 1.0  blue 1.0  filter 1.0

o tambien:

 color transmit 1.0

En el 2º ejemplo no importa cuales sean los valores de rgb. Toda la luz pasa a través intacta. Otro error común es la utilización de identificadores y expresiones con palabras reservadas para los colores. Por ejemplo ...

 color Mi_Color red 0.5

sustituye el componente rojo de Mi_Color, cualquiera que sea, por un componente rojo de 0.5. Sin embargo ...

 color Mi_Color + red 0.5

añade 0.5 al componente rojo de Mi_Color, e incluso menos obviamente ...

 color Mi_Color * red 0.5

corta por la mitad el componente rojo como ya habrás supuesto, ¡pero además multiplica los componentes verde, azul, filtro y transmisión por cero! La parte de la expresión después del operador de multiplicación se evalua como rgbft<0.5,0,0,0,0> como un color completo de 5 componentes.

El siguiente ejemlo no conlleva ningún cambio a Mi_color.

 color red 0.5 Mi_Color

Esto es porque el identificador sobreescribe completamente el valor anterior. Cuando se usan identificadores con palabras reservadas para el color, el identificador debe ir primero. Otra cuestión a tener en cuenta: Alguna sintaxis de POV-Ray permite especificaciones de color completo pero solo utiliza la parte de rgb. En estos casos se permite utilizar un valor en coma flotante donde se necesita el color. Por ejemplo:

 finish { ambient 1 }

La palabra reservada ambient cuenta con un color, por tanto el valor 1 pasa a ser <1,1,1,1,1> con lo cual no hay ningún problema.

Por otro lado...

 pigment { color 0.4 }

es válido, pero puede no dar el resultado que pretendías. El 0.4 pasa a ser <0.4,0.4,0.4,0.4,0.4>, con el filtro y la transmisión puestos también como 0.4. Posíblemente lo siguiente encaje más con lo que querías ...

 pigment { color rgb 0.4 }

en cuyo caso se obtiene un vector de 3 componentes. Por tanto el 0.4 da como resultado <0.4,0.4,0.4,0.0,0.0>, con un cero por defecto para el filtro y la transmisión.

Finalmente hay otro problema que surge cuando se utilizan operadores punto en las directivas #declare o #local. Considera estas directivas:

 #declare MiColor = rgb <0.75, 0.5, 0.75>;
#declare CantRojo = MiColor.red;

EL identificador CantRojo debería ser un valor en coma flotante pero desafortunadamente es un color. POV-Ray mira en el primer identificador que aparece después del igual para intentar adivinar que tipo de identificador se quiere usar. Ve el identificador de color MiColor y asume que lo que se quiere es declarar un color. Entonces se calcula el valor en coma flotante como 0.75, lo cual pasa a ser rgbft<0.75,0.75,0.75,0.75,0.75>. Arreglar este problema requeriría una reescritura importante del programa, por eso nos limitamos a avisar sobre ello. Cualquiera de los siguientes ejemplos funcionará adecuadamente.

 #declare CantRojo = 0.0+MiColor.red;
#declare CantRojo = 1.0*MiColor.red;
#declare CantRojo = (MiColor.red);