 |
Implementación
de las texturas |
Una vez vista la
teoría, ha llegado el momento de llevar las texturas a la práctica.
A continuación comentaremos cómo se ha hecho en el programa
de ejemplo (RAY.EXE).
Lo primero es leer
el fichero gráfico con la textura. Por su simplicidad se ha utilizado
el formato TGA sin comprimir, que ya explicamos en un artículo
anterior. De hecho, las rutinas que se han utilizado son exactamente
las mismas que se utilizaron entonces.
A continuación,
se ha modificado la estructura "RT_object" para añadir
las propiedades de las texturas: una variable que indica si se utiliza
textura, la imagen a utilizar y los factores de escalado (u_scale y
v_scale). También nos aseguramos de tener bien definidos los
tres ejes del objeto (EjeX, EjeY y EjeZ).
A la hora de implementar
las texturas en sí, se ha optado por "unificar" los
factores de iluminación ambiente, difusa y especular en uno solo
(el "color" del objeto), que se corresponderá con el
color que leemos de la textura. Aquí surge el primer problema,
pues se había definido estos coeficientes para que variasen entre
0 y 1, mientras que los valores leídos desde la imagen se encuentran
0 y 255. Esto se podría arreglar mediante una división,
pero hemos considerado que sería más eficiente ahorrarnos
esta operación extra, por lo que al final se ha permitido que
las tres componentes del color del objeto varíen entre 0 y 255.
Evidentemente, esto se tiene que compensar por otro lado, por lo que
las luces (que antes tomaban valores entre 0 y 255) ahora aceptan rangos
entre 0 y 1.
"La
mayor ventaja de las texturas procedurales es que ocupan poco,
pero requieren un cierto tiempo de cálculo"
|
El siguiente dilema
es dónde introducir la rutina que modificará el color
del objeto según la textura. Para modificar en lo mínimo
la estructura del programa teníamos dos posibilidades: calcular
las coordenadas de mapeado cuando se calculan las intersecciones con
los objetos o introducirlo en la rutina de calcular el vector normal
del objeto (cosa que permite aprovechar algunos cálculos que
se hacían). Al final se ha optado por la segunda alternativa,
ya que así nos ahorramos de calcular el mapeado de objetos que
tal vez sean ocultados por otros. Recordemos que la rutina de calcular
el vector normal solo se llamaba cuando ya se había encontrado
la intersección con el objeto más cercano al punto de
origen del rayo. Como veremos más adelante, en algunos casos
muy concretos es más conveniente utilizar la otra opción.
Una vez decidido
todo esto, sólo hace falta introducir las fórmulas que
hemos explicado para calcular las coordenadas de mapeado y asignar al
color del objeto el color del punto de la textura que le corresponde.
 |
Variaciones
sobre las texturas
|
Como dice en el
encabezado de este artículo, el tema de las texturas es mucho
más complejo que lo que hemos contado hasta ahora. Las posibilidades
que ofrece son enormes, tantas que sería imposible recogerlas
todas en esta sección. Así que vamos a comentar algunos
ejemplos relativamente simples de lo que se puede hacer con ellas.
 |
Otras
coordenadas de mapeado
|
Los tres tipos
de coordenadas de mapeado que hemos comentado son las más utilizadas,
las que podríamos llamar "estándar", pero en
realidad uno se puede inventar las fórmulas que quiera para obtener
las coordenadas de mapeado y conseguir efectos interesantes. Las posibilidades
son infinitas, sólo hay que ir con cuidado en que las fórmulas
utilizadas nos puedan dar un resultado no computable (infinito, por
ejemplo) o que no incurramos en una incoherencia matemática (intentar
buscar el arcoseno de un número no comprendido dentro del rango
[-1,1] o la raíz cuadrada de un número negativo). Esto
podría provocar un cuelgue total del programa y se tiene que
evitar a toda costa. Veamos un ejemplo sencillo.
Lo usual al calcular
las coordenadas de mapeado en un plano es utilizar un sistema de ejes
cartesianos, pero también se podrían utilizar coordenadas
polares:
En este caso, las
ecuaciones de las coordenadas de mapeado quedarían como:
U= atan[(EjeX·(P-Pos))/
(EjeY·(P-Pos))]/2p
V= raiz[(EjeX·(P-Pos))2+(EjeY·(P-Pos))2]
Teniendo en cuenta que estamos
en un plano, la coordenada V se puede simplificar como sigue:
V=raiz[(P-Pos)2]
"Se
pueden utilizar imágenes como máscaras de objetos, permitiendo
obtener figuras complejas a partir de objetos simples"
|
El resultado será
algo similar al efecto "túnel" que explicamos hace
tiempo, pero aplicado a un plano del raytracing.
En el CD-ROM se ha incluido
el programa VAR1.EXE (lo de VAR viene de variación) con esta
modificación, y la escena VAR_1.RAY, específica para este
programa, que muestra este efecto.
|