Tutorial de POV-Ray

Contenido

Generalidades de este texto

Esta página está diseñada intencionalmente sin frames para facilitar la lectura lineal del contenido. De todas formas se incluyen links al comienzo de la página para saltar a alguna sección determinada si así se lo desea.

El texto utiliza hojas de estilo separadas para pantalla e impresora, de modo de permitiruna buena reproducción en ambos medios.
Un buen navegador que implementa las hojas de estilo de modo de respetar este tipo de esquemas es el Opera, que además tiene una buena vista preliminar de la impresión.

Cada ejemplo está formado por tres partes:

La idea es seguir este tutorial con el POV-Ray ya instalado en la máquina, para poder hacer experimentos a lo largo de él así como para consultar su ayuda por detalles que aquí no pueden ser mencionados.

El link para conseguir esto y muchísimo más no es otro que El Sitio oficial del POV-Ray

Por ultimo, quiero aclarar que pese a los nombres en inglés de los archivos y las imágenes, todas son de mi autoría. Los nombres en inglés los uso solo porque son mas cortos y fáciles de escribir que en español, nada más.

Por dudas o consultas sientanse libres de escribirme a Ignacio Ramirez

El POV-Ray: Que es y para que sirve?

El POV-Ray es un programa freeware que permite generar escenarios de altísima calidad fotográfica y realista a partir de archivos de texto ASCII ordinarios (comunmente distinguidos con la extensión .POV) que contienen una descripción del escenario en un formato fácilmente editable y entendible por usuarios.
El nombre POV-Ray es una sigla para el verdadero nombre: Persistence Of Vision Raytracer, siendo la primera parte en honor al cuadro de Dalí del mismo nombre (en español por supuesto).
Es importante notar que no es un programa de modelado, es decir, no dispone de una interfaz de usuario amigable para "esculpir" escenarios, etc. Sin embargo existen una buena cantidad de excelentes programas de modelado pensados para el POV-Ray para aquellos que lo deseen (los mas comunes listados al final del texto). La principal tarea del POV-Ray es la de generar las imágenes utilizando el método de Raytracing brevemente discutido más adelante.

Un poquito de historia

Si bien esto no es imprescindible, a mi particularmente me encanta la historia de este programa así que quise agregarlo de todos modos.

Sus orígenes datan del año 1987 en un programa llamado DKBTrace que fue escrito por David K. Buck (DKB) para la Commodore Amiga 500. A principios de los 90' surge la primera versión de POV-Ray, 0.5b, y yo recién la descubrí en el año 1995 en una BBS.
En aquel entonces tenía una 486DLC sin coprocesador matemático, y el primer ejemplo que aquí se presenta, que hoy no demora más de 1 o 2 segundos, llevó más de 5 horas para completarse en aquella máquina.

En aquella época existían aparte del POV-Ray dos o tres programas más del mismo tipo, también freeware, pero de inferior calidad. Con el tiempo el POV-Ray evolucionó y aumentó en complejidad hasta ser lo que hoy es, en su versión 3.1 y a punto de salir la 3.5, un programa extremadamente vasto y complejo con miles de opciones, disponible principalmente para Linux, Windows y Macintosh.
Su código es abierto y distribuído libremente, por lo que cualquiera puede modificarlo y/o compilarlo a gusto en su plataforma preferida.
Existen miles de utilidades diseñadas para usar con este programa: modeladores, conversores de otros formatos (3D Studio, etc), generadores de terrenos, objetos, texturas, etc.
El prestigio alcanzado por este programa se refleja en una gran cantidad de seguidores de todo el mundo que utilizan el programa con fines tanto artísticos como de trabajo.

El Raytracing

Existen desde hace ya más de 20 años sistemas de generación de imágenes tridimensionales de varios tipos.
Estos programas se dividen en dos grandes famílias: rendering poligonal y raytracing.

La técnica de Raytracing se basa en emular el comportamiento de la luz utilizando las ecuaciones que rigen los efectos ópticos presentes en la naturaleza, básicamente: reflección, absorción, difracción y difusión.
No cabe aquí una descripción detallada, pero por ahora diremos que para generar una imágen el sistema utiliza una cámara ficticia que tiene como filme a la propia imágen a generar. Por cada píxel de la imágen, el raytracer recorre el camino inverso de la luz partiendo desde el ojo de la cámara hacia el escenario. Cada rayo es testeado contra todos los elementos del escenario y de allí se determina el "color" que ese rayo traerá de vuelta hacia la cámara.

diferencias del raytracing con otros sistemas de rendering

En el rendering poligonal el escenario y sus figuras son descritas en forma explícita por conjuntos de puntos que conforman las distintas superficies de los objetos presentes en la escena, y por texturas también descritas explícitamente por bitmaps que son "pegados" alrededor de los objetos a representar.

En el raytracing las imágenes pueden ser representadas en forma implícita por ecuaciones matemáticas aunque también pueden utilizarse las técnicas anteriormente descritas. También es posible describir las texturas en forma implícita mediante ecuaciones y procedimientos. La flexibilidad es virtualmente infinita en este sentido, lo que da lugar a mucha más expresividad potencial.

Características sobresalientes del POV-Ray

El POV-Ray adminte una vasta cantidad de formas además de las básicas: esferas, planos, cubos, todas las superficies cuadráticas, bicúbicas y cuárticas (4to orden!), así como splines, bezier, fractales, superficies de revolución, CSG, blobs.
También dispone de varios tipos de cámara (ojo de pez, ortogonal, omnimax, esférica, perspectiva), luces (puntual, spots, area).
Lo más impresionante es sin duda la parte de texturas, con docenas de tipos de mapeo (además de permitir texturas "mapeadas", es decir, bitmaps explícitos) mapas de color, efectos de "warp", turbulencia ajustable, docenas de parámetros ópticos ajustables, interiores, efectos atmosféricos, gases incandescentes, etc.

Ventajas y desventajas

Es extremadamente flexible, las posibilidades son infinitas, la calidad de las imágenes producidas no tiene límite. Es por eso que se utiliza mucho más con fines artísticos que como herramienta industrial.

Puede ser extremadamente lento para producir una buena imágen debido a la cantidad de cálculos implicados. Es necesaria una buena dósis de experiencia para producir resultados satisfactorios, y muuucha paciencia.

Primer ejemplo

Esto es, a pesar de sencillo, todo un ritual de iniciación en el raytracing.
Les presento el famoso Red Ball Over Checkered Floor.

Notar que a pesar de la sencillez hay algo que ya es distinto de los sistemas poligonales : los bordes de la esfera son totalmente lisos, cosa que en general no sucede con los poligonales. Esto es debido a la naturaleza implícita de la superficie representada.
Aqui está el contenido del archivo, por esta vez todo completo:

#include "colors.inc"
#include "textures.inc"
#include "shapes.inc"       

sphere { <0,1,0>,1             
  texture {
    pigment { color rgb <1,0,0> }
   }
}   

plane { <0,1,0>,0
  texture {
    pigment { 
      checker 
        pigment {color White}, 
        pigment{color Green} 
    } 
  }
}

camera {
  location <0,0.5,-4>
  sky <0,1,0>
  right <4/3,0,0>
  look_at <0,1,-1>
}

light_source { <5,3,-5> color White }

Cada parte será comentada a su vez.

El archivo

Aquí está el archivo POV.

Antes que nada veamos la cabecera del archivo.

#include "colors.inc"
#include "textures.inc"
#include "shapes.inc"       

Estas tres líneas utilizan una sintaxis muy similar a la del preprocesador del lenguaje C para incluir el contenido de los archivos textures.inc, shapes.inc y colors.inc en la escena.

La extensión .inc se utiliza por convención para este tipo de archivos utilitarios. En partiticular estos definen algunas formas, texturas y colores comunmente utilizadas en POV-Ray (por ejemplo los colores White y Green).

El objeto

Veamos pues ahora como se describen los objetos. La estrella de esta escena es sin duda la pelota roja, que está descrita así:

sphere { <0,1,0>,1             
  texture {
    pigment { color rgb <1,0,0> }
   }
}   

Esto indica al programa que debe incluir en el escenario a una esfera con centro en <0,1,0>, es decir, x = 0, y = 1 y z = 0 y de radio = 1 (la sintaxis completa es centro,radio).
Estos son los parámetros de la forma en sí y varía en cada tipo de forma. Por ejemplo, un cilindro se describe como centro1,centro2,radio y un cilindro centro1,radio1,centro2,radio2.

Luego de los parámetros de la forma viene la textura (bloque texture). En este caso la textura más básica posible es la formada por un sólo color, definido en el bloque pigment. Pigment se utiliza para muchas cosas más, pero aquí solo se define como un color liso con componentes rgb <1,0,0> es decir R = 1, G = 0 y B = 0.
Los valores para cada componente van entre 0 y 1, aunque se pueden hacer cosas raras con valores negativos o mayores que 1 (experimentarum). En este caso el color es Rojo puro.

Nota:

El POV-Ray utiliza el sistema de coordenadas de mano izquierda. Esto implica en general que si tenemos al vector X apuntando hacia nuestra derecha, el vector Y apuntará hacia arriba y el Z hacia el frente. Tecnicamente, Y^X = Z.
Esto contraría al sistema clásico de mano derecha, utilizado entre otras cosas en los cursos de álgebra dictados en nuestra facultad.

La cámara

camera {
  location <0,0.5,-4>
  sky <0,1,0>
  right <4/3,0,0>
  look_at <0,1,-1>
}

Este bloque define la cámara del escenario (única).
Los parámetros definidos son los mínimos necesarios:

location
indica la posición del punto de visión u ojo de la cámara.
sky
indica adonde está "arriba" para la cámara. En este caso la cámara está totalmente vertical.
right
Cumple dos funciones. La primera es determinar hacia donde queda la "derecha" de la cámara. Si en lugar de ser 4/3 fuera -4/3, tendríamos un sistema de mano derecha en lugar de mano izquierda!
Además, permite definir el aspect ratio o relación de aspecto de la escena, es decir, la proporción entre el ancho y el alto de un píxel.
En este caso 4/3 es el que hay que utilizar en imágenes de relación 4/3 (320x240, 640x480, 1024x768, etc).
look_at
Como su nombre lo dice, indica hacia donde mira la cámara. Esta es la forma más sencilla de dirigir la cámara, hay otras más complicadas pero a veces necesarias

La luz

light_source { <5,3,-5> color White }

Por supuesto, sin luz no se puede ver nada no? Bueno, una lucecita es lo mínimo que necesitamos para ver algo y la podemos definir de esta manera.

Esta sintaxis define una fuente de luz puntual con centro en (5,3,-5) y de color blanco.
Notar que a pesar de que esta es una fuente de luz, si uno apunta la cámara hacia ella no se ve nada porque no es un objeto en sí.
Existen muchos mecanismos para darle visibilidad a la luz, pero no entraremos en ellos ahora.

Texturas

Muy bien, tenemos una lisa y aburrida pelota sobre un piso cuadriculado.
Estamos aún muy lejos de impresionar a alguien no? Es un largo camino. Veamos que se puede hacer...

finish

Primero vamos a agregarle algo de brillo a la pelota, es decir, una terminación (de ahí finish). Veamos como queda:

Aquí está el archivo POV.

Los cambios en el código los pueden ver en negrita:

sphere { <0,1,0>,1             
  texture {
    pigment { color rgb <1,0,0> }
    finish { 
		phong 1.0 
		phong_size 20.0 
	}
   }
}   

El bloque finish es donde se definen los parámetros ópticos de la superficie: reflexión, refracción (si la pelota es transparente), índices de difusión, brillosidad, luz ambiente.

En este caso agregamos a la superficie brillo especular utilizando las formulas de Phong (un chino que modelo este efecto).

El brillo phong toma un parámetro obligatorio que indica qué tanto de la fuente de luz habrá en el centro del brillo. En este caso 1.0 indica que el color en ese punto será totalmente determinado por el color de la luz (sugerencias: probar agregar otra luz, cambiar el color de la luz o el propio parámetro a ver que pasa).
Hay un segundo parmaétro opcional definido por phong_size.
Mientras más grande és más pequeño será el punto brillante y la superficie parecerá más pulida.
Por último, existe una alternativa más exacta y realista que phong aunque levemente más lenta que es utilizando los parámetros specular y roughness que no serán tratados aquí.

Bola de flipper

Ahora, que tal si queremos una esfera de metal azulado y reflejante?? A ver esto:

Aquí está el archivo POV.

sphere { <0,1,0>,1             
  texture {
    pigment { color rgb <0.6,0.6,0.8> }
    finish { 
		phong 1.0 
     phong_size 50.0 
      	metallic
      	reflection 0.2
      	diffuse 0.5
      	brilliance 10
      	ambient 0.1
	}
   }
}   

Primero le aumentamos un poco el phong_size para darle una sensación de más pulida.
Luego la palabra metallic indica que el reflejo de las luces debe ser metálico lo que implica que el color del reflejo sea el mismo color que el de la superficie, en lugar de ser el de la propia luz. Notar cómo el centro del reflejo phong es ahora azulado en lugar de blanco como antes.
reflection 0.2 indica que el color visto de la superficie proviene en un 20% del reflejo del resto del escenario y un 80% de la superficie en sí.
diffuse 0.5 indica que el 50% de la luz que llega a la superficie será reflejada hacia afuera (o sea, lo que veremos desde la cámara de ella será 50% debido a la luz).
ambient 0.1 indica que la superficie ya tiene de por sí un 10% de luz atribuída a una luz "ambiente" o global totalmente ficticia. Es decir que si no hubieran fuentes de luz en el escenario veríamos aún así un círculo chato, sin sombras, del 10% del color de la superficie.

Bola de cristal

Que tal si queremos modelar una gitana diciendo la fortuna? No hay Gitana que no tenga su famosa bola de cristal...

Aquí está el archivo POV.

Los cambios que se hicieron aqui son pocos y sin embargo vean los efectos que producen!

sphere { <0,1,0>,1             
  texture {
    pigment { color rgbt <1.0,0.85,0.7,0.9> }
    finish { 
	phong 1.0 
	phong_size 200.0 
    reflection 0.1
    diffuse 0.0
 refraction 0.9
	ior 1.5 
	brilliance 10
    ambient 0.0
    }
   }
}   

Por supuesto que están esos tres cilindros, pero los agregué sólo para ejemplificar. Pueden verlos en el archivo fuente

refraction 0.9 indica que 90% de la luz que veremos desde la esfera proviene de rayos refractados a través de ella. Esto tiene que ser acompañado por una cierta transparencia de la bola. Notar que ahora color es un vector de tipo rgbt con t de transparencia. En este caso tenemos un color que es 90% transparente y 10% opaco.
En lugar de t se puede utilizar f que indica filter. En este último caso la luz no es simplemente transparentada sino que es filtrada por el propio color de la esfera. Si la esfera fuera roja como antes, sólo los componentes rojos de lo que hay atrás podrían verse.
ior 1.5 especifica el indice de refracción de la superficie. Este índice determina que tanto se "tuerce" la luz al pasar por la superficie.
Si ior fuera 1.0 no habría distorsión. Para fijar ideas, ior 1.33 es el índice de refracción del agua, 2.7 es el del diamante, el mayor existente.

pigment

Digamos ahora que nuestra radio se trancó inevitablemente en Galaxia FM 105.9 y no la podemos apagar y la música nos influye subconcientemente por lo que nos viene el deseo irrefrenable de agregarle mucho color mezclas de color a la pelota. Nuestras manos involuntariamente se mueven y llegamos a esto:

Que he hecho?! Acá está lo que has hecho: la pelota villera

archivo POV.

El código que produce la imágen anterior (quitando las luces extra)

sphere { <0,1,0>,1             
  texture {
    pigment { 
 bozo 
      color_map {
       [0 0.2 color White color Red ]
       [0.2 0.4 color Red color Green ]
       [0.4 0.6 color Green color Blue ]
       [0.6 0.8 color Blue color Green ]
       [0.6 0.8 color Green color White ]
      }
      turbulence 0.4
    }

    finish { 
		phong 1.0 
	  phong_size 20.0 
    }
   }
}                                    


plane { <0,1,0>,0
  texture {
    pigment { 
      onion 
      color_map {
        [ 0 0.1 color Yellow color Yellow ] 
        [ 0.1 0.3 color Yellow color Red ]
        [ 0.3 0.8 color Red color Black ] 
        [ 0.8 0.99 color Black color Black ] 
      } // color_map     
      turbulence 2
    } // pigment
	// por ahora no tocaremos estas dos lineas, si bien es facil 
	// darse cuenta lo que hacen
    translate 1*y
    scale <0.2,2,2>*0.5

  } // texture
}

Aquí entran 3 cosas esenciales en el confeccionamiento de texturas:

patrones de textura

bozo y onion son sólo dos de los muchos patterns disponibles para simular texturas. Tambien hay wood, checker, gradient, leopard y otros tantos.
Tecnicamente, son campos escalares (vieron como álgebra y cálculo sirven para algo?), es decir, funciones R^3->R, que toman valores entre 0 y 1.
En particular bozo es una función bastante compleja, continua, que se utiliza sobre todo para simular nubes y onion es tal que onion(X) = |X| mod 1

color_map

Ahora, estas funciones toman valores en el rango [0,1). Que hace el POV-Ray con esos valores? Para ello existe el color_map. Este bloque especial permite asignar un color para cada valor entre 0 y 1 que pueda tomar un punto en el espacio. En la forma más sencilla, como se presenta aquí, esto implica una interpolación lineal.
Cada entrada del color_map permite definir un rango de valores por un valor inicial y uno final y los colores asignados a esos extremos. Todos los valores intermedios son obtenidos de la interpolación lineal de esos colores a lo largo del rango formando un gradiente.

En este caso tenemos para la textura del piso (que intenta ser una especie de atigrado) que para todos los puntos P del espacio que pertenecen al plano que:

Cabe notar que se admiten discontinuidades entre un rango y otro

turbulencia

Ahora, nadie me va a creer que la función f(X) = |X| mod 1 (norma de X módulo 1) tiene esa forma verdad?? En todo caso, se verían círculos concéntricos.
Veamos que pasa si quito turbulence de la escena:

Creo que queda claro el propósito de turbulence. Lo que esta función hace es "simplemente" agregar una especie de ruido continuo (llamado DNoise) al espacio antes de evaluar el campo escalar.

Esto no es simplemente un campo vectorial como podría suponerse. En realidad es un algoritmo que aplica repetidamente un campo vectorial (R^3-R^3) llamado justamente función DNoise (Dimentional Noise) para lograr esa agitación.
El parámetro que acompaña a turbulence es la magnitud de la "agitación" y suele ser difícil embocarle al valor que produce el efecto deseado.

normal

Para culminar este ejemplo ultra-ultra-ultra-básico agreguemos algo más de lo imprescindible.

Supongamos ahora que no queremos una hermosa pelota lisita sino que preferimos algo así como una pelota de Golf. Todos sabemos que las pelotas de golf vienen todas defectuosas, llenas de abolladuras por todos lados.
Sin embargo en este caso nos interesa el realismo y si las pelotas de golf son así, que le vamos a hacer?

El POV-Ray permite simular superficies no lisas, alterando en forma aparente la normal de la superficie. Veamos entonces que se puede hacer con respecto a la pelota de golf:

archivo POV

El código principal es:


sphere { <0,1,0>,1             
  texture {
    pigment { color rgb <0.9,0.9,0.9> }
    finish { 
		phong 1.0 
	  phong_size 20.0 
	  ambient 0.5         
	  diffuse 0.5
    }             
 normal { leopard -0.5 }
    scale 0.043
   }
}                                    

// Pasto
plane { <0,1,0>,0
  texture {
    pigment { color Green } // pigment
    finish { ambient 0.5 }
 normal { wrinkles 5.0 } 
    translate y*1
    scale 0.05
  } // texture
}               

Nuevamente hice trampa y agregué alguna cosita más, que también creo es bastante intuitivo darse cuenta lo que hace ;=)

// Cielo
sky_sphere { 
  pigment { 
    gradient y
    color_map { 
      [0 0.6 color White color Blue ] 
      [0.6 1.0 color Blue color Blue ]
    }
  } 
}

Tenemos aquí dos patterns de normal aplicados: wrinkles ("arrugas" en inglés) y leopard.
El primero utilizado para el pasto da buenos resultados.
El segundo, leopard, es una función muy sencilla: sqrt((sin(x)+sin(y)+sin(z))/3), una especie de sinusoide tridimensional y da el efecto de "pelotitas" deseado.
La primera conclusión sorprendente de esto, y que muestra el potencial del POV, es que estos patrones son los mismos que se utilizan para las texturas e inclusive para ciertos efectos ambientales, como veremos más adelante.
Es decir que bozo, onion, wood, checker, etc, etc se pueden utilizar indistintamente tanto en normal como en pigment!

En todo caso, el parámetro que acompaña al pattern indica la intensidad de la perturbación aplicada.

Por último, otra cosa reutilizable es la turbulencia. Veamos como queda la pelota de golf luego de ser usada en 462 campeonatos:

archivo POV


sphere { <0,1,0>,1             
  texture {
    pigment { color rgb <0.9,0.9,0.9> }
    finish { 
		phong 1.0 
	  phong_size 20.0 
	  ambient 0.5         
	  diffuse 0.5
    }             
    normal { leopard -0.5
		turbulence 1.0 
	}
    scale 0.043
   }
}                                    

A esta altura creo conveniente hacer notar algo: las transformaciones (rotate, translate y scale) pueden ser aplicadas a distintos niveles. Por ejemplo, si aparecen dentro de los bloques pigment o normal sólo afectarán a los patterns de pigment o normal respectivamente. Si en cambio aparecen a nivel de textura afectarán por igual a todos los bloques internos.
Lo mismo se aplica si aparecen a nivel de objeto, como veremos más adelante.

Texturas en capas

Pero Esto recién empieza! POV-Ray permite que una textura se defina como varias capas de distintas texturas, una encima de la otra. Por supuesto que para que esto tenga sentido las capas superiores deben tener algo de transparencia.

Para ello veamos un ejemplo medio rebuscado: un piso de magma ardiente.
Se me ocurre que esto estaría bien modelado por una capa inferior de colores rojos y amarillos y una costra de roca enfriada gris-azulada por encima.
Veamos como queda:

archivo POV


#declare Transparente = color rgbt <1,1,1,1>
#declare Frio = color rgb <0.3,0.3,0.4>

plane { <0,1,0>,0
  // esta queda abajo
  texture {
    pigment {
      bozo 
      color_map {
        [ 0 0.5 color Red color Yellow ]
        [ 0.5 1.0 color Yellow color Red ]
      }                                  
    }
    // esto es para que esté totalemte "iluminado"
    // y no reaccione a la luz, para que parezca que tiene
    // luz propia. 
    finish { ambient 1.0 diffuse 0.0 } 
  }                  
  // esta queda arriba
  texture {
    pigment { 
      crackle 
      color_map {
        [ 0 0.02 color Transparente color Transparente ]
        [ 0.02 0.1 color Red color Frio ]
        [ 0.1 1.0 color Frio color Frio ] 
      }                    
      turbulence 0.5
    } // pigment
    finish { ambient 0.2 }
    // un poco de rugosidad
    normal { wrinkles 1.0 turbulence 0.4 scale 0.1 }
  } // texture

}               

Esta vez dejo a ustedes el ejercicio de entender cada parte.
Basta con notar que pueden agregarse todas las capas que se desee y que estas aparecerán según el orden en que se definen, la segunda por sobre la primera, la tercera sobre la segunda, etc.

Otro artilugio interesante es la linea que dice

finish { ambient 1.0 diffuse 0.0 }

Que se suele utilizar para dar la sensación de brillo propio a un objeto. Esto lo que hace es simplemente hacer que la luz ambiente sea 1 (iluminación total y uniforme) y a la vez evita que las luces reales del ambiente modifiquen la luminosidad (diffuse o).

Notarán que también colé un par de líneas nuevas: los #declare son parte del preprocesador y permiten definir símbolos que luego pueden ser utilizados en lugar de objetos, vectores, colores, texturas y virtualmente todos los tipos de elementos presentes en un escenario.

Mapas de texturas

Al igual que existe color_map, existen también recursos análogos para mezclar texturas, pigmentos y normales.
La sintaxis es idéntica a color_map y los patterns utilizados son los mismos que en pigment o normal (bozo, onion, wood, etc).

Volvamos como ejemplo a nuestra pelota de golf, ahora apoyada sobre un suelo medio gastado, con lamparones de tierra sin pasto.

Para modelar esto apelaremos a un texture_map que va desde una textura tierra a una textura pasto. Notar el uso de #declare en este caso aplicado a texturas.

archivo POV

#declare Pasto = texture {
    pigment { color Green } // pigment
    finish { ambient 0.5 }
    normal { wrinkles 5.0 }
    translate y*1
    scale 0.05
  } // texture   
  
#declare Tierra = texture {
    pigment { color <0.5,0.4,0.2> } // pigment
    finish { ambient 0.5 }
    normal { granite 0.8 }
    translate y*1
    scale 0.05
}


plane { <0,1,0>,0    
  texture {
    bozo           
    turbulence 0.5
    texture_map {
     [ 0.0 Pasto  ] // sintaxis alternativa para *_map solo se especifica el punto inicial
     [ 0.4 Pasto  ] 
     [ 0.7 Tierra ]
    }
  }
}               

Texturas explícitas

Cuando todo lo demás falle podemos recurrir a las viejos y queridos bitmaps para usarlos como texturas.
Veamos un pequeño ejemplo:

archivo POV

Hay algo raro con la luz verdad?
De todas formas, por ahora concentrémonos en la textura, ya veremos que pasó con la luz en su debido tiempo.
Hete aquí el código del cuadro:

box { <0,0,0>,<1.2,1.2,0.15>                            
  // textura en 3 capas: un cuadrito de Wes Montgomery con marco, foto y vidrio protector

  // marco plateado
  texture { Chrome_Texture }

  // foto
  texture {
    pigment { 
      image_map { 
        gif "wes.gif"
        map_type 0 // 0 = plano, 1 = esferico, 2 = cilindrico
        interpolate 2  // interpolación bilineal    
        once // que no se repita
      }
    }  
    finish { diffuse 0.9 }
    translate 0.1*x+0.1*y // x e y son constantes del sistema: x = <1,0,0> y = <0,1,0>
  }           
  
  // vidrio
  texture {  
    Glass     
  }

  scale 3 // agrando el cuadro
  rotate    -15*y+10*x // lo roto un poquito hacia la derecha y lo inclino un poco hacia arriba
  translate -2*x // 
  
}

Como no podía ser de otra forma, esta también viene con extras.
En este caso utilicé dos texturas predefinidas de las cientos que el POV-Ray ya trae para que nosotros utilicemos. En este caso un metal para el marco del cuadro, llamado Chrome_Texture y un vidrio para cubrir el cuadro con textura Glass.
El POV-Ray trae cientos de estas texturas. También trae una serie de archivos POV de ejemplo que hacen las veces de catálogo para poder ver como quedan.

Pero bien, la parte interesante aquí es image_map. Este tipo de pigmento toma una imágen desde un archivo y mapea los píxels sobre la superficie deseada.
en realidad la correspondencia "punto del espacio"-"pixel de la imagen" está dada por el tipo de mapeo map_type.
El mapeo plano (tipo 0) se basa sólamente en las coordenadas x e y.
Sin transformaciones, la imágen entera es proyectada sobre el cuadrado que va desde <0,0,0> a <1,1,0>. La coordenada Z no importa en este caso.
El mapeo esferico utiliza coordenadas esféricas (es decir, se basa en ángulos sin importar el radio) referidas al origen del escenario.
Por último el mapeo cilíndrico utliza las coordenadas cilíndricas Y y phi, siendo phi el ángulo del vector respecto a X. En este caso el radio tampoco importa.
Por último interpolate permite suavizar la imágen proyectada (antialias).

Texturas de mapeo explícito

[pendiente]

Formas

Pasemos al otro punto principal que son las formas nada mas y nada menos.

Aquí también hay un gran arsenal de formas para elegir.

Básicas

A continuación vemos una imágen compuesta por varias formas básicas a modo de vidriera. El código será comentado por partes:

archivo POV

Superficies Cuadricas

El código de la imágen anterior contiene las siguientes cuádricas definidas:

sphere { <0,0,0>,0.8 // centro, radio
  pigment {White_Marble } 
  translate -2*x-1.5*z+0.8*y
}

plane { <0,1,0>,0 // vector normal, offset ( N·X = offset )
  texture {
    pigment { DMFLightOak }
    finish { reflection 0.1 diffuse 0.9 } 
  }
}

Las superficies cuádricas son las típicas superficies estudidas en cálculo II por ejemplo. esferas, cilindros, conos, planos, paraboloides, hiperboloides, etc.
Salvo las esferas y elipsoides, todas las demas son virtualmente infinitas para el Raytracer, ya que representan un conjunto de puntos en el espacio que cumplen una cierta ecuación (superficies de nivel).
Hasta ahora hemos visto casi exclusivamente este tipo de objetos (las pelotas y los planos).
El hecho de que sean infinitas no implica en absoluto que sean lentas de calcular u ocupan mucha memoria, por lo contrario son los más rápidos y fáciles de calcular!.

Si uno no está contento con las superficies provistas por POV-Ray, es posible incluso definirlas en función de todos los coeficientes de la ecuación (son unos cuantos). Para exquisitos solamente.

Variantes finitas

Por comodidad se definen en POV-Ray una serie de variantes finitas de las cuádricas.
En realidad éstas son implementadas en función de las anteriores. Un ejemplo es box que aparece en la imagen del cuadro.

Aquí se ve la parte que define las cuádricas finitas:


// marco del espejo
box { <0,0.0,0>,<1.3,1.3,0.15>                            
  // vidrio
  texture { Chrome_Texture }

  translate 0.01*z-0.05*x-0.05*y
  scale 5 // agrando el cuadro
  rotate    -25*y+1*x // lo roto un poquito hacia la derecha y lo inclino un poco hacia arriba
  translate -5*x+3*z // 
}

// espejo
box { <0,0.1,0>,<1.2,1.2,0.15> // esquina1, esquina2 
  // vidrio
  texture { Mirror }

  scale 5 // agrando el cuadro
  rotate    -25*y+1*x // lo roto un poquito hacia la derecha y lo inclino un poco hacia arriba
  translate -5*x+3*z // 
}

cone { <0,0,0>,0.7 <0,1,0>,0.0 // centro1,radio1,centro2,radio2
  texture { Chrome_Texture } 
  translate 4*y+1*x-1*z
  scale 1
}

cylinder { <0,0,0>,<0,0.2,0>,1.5 // centro1,centro2,radio
  texture { Brass_Texture } 
  translate 1*x-2*z
}

box { <0,0,0>,<0.5,4,2> 
  texture {
    pigment { color rgb <0.9,0.6,0.3> }
    finish { 
      brilliance 1.5 diffuse 0.7 
      specular 0.5 roughness 0.0001 
    }
  }
  translate 3*x
}

No entraré en detalle de cada una de ellas. Es fácil ver como funciona la sintaxis en base a los comentarios.

C.S.G.

Height Fields

Explícitas

Estrambóticas

Transformaciones

Simples

Definidas por el usuario

Luces

Tipos de luces

Luz ambiente

Cosas raras

Atmósfera y media

Niebla

Interior

Gases incandescentes/absorbentes/mixtos

Preprocesador

Delaraciones

Macros

Funciones

Animación

Ejemplo mínimo

Sintaxis de línea de comandos

Animación no es solo movimiento

Epílogo

Links