Vous êtes sur la page 1sur 85

Universidade de São Paulo – São Carlos, SP

Instituto de Ciências Matemáticas e de Computação

Tutorial POV-Ray

Aluna de graduação:

Nathalia Rossetti nº.5237639

Professoras:

Rosane Minghim
Maria Cristina Ferreira de Oliveira
SUMÁRIO

Índice de figuras............................................................................................3

Índice de quadros...........................................................................................5

Índice de tabelas............................................................................................7

1. Introdução..................................................................................................8

2. História......................................................................................................9

3. Adquirindo a ferramenta.........................................................................10

4. Princípios Básicos...................................................................................11

5. Objetos.....................................................................................................14

6. Textura.....................................................................................................28

6.1 Forma Geral......................................................................................................28

6.2 Tipos de pigmentação.......................................................................................31

6.3 Finalização........................................................................................................40

6.4 Normal..............................................................................................................48

7. CSG.........................................................................................................58

8. Iluminação...............................................................................................65

9. A linguagem............................................................................................71

10. Animações.............................................................................................78

11. Conclusão..............................................................................................82

2
LISTA DE FIGURAS

Figura 3.1 Imagens geradas pelos códigos inclusos no pacote POV-Ray ..11
Figura 4.1 Eixo de coordenadas do POV-Ray e exemplo da mão direita...12
Figura 5.1 Cores inclusas na biblioteca “colors.inc”...................................16
Figura 5.2 Exemplo da cena de uma esfera vermelha sem iluminação.......18
Figura 5.3 Exemplo da cena de uma esfera vermelha iluminada................20
Figura 5.4 Cilindro......................................................................................21
Figura 5.5 Cone...........................................................................................21
Figura 5.6 Caixa..........................................................................................22
Figura 5.7 Triângulo....................................................................................22
Figura 5.8 Bolha..........................................................................................23
Figura 5.9 Esfera no centro de um disco.....................................................24
Figura 5.10 Arquivo de imagem e campo alto da imagem no POV-Ray....25
Figura 5.11 Exemplificação da regra da mão esquerda para rotações........27
Figura 5.12 Toro que passou por transformações.......................................28
Figura 6.2.1 Esfera com pigmentação gradiente.........................................32
Figura 6.2.2 Esferas com diferentes valores de pigmentação gradiente.....33
Figura 6.2.3 Turbulência aplicada em uma esfera.......................................33
Figura 6.2.4 Esferas com pigmentação mármore........................................34
Figura 6.2.5 Esfera com pigmentação ágata................................................35
Figura 6.2.6 Esfera com pigmentação palhaço............................................36
Figura 6.2.7 Esfera com pigmentação manchada, granito, leopardo e
madeira respectivamente.........................................................36
Figura 6.2.8 Esfera com pigmentação tabuleiro de xadrez.........................37
Figura 6.2.9 Esfera com pigmentação hexágono........................................38
Figura 6.2.10 Arquivo de imagem e pigmentação mapeamento de imagem
no POV-Ray..........................................................................39
Figura 6.3.1 Diferença entre uma esfera padrão e uma com iluminação
Ambiente................................................................................41
Figura 6.3.2 Esfera com brilho....................................................................41
Figura 6.3.3 Esfera com finalização crand..................................................42
Figura 6.3.4 Esfera com difusão..................................................................43
Figura 6.3.5 Caixa e esfera com finalização phong....................................44
Figura 6.3.6 Esfera com diferentes valores de phong size..........................44
Figura 6.3.7 Esfera com finalização metálica.............................................45
Figura 6.3.8 Esfera com finalização pálida e valores de valores de
Rugosidades............................................................................46
Figura 6.3.9 Esfera com reflexo..................................................................47
Figura 6.3.10 Esfera com refração e diferentes valores de ior....................48
Figura 6.4.1 Cena de uma esfera comum....................................................50

3
Figura 6.4.2 Esfera batida............................................................................51
Figura 6.4.3 Esfera acidentada....................................................................51
Figura 6.4.4 Esfera com normal ondulação.................................................52
Figura 6.4.5 Esfera com normal oscilação..................................................52
Figura 6.4.6 Esfera com normal ruga..........................................................53
Figura 6.4.7 Cone com finalização normal.................................................55
Figura 6.4.8 Plano com finalização normal.................................................55
Figura 6.4.9 Esfera com textura Jade..........................................................56
Figura 6.4.10 Textura contidas na biblioteca (Parte 1)...............................57
Figura 6.4.11 Textura contidas na biblioteca (Parte 2)...............................57
Figura 7.1 Exemplo matemático de união...................................................59
Figura 7.2 União feita com triângulos.........................................................60
Figura 7.3 Diferença entre união e junção..................................................61
Figura 7.4 Exemplo matemático de diferença.............................................61
Figura 7.5 Diferença entre união e diferença..............................................62
Figura 7.6 Exemplo matemático de intersecção..........................................62
Figura 7.7 Diferença entre união e intersecção...........................................63
Figura 7.8 Exemplo matemático de inversão..............................................63
Figura 7.9 Diferença entre união e inversão................................................64
Figura 8.1 Cena com iluminação pontual simples......................................67
Figura 8.2 Cena com foco de luz pontual....................................................68
Figura 8.3 Cena com foco de luz pontual com fallof maior que radius......68
Figura 8.4 Cena com foco de luz e tightness...............................................69
Figura 8.5 Cena com iluminação feita por uma área luminosa...................70
Figura 8.6 Cena com iluminação feita por uma área de foco luminoso......71
Figura 9.1 Cena feita utilizando declaração de objetos...............................73
Figura 9.2 Cena feita utilizando declaração de texturas..............................74
Figura 9.3 Cena feita utilizando declaração de controle de fluxo...............78
Figura 10.1 Cena que será utilizada para animação....................................79
Figura 10.2 Frames gerados pela animação no POV-Ray...........................80
Figura 11.1 “Christmas Baubles” feita pelo artista Jairo Vives Piqueres...83
Figura 11.2 “Glasses” feita pelo artista Grilles Tran...................................83
Figura 11.3 “Boreal” feita pelo artista Norbert Kern..................................84
Figura 11.4 “Distant Shores” feita pelo artista Christoph Gerber...............84

4
LISTA DE QUADROS

Quadro 4.1 Exemplo de comentário............................................................14


Quadro 5.1 Exemplo de posicionamento da câmera...................................14
Quadro 5.2 Exemplo de declaração da cor de fundo...................................15
Quadro 5.3 Exemplo de inclusão da biblioteca “colors.inc”.......................15
Quadro 5.4 Exemplo de uma cena contendo uma esfera vermelha.............17
Quadro 5.5 Exemplo de luz pontual na cena da esfera vermelha................19
Quadro 5.6 Exemplo de um cilindro...........................................................20
Quadro 5.7 Exemplo de cone......................................................................21
Quadro 5.8 Exemplo de caixa.....................................................................22
Quadro 5.9 Exemplo de triângulo...............................................................22
Quadro 5.10 Exemplo de bolha...................................................................23
Quadro 5.11 Exemplo de disco...................................................................24
Quadro 5.12 Exemplo de plano infinito......................................................24
Quadro 5.13 Exemplo de campos altos.......................................................25
Quadro 5.14 Exemplo de mudança de escala, rotação e translação em um
toro..........................................................................................27
Quadro 6.1.1 Forma correta de declarar a pigmentação..............................28
Quadro 6.1.2 Exemplo de declaração de mapeamento de cor com
informação completa..............................................................29
Quadro 6.1.3 Exemplo de declaração de mapeamento de cor.....................29
Quadro 6.1.4 Forma geral da declaração de pigmentação..........................30
Quadro 6.1.5 Três maneiras diferentes de declarar a turbulência...............30
Quadro 6.2.1 Exemplo de declaração da pigmentação gradiente................32
Quadro 6.2.2 Exemplo de aplicação de turbulência....................................33
Quadro 6.2.3 Exemplo de declaração da pigmentação mármore................34
Quadro 6.2.4 Exemplo de declaração da pigmentação ágata......................34
Quadro 6.2.5 Exemplo de declaração da pigmentação palhaço..................35
Quadro 6.2.6 Exemplo de declaração da pigmentação tabuleiro de
xadrez....................................................................................37
Quadro 6.2.7 Exemplo de declaração da pigmentação hexágono...............37
Quadro 6.2.8 Forma gera da declaração de mapeamento de imagem.........38
Quadro 6.2.9 Exemplo de declaração da pigmentação mapeamento de
Imagem..................................................................................39
Quadro 6.3.1 Forma gera da declaração de finalização..............................40
Quadro 6.3.2 Exemplo de declaração do atributo ambiente........................40
Quadro 6.3.3 Exemplo de declaração do atributo brilho.............................41
Quadro 6.3.4 Exemplo de declaração do atributo crand.............................42
Quadro 6.3.5 Exemplo de declaração de difusão........................................42
Quadro 6.3.6 Exemplo de declaração do atributo phong............................43
Quadro 6.3.7 Exemplo de declaração do parâmetro “phong_size”.............44

5
Quadro 6.3.8 Exemplo de declaração do modificador metálico.................45
Quadro 6.3.9 Exemplo de declaração do atributo polido............................45
Quadro 6.3.10 Exemplo de declaração do atributo reflexão em uma cena.46
Quadro 6.3.11 Exemplo de declaração do atributo refração.......................48
Quadro 6.4.1 Forma geral da declaração da normal....................................49
Quadro 6.4.2 Código base para os próximos exemplos..............................49
Quadro 6.4.3 Exemplo de declaração de batida..........................................50
Quadro 6.4.4 Exemplo de declaração da normal acidente..........................51
Quadro 6.4.5 Exemplo de declaração de ondulação...................................51
Quadro 6.4.6 Exemplo de declaração da oscilação.....................................52
Quadro 6.4.7 Exemplo de declaração da normal ruga................................52
Quadro 6.4.8 Exemplo de declaração do mapeamento de batida................53
Quadro 6.4.9 Código de um cone com finalização normal.........................54
Quadro 6.4.10 Código de um plano com finalização normal......................55
Quadro 6.4.11 Exemplo de inclusão da biblioteca “texture.inc”................55
Quadro 6.4.12 Exemplo de declaração da textura “Jade” inclusa na
biblioteca “texture.inc”........................................................56
Quadro 7.1 Exemplo de declaração da união utilizando triângulos............59
Quadro 7.2 Exemplo de declaração de junção............................................60
Quadro 7.3 Exemplo de declaração da diferença........................................61
Quadro 7.4 Exemplo de declaração da intersecção.....................................62
Quadro 7.5 Exemplo de declaração da inversão.........................................63
Quadro 8.1 Forma geral para a declaração dos tipos de iluminação...........65
Quadro 8.2 Exemplo de declaração de iluminação pontual simples...........66
Quadro 8.3 Exemplo de declaração de foco de luz pontual........................67
Quadro 8.4 Exemplo de declaração do modificador tightness....................68
Quadro 8.5 Exemplo de declaração de área luminosa.................................69
Quadro 8.6 Exemplo de declaração de área de foco de luz.........................71
Quadro 9.1 Exemplo de declaração de objeto.............................................71
Quadro 9.2 Exemplo de referência à declaração.........................................72
Quadro 9.3 Exemplo de cena simplificada pela declaração de objeto........72
Quadro 9.4 Exemplo de cena simplificada pela declaração de texturas.....73
Quadro 9.5 Exemplo de condição if............................................................75
Quadro 9.6 Exemplo de condição switch....................................................75
Quadro 9.7 Exemplo de condição afirmativa de declaração.......................76
Quadro 9.8 Exemplo de condição negativa de declaração..........................76
Quadro 9.9 Exemplo de destruição de declaração......................................76
Quadro 9.10 Exemplo de loop.....................................................................77
Quadro 9.11 Exemplo de cena utilizando comandos de controle de fluxo.77
Quadro 10.1 Exemplo de cena que pode ser animada.................................78
Quadro 10.2 Exemplo de arquivo de animação .ini....................................79

6
LISTA DE TABELAS

Tabela 5.1 Tabela de cores inclusas na biblioteca “colors.inc”..................16


Tabela 6.4.1 Tabela de texturas inclusas na biblioteca “texture.inc”..........58

7
1- INTRODUÇÃO

O Persistence of Vision Raytracer (POV-Ray) é uma ferramenta de software


livre para a criação de gráficos tridimensionais impressionantes. O POV-Ray utiliza as
técnicas de ray tracing e é, provavelmente, uma das ferramentas mais utilizadas
atualmente, devido à sua relativa facilidade de uso, baixo custo e alta qualidade.

As cenas são descritas em uma linguagem de definição de dados denominada


scene description language. É necessário apenas digitar os comandos de definição de
objetos em um arquivo texto que o POV-Ray lê e interpreta, construindo a cena. A
linguagem possui uma sintaxe muito similar à da linguagem “C”, com comentários,
estruturas definindo objetos, blocos definidos por “{}” e diretivas de inclusão de
arquivos por “#include”. Algumas de suas características são: suporte para projeção
ortográfica e perspectiva; possibilidade de incluir vários tipos de fontes de luz;
radiosidade; primitivas, tais como cone, cilindro e esfera; técnicas de modelagem mais
avançadas, tais como superfície paramétrica Bèzier, sweep, fractais e CSG
(Constructive Solid Geometry); possibilidade de especificar as propriedades dos
materiais incluindo diferentes tipos de texturas.

O POV-Ray é o que podemos chamar de “maquina de renderização”, isto é,


damos à ele um arquivo como entrada e ele gera um arquivo de saída, mas sem muita
interface. Existem modeladores disponíveis para POV-Ray que faz esse tipo de
visualização, mas é recomendado que se tenha um conhecimento mais aprimorado do
POV-Ray antes de começar a usá-los.

8
2. HISTÓRIA

Em meados de 1986, David Kirk Buck fez o download de um código “C” para
raytracer (Unix). Ele ficou impressionado, apesar de só ter conseguido exibir esferas
planas com um piso em preto e branco, sem texturas. Resolveu, então, brincar com o
código adicionando suporte para cor, mas finalmente decidiu que poderia fazer um
trabalho melhor escrevendo um código raytracer a partir do zero, seu projeto teve o
nome de DKBTrace.

David decidiu começar com a geração de superfícies, pois assim poderia


representar esferas, elipses, cilindros, aviões e muitos outros. Para a estrutura de seu
programa, ele decidiu usar orientação a objeto, estilo Smalltalk que ele havia aprendido
na universidade e que achava que se encaixava muito bem ao problema. Para que a
modelagem se tornasse mais flexível, ele acrescentou CSG e texturas. Como David
estava planejando retornar à universidade para iniciar seu mestrado e não tinha tempo
para desenvolver um projeto comercial, ele decidiu liberar seu raytracer como um
código livre e o disponibilizou em lugares como a internet.

Só havia um programa, mas atraía um grande interesse. David liberava várias


versões do mesmo, adicionando novas funcionalidades, mais primitivas, mais opções de
texturas, etc.

Por volta de 1987 ou 1988, Aaron Collins entrou em contato com David, pois
tinha encontrado o DKBTrace e conseguiu portá-lo para personal computer, além de
acrescentar um modelo de iluminação. Finalmente, a última versão do DKBTrace, agora
portátil, foi liberada (1989).

Quando o programa provou ser mais popular do que o previsto, eles não
puderam acompanhar a demanda por mais recursos. Então, David propôs que eles
formassem uma equipe para desenvolver um novo raytracer, usando o DKBTrace como
base. Na opinião de David o código deveria continuar livre, ser portável para diferentes
plataformas e possuir um nome diferente de DKBTrace, pois este continha as inicias de
seu nome e, com uma equipe trabalhando, este nome seria inadequado.

O nome escolhido foi Persistence of Vision Raytracer, que posteriormente foi


encurtado para POV-Ray. Muitas pessoas se envolveram com o projeto, entre elas

9
estavam Drew Wells, Aaron Collins, Chris Young, Steve Anger, Tim Wegner, Dan
Farmer, Bill Pulver (IBM), e Alexander Enzmann (matemático), Chris Cason e Robert
Skinner.

Houve tanta procura para que uma nova versão fosse liberada que foi lançado o
POV-Ray 0.5. Este foi basicamente um reforço do DKBTrace, com muitas
semelhanças, entre elas a gramática, que só foi renovada no POV-Ray 1.0.

Na versão 2.0, David Kirk Buck deixou o projeto para se dedicar à outras áreas
(modelagem e animação). O POV-Ray ficou nas mãos da equipe que desenvolveu o seu
estado atual, Chris Cason é agora o lider do projeto.

Mesmo não sendo mais da equipe, David continua acompanhando o curso do


POV-Ray e admirando a obra de arte que as pessoas criam com ele, pois se sente
constantemente espantado com o que as pessoas conseguem fazer no software que
ajudou a criar.

3. ADQUIRINDO A FERRAMENTA

O POV-Ray é gratuito e pode ser baixado a partir do site oficial


<http://www.povray.org/>. O programa possui versões para Windows 9x/ME/NT/2000/
XP, Macintosh Mac OS e Mac OS X, x86 Linux e UNIX. Todo o código fonte para
cada uma dessas plataformas está disponível para aqueles desejosos de realizar suas
próprias implementações de variações ou portarem para outras plataformas. Sua
instalação e execução também é diferente para cada um dos sistemas para qual foi
implementado.

O pacote POV-Ray inclui instruções detalhadas na utilização do raytracer e na


criação de cenas com sua linguagem de definição. Muitas cenas prontas foram incluídas
no pacote, e os autores sugerem que o aprendiz inicie tomando o código pronto de uma
cena, renderizando-o, tentando entende-lo e modificando-o aos poucos, antes de tentar
criar suas próprias cenas a partir do zero.

10
Figura 3.1: Imagens geradas pelos códigos inclusos no pacote POV-Ray.

Além disso, uma biblioteca bastante extensa de formas e materiais também é


provida com o pacote. Estas formas e materiais podem se utilizados em uma cena que
você está construindo simplesmente através da inclusão da biblioteca no topo do
arquivo de definição de cena e da subsequente utilização do nome do objeto no corpo do
arquivo de cena.

4. PRINCÍPIOS BÁSICOS

Entender o funcionamento do POV-Ray é bastante simples. Damos ao POV-Ray


um arquivo contendo uma descrição de cada objeto na cena, escrita na língua POV-Ray
e, ele gera a imagem. Cada objeto da descrição consiste de duas partes:

• O objeto, em si (pode ser um objeto do POV-Ray ou um que criamos);

• Os atributos do objeto (a sua, reflexão da luz, etc.).

11
O POV-Ray utiliza um sistema tridimensional (3D) de coordenadas cartesianas.

Figura 4.1: Eixo de coordenadas do POV-Ray e exemplo da mão direita


(imagine a coordenada z saindo do computador).

Podemos usar a mão esquerda para visualizar melhor. Assim, coloque a mão
esquerda aberta na frente dos olhos, com a palma virada para o lado oposto deles.
Abaixe o dedo mínimo e o anelar, permanecendo com o polegar apontado para o lado
direito, o indicador apontado para cima e o médio apontado para frente. Pronto, todos os
dedos apontam para o lado positivo dos seus respectivos eixos mostrado na figura.

Caso você tenha experiência com o sistema matemático de coordenadas 3D, irá
notar que os eixos estão rotulados de uma maneira um pouco diferente do que se é
comumente utilizado em termos matemáticos. No POV-Ray os eixos não são fixos
como aparentam na figura, eles dependem de onde a câmera é posicionada.

Para definirmos os vetores no POV-Ray utilizamos três valores que são cercados
por colchetes angulares. Por exemplo, para especificar a origem diríamos <0,0,0>.

Há uma funcionalidade chamada de vetor promoção, isto é, um único numero é


promovido a vetor quando todos os elementos do vetor são iguais a esse numero. Por
exemplo, o número 2 pode substituir o <2,2,2>.

Ocasionalmente será preciso especificar um vetor normal no POV-Ray. Em


termos simples, um vetor normal é um vetor paralelo a um determinado plano em três
dimensões. Imagine uma folha de papel plana. É possível visualizar o vetor normal se
colocarmos um lápis em pé sobre uma folha de papel, nesse caso, o lápis representaria o
vetor normal em relação ao papel.

Da mesma forma que uma posição dentro da cena pode ser descrita por um
vetor, as cores também podem. Ao descrever uma cor, cada elemento do vetor

12
corresponde ao montante de uma cor primária. Esse vetor é chamado de vetor RGB
(vermelho, verde e azul).

Os valores de um vetor RGB devem ficar entre 0,0 e 1,0. O valor 1,0 significa o
uso de 100% da cor correspondente. Por exemplo, a cor negra, que é justamente a
ausência de todas as cores, é descrita pelo vetor <0,0,0>, já a cor branca, uma
combinação completa das três cores primarias, é definida pelo vetor <1,1,1>.

Além do vetor RGB, as cores no POV-Ray podem ser especificadas pelo vetor
RGBF. O vetor RGBF possui um elemento extra quando comparado ao RGB, esse
elemento (F) funciona como um filtro de transparência, variando de 0,0 (sem
transparência) a 1,0 (100% transparente). O vetor RGB possui um valor de filtro
implícito de 0,0, em outras palavras, uma cor especificada por um vetor RGB será
perfeitamente opaca. Para exemplificar o funcionamento desse filtro, vamos usar o vetor
RGBF <1,0,0,1>, dessa maneira a cor atuará como um papel celofane vermelho,
100% da luz é transmitida através da cor, mas o pigmento vermelho é filtrado. O vetor
RGBF pode ser um pouco confuso no início, mas ele não é muito difícil, uma vez que se
começa a pegar o jeito.

Como foi dito anteriormente, o POV-Ray lê um arquivo texto na sua liguagem e


tem como saída uma imagem. Existem algumas coisas importantes para se saber sobre o
código da linguagem:

• É case sensitive;

• Ignora espaços em branco;

• Não é preciso ordenar a declaração de objetos.

Case sensitive significa que o POV-Ray diferencia as letras maiúsculas das


minúsculas. Por exemplo, para o POV-Ray, uma esfera é diferente de uma Esfera e
ambas são diferentes de uma EsFeRa. Espaços em branco é o nome comum dado à
quaisquer caracteres que não podem ser vistos diretamente na tela (eles são obtidos
pressionando as teclas Space, tab, enter...). Entre quaisquer duas palavras ou símbolos,
o POV-Ray não se importa se for colocado um espaço, dois espaços, cem espaços, uma
nova linha, ou qualquer outro espaço.

Não importa a ordem em que os objetos são declarados no POV-Ray, pois isso
não fará diferença para a cena final.

13
É possível fazer comentários no POV-Ray, ou seja, uma parte do texto que o
programa irá ignorar quando gerar a cena. Os comentários são utilizados para adicionar
informações ao código, geralmente para tornar as coisas mais claras para um leitor
humano. Podem ser incluídos em /* e */ ou, para uma única linha de comentários,
pode ser prefixo com um //. Por exemplo:

Quadro 4.1: Exemplo de comentário.

//Essa é uma única linha de comentário

/*Este é outro comentário


E ele pode ter o tamanho que desejar.*/

A inclusão de bibliotecas é uma característica de muitas línguas que torna mais


fácil a reutilização do código. O POV-Ray possui bibliotecas de cores pré-definidas,
texturas e até mesmo objetos. Para utilizá-los basta colocar no início de seu código a
função #include ”nome da biblioteca”. Tecnicamente, a declaração não tem de
ocorrer no início do código, mas isso contribui para a legibilidade.

5. OBJETOS

Antes de se construir uma cena é preciso saber de onde ela está sendo observada,
ou seja, o POV-Ray necessita de informações. Imagine uma câmera fotográfica pronta
para tirar uma foto, ela precisa ter uma posição e uma direção. E são exatamente essas
informações que o POV-Ray necessita, e para enviá-las é preciso um objeto do tipo
câmera. A câmera é muito importante e o POV-Ray exige que só haja uma em cada
cena.

Uma câmera pode ter muitos atributos, por hora, vamos nos concentrar nos dois
mais úteis: a localização e a direção.

Uma câmera simples no POV-Ray é declarada da seguinte forma:

Quadro 5.1: Exemplo de posicionamento da câmera.

camera {
location <2,5,-10>
look_at <0,0,0>
}

14
Este exemplo define uma câmera localizada em <2,5,-10> e apontando para a
origem. Isto significa que qualquer coisa possuir a coordenada z inferior a -10 será
certamente invisível para esta câmera, pois estará atrás da mesma.

É possível colocar a câmera em qualquer lugar, inclusive no interior de objetos


(embora nesse caso não seja possível ver muita coisa), com uma exceção: não é possível
colocar a câmera centrada sobre a origem com a direção voltada para baixo. Por razões
matemáticas isso irá gerar um erro no POV-Ray, caso precise dessa configuração, a
solução será colocar a câmera um pouco à direita ou à esquerda.

Vamos começar a construir uma cena com a declaração do fundo, ela permite
alterar a cor do fundo da cena. A cor do fundo deve ser uma cor sólida, portanto texturas
não são permitidas. Para exemplificar, declararemos um fundo na cor preta:

Quadro 5.2: Exemplo de declaração da cor de fundo.

//primeiro, a posição da câmera


camera {
location <2,5,-10>
look_at <0,0,0>
}

//cor de fundo preta


background {
color rgb <0, 0, 0>
}

Caso a biblioteca de cor seja declarada podemos usar o seu nome como no
exemplo abaixo:

Quadro 5.3: Exemplo de inclusão da biblioteca “colors.inc”.

//incluindo a biblioteca de cor


#include "colors.inc"

//primeiro, a posição da câmera


camera {
location <2,5,-10>
look_at <0,0,0>
}

//cor de fundo preta


background {
color Black
}

15
Executando os códigos dos exemplos acima temos uma janela com sua cor
declarada. Caso queira colocar uma textura no fundo, deve-se usar uma “esfera céu”,
uma esfera muito grande (raio de 10000) em que se pode colocar uma textura e que fica
no fundo da cena. Mas veremos isso mais adiante.

Aqui temos uma tabela para ajudar na utilização da biblioteca de cores:

Figura 5.1: Cores inclusas na biblioteca “colors.inc”.

Tabela 5.1: Tabela de cores inclusas na biblioteca “colors.inc” (de acordo com a figura 5.1).

00 = color Black 34 = color MediumForestGreen 68 = color Copper


01 = color White 35 = color MediumGoldenrod 69 = color Bronze
02 = color Red 36 = color MediumOrchid 70 = color Bronze2
03 = color Green 37 = color MediumSeaGreen 71 = color Silver
04 = color Blue 38 = color MediumSlateBlue 72 = color BrightGold
05 = color Yellow 39 = color MediumSpringGreen 73 = color OldGold

16
06 = color Cyan 40 = color MediumTurquoise 74 = color Feldspar
07 = color Magenta 41 = color MediumVioletRed 75 = color Quartz
08 = color Black 42 = color MidnightBlue 76 = color NeonPink
09 = color Aquamarine 43 = color Navy 77 = color DarkPurple
10 = color BlueViolet 44 = color NavyBlue 78 = color NeonBlue
11 = color Brown 45 = color Orange 79 = color CoolCopper
12 = color CadetBlue 46 = color OrangeRed 80 = color MandarinOrange
13 = color Coral 47 = color Orchid 81 = color LightWood
14 = color CornflowerBlue 48 = color PaleGreen 82 = color MediumWood
15 = color DarkGreen 49 = color Pink 83 = color DarkWood
16 = color DarkOliveGreen 50 = color Plum 84 = color SpicyPink
17 = color DarkOrchid 51 = color Salmon 85 = color SemiSweetChoc
18 = color DarkSlateBlue 52 = color SeaGreen 86 = color BakersChoc
19 = color DarkSlateGray 53 = color Sienna 87 = color Flesh
20 = color DarkTurquoise 54 = color SkyBlue 88 = color NewTan
21 = color Firebrick 55 = color SlateBlue 89 = color NewMidnightBlue
22 = color ForestGree 56 = color SpringGreen 90 = color MandarinOrange
23 = color Gold 57 = color SteelBlue 91 = color VeryDarkBrown
24 = color Goldenrod 58 = color Tan 92 = color DarkBrown
25 = color GreenYellow 59 = color Thistle 93 = color GreenCopper
26 = color IndianRed 60 = color Turquoise 94 = color DkGreenCopper
27 = color Khaki 61 = color Violet 95 = color DustyRose
28 = color LightBlue 62 = color VioletRed 96 = color HuntersGreen
29 = color LightSteelBlue 63 = color Wheat 97 = color Scarlet
30 = color LimeGreen 64 = color YellowGreen 98 = color DarkTan
31 = color Maroon 65 = color SummerSky 99 = color White
32 = color MediumAquamarine 66 = color RichBlue
33 = color MediumBlue 67 = color Brass // Grey = Gray; // Mica = Black

Os blocos de construção de cenas e de objetos no POV-Ray são chamados de


primitivas. Primitivas são, geralmente, simples formas geométricas, tais como esferas,
cubos e cones, objetos que o POV-Ray já conhece e tudo o que precisa ser feito é
descrever alguns dos seus atributos.

As primitivas no POV-Ray, em geral, são da seguinte forma:

Nome_do_objeto{
Parâmetros_do_objeto
Alguns_atributos_simples_do_objeto
Alguns_outros_atributos_simples
Alguns_atributos_complexos{
Alguns_atributos
Alguns_outros_atributos
}
}

Veremos o exemplo:

Quadro 5.4: Exemplo de uma cena contendo uma esfera vermelha.

//primeiro, a posição da câmera

17
camera {
location <2,5,-10>
look_at <0,0,0>
}

//cor de fundo preta


background {
color rgb <0, 0, 0> //fundo preto
}

//esfera vermelha no centro


sphere {
<0, 0, 0>, 3
pigment {
color rgb <1, 0, 0> //esfera vermelha
}
}

Não é complicado decifrar o que significa o exemplo. O código define uma


esfera, com o seu centro na origem (isto é <0,0,0>), e com raio de 3 (em outras
palavras, a distância do centro da esfera a qualquer ponto da sua borda é exatamente 3
unidades). “pigment {color rgb <1,0,0>}” significa que a pigmentação (ou cor)
da esfera é descrita pelo vetor RGB <1,0,0>, que é a cor vermelha. Poderíamos usar a
cor vermelha como sendo “color Red” se tivéssemos incluído a biblioteca de cores. O
atributo pigmentação é um atributo complexo no qual a cor é apenas um dos muitos
atributos que podem ser contidos em seu interior.

Figura 5.2: Exemplo da cena de uma esfera vermelha sem iluminação.

No POV-Ray existe as primitivas finitas e as infinitas. As primitivas finitas


possuem limites bem definidos, por exemplo, esferas e cones. As primitivas infinitas
possuem componentes que podem potencialmente esticar-se ao infinito como, por

18
exemplo, um plano. O importante na hora de descrever as primitivas é apenas saber a
sua sintaxe. A sintaxe completa para descrever objetos finitos e infinitos será descrita
mais adiante.

Para que nossa esfera seja vista em 3D, é necessário adicionarmos uma fonte de
luz.

Existem alguns tipos de fontes de luz diferentes no POV-Ray. Vamos nos


concentrar no mais simples (e útil): a fonte luminosa pontual. Pode-se pensar numa
fonte pontual como sendo um objeto infinitamente pequeno que emite luz. Sendo
pequenas assim, não é preciso se preocupar com a aparência delas na cena, no entanto,
seus efeitos podem certamente ser vistos, a sua cena acende!

Uma fonte de luz pontual pode ser conhecida como uma fonte não-atenuante, ou
seja, a luz emitida não fica mais fraca com a distância. Isto significa que é possível
iluminar a cena inteira com uma fonte de luz pontual colocada longe da cena. Também é
possível ter quantas fontes de luz desejar, mas elas são caras computacionalmente, ou
seja, quanto maior o número delas na cena, mais tempo o POV-Ray irá gastar para gerar
a imagem.

Para exemplificar, vamos colocar uma fonte de luz pontual na nossa cena:

Quadro 5.5: Exemplo de luz pontual na cena da esfera vermelha.

// Nossa esfera vermelha simples

// primeiro, a posição da câmera


camera {
location <2,5,-10>
look_at <0,0,0>
}

//cor de fundo preta


background {
color rgb <0, 0, 0> //fundo preto
}

// agora, um pouco de luz


light_source {
<0,10,-10>
color rgb <1,1,1>
}

// a esfera vermelha
sphere {
<0,0,0>, 3
pigment { color rgb <1,0,0> }

19
}

O primeiro vetor é um vetor posição indicando a localização da fonte luminosa.


O segundo vetor especifica a cor (e brilho) da luz. Em geral, é bom usar luz branca ou
cinza, uma vez que a luz colorida pode ter alguns efeitos secundários, como por
exemplo, alguns objetos verdes não serão exibidos quando expostos a uma luz vermelha
pura.

Figura 5.3: Exemplo da cena de uma esfera vermelha iluminada.

Agora que o código já esta familiarizado, a melhor forma de aprender é


experimentar, então, vamos substituir os objetos. Começaremos com um cilindro
primitivo, apenas troque o objeto esfera pelo do cilindro abaixo.

Quadro 5.6: Exemplo de um cilindro.

//um cilindro primitivo azul claro


cylinder {
<0, 0, 0>, <0, 4, -1>, 3 //2 vetores posição e raio
pigment { color rgb <0.3, 0.6, 0.7> }
}

Os vetores iniciais determinam a posição do cilindro, eles indicam a posição


final de cada lado (com eles é possível determinar o comprimento e a direção do
cilindro). O terceiro argumento determina o raio da circunferência do cilindro.

20
Figura 5.4: Cilindro.

Agora, um exemplo de um cone primitivo:

Quadro 5.7: Exemplo de cone.

// um cone primitivo
cone {
<0, 0, 0>, 3,
<0, 6, 4>, 0.5
pigment { color rgb <1,0,1> }
}

O primeiro vetor indica a posição final de um dos lados seguido do seu


respectivo raio. O segundo vetor indica a posição final do outro lado seguido de seu
respectivo raio também.

Figura 5.5: Cone.

Uma caixa (paralelepípedo) primitiva pode ser descrito da seguinte forma:

21
Quadro 5.8: Exemplo de caixa.

box {
<0, 0, 0>, <5, 3, -5>
pigment { color rgb <1,0.5,0> }
}

Os vetores indicam a posição dos cantos opostos.

Figura 5.6: Caixa

Triângulos são os famosos polígonos de três lados. Assim como na caixa, a


posição do triângulo é especificada pelos seus cantos, mas nesse caso são necessários
todos os três cantos.

Quadro 5.9: Exemplo de triângulo.

triangle {
<0, -5, 1>, <-5, 0, 1>, <3, 3, 1>
pigment { color rgb <0.5, 0.7, 1> }
}

Figura 5.7: Triângulo.

22
As bolhas são basicamente um conjunto de esferas atraem ou repelem umas as
outras para formar uma superfície. Elas não se comportam como objetos precisos, mas
dão uma espécie de sensação “orgânica” para a cena.

Quadro 5.10: Exemplo de bolha.

// Blob com três components


blob {
threshold 0.25
component 2, 2, <0, 0, 0>
component 1, 2, <-2, 2, 0>
component 1, 2, <2, 2, 0>
pigment { color rgb <1,1,1> }
}

Ele cria campos em torno de cada um dos elementos, e a força que indica o quão
forte é o campo é indicada pelo primeiro atributo da mesma. Essa força pode ter valores
positivos, que fará com que a superfície atraia outras componentes da bolha, ou
negativos, que fará a superfície repelir as componentes da bolha. Quanto maior o valor,
maior será o efeito que esta componente terá.

O segundo atributo da componente é o raio, este descreve seu campo de


aplicação. Equações são criadas de modo que a intensidade do campo de cada
componente da bolha seja igual à força no centro dessa componente, decrescendo a
zero.

O vetor indica a posição do centro da componente da bolha.

Figura 5.8: Bolha.

As bolhas podem ser usadas em CSG, a intensidade do campo é maior no


interior de uma bolha do que na superfície. Inversamente, qualquer ponto fora do campo

23
possui intensidade menor. Note que as componentes de diferentes objetos do tipo bolha
não afetam umas as outras.

O disco primitivo cria um disco circular muito fino com um buraco opcional no
centro.

Quadro 5.11: Exemplo de disco.

//disco com buraco no centro


disc {
<0, 0, 0>, < 1, -1, 0>, 6, 4
pigment { color rgb <0,0.5,1> }
}

O primeiro vetor indica a posição do centro do disco, o segundo vetor é um vetor


normal, ou seja, um vetor perpendicular ao disco. Os valores que seguem indicam o raio
do disco e o raio do buraco no interior (opcional) respectivamente. Note que o valor do
raio do buraco no interior do disco precisa ser maior do que o raio do disco, caso
contrário não é possível visualizar o disco.

Figura 5.9: Esfera no centro de um disco.

O plano primitivo cria um plano infinito.

Quadro 5.12: Exemplo de plano infinito.

plane {
y, -4 //onde y é o vetor normal (pode ser especificado como
// <0,1,0>. E 4 indica que o plano irá passar a uma
// distância de 4 da origem.
pigment { color rgb <0, 0.6, 0.9> }
}

24
Campos altos é uma maneira fácil de criar montanhas em suas cenas. Ele,
basicamente, lê um arquivo de imagem e, em seguida, transforma a imagem em uma
malha de triângulos. A altura de cada ponto da malha é determinada pelo valor do pixel
correspondente na imagem. Ele é declarado da seguinte forma:

Quadro 5.13: Exemplo de campos altos.

height_field {
gif "fract001.gif"
pigment { color rgb <1, 1, 1> }
translate <-0.5, -0.5, -0.5>
}

Onde “gif” é o tipo do arquivo da imagem (poderia ser outro), em seguida está
o nome do arquivo de imagem. Veremos mais adiante o que significa “translate”.

Figura 5.10: Arquivo de imagem (à esquerda) e campo alto


da imagem no POV-Ray (à direita).

Para arquivos do tipo “gif”, a altura de um pixel é determinada com base no seu
índice na paleta de cores. O valor 0 seria a menor altura do campo, enquanto 255 seria a
maior.

Para arquivos do tipo “tga” o mapeamento da altura é feito de maneira um


pouco diferente. Como há muitos índices na paleta de cores (65.536), para cada pixel
são armazenados os bytes através dos pixels vermelho e verde, o byte mais significativo
é armazenado no vermelho, o menos significativo no verde. A geração de altura destes
tipos de campos vai muito além do alcance da maioria dos programas de pintura, mas é
muito raro que realmente seja preciso 65.536 níveis distintos de altura, de qualquer
forma. Belas montanhas tendem possuir 256 divisões, a não ser que você deseja obter
uma visão muito aproximada.

Normalmente, o POV-Ray gera campos altos fora do normal, então para ter
exatamente o que se deseja, pode-se incluir a palavra chave "smooth" na declaração (é
opcional). Isto fará com que o POV-Ray use bons triângulos em vez de usar os planos,

25
isso ocorre porque o POV-Ray irá calcular automaticamente superfícies normais para
fazer a altura do campo ficar boa, mas há um custo maior.

Outra palavra-chave que é possível incluir é "water_level", ela é usada para


cortar a parte inferior de um campo alto. Isso é útil para as montanhas que você
pretende parcialmente submergir em água. Nesse caso a renderização fica mais rápida,
pois a parte que se encontram abaixo do campo "water_level" não será transformada
em triângulos. O “water_level” possui valores entre 0.0 e 1.0, que especificam os
níveis de fatiamento, sendo 0,0 um corte no nível mais baixo do campo, 1,0 para o mais
alto e 0,5 iria cortar na metade inferior do campo.

Então agora podemos criar alguns objetos simples. Há vários outros, bem
como bibliotecas de formas (como shapes_lo.inc), mas não iremos abordar aqui.
Alguns destes objetos que podem ser criados no POV-Ray só podem se localizar em
torno da origem (como o toro). E se queremos colocá-los em outro lugar? E se
queremos deslocá-los? O POV-Ray oferece respostas para todas estas questões sob a
forma de transformações. As transformações, falando de raytracing, são atributos que
mudam a posição, tamanho ou orientação de objetos (e dos diversos atributos dos
objetos). Os tipos mais comuns de transformações, e os que POV-Ray suporta, são
traduções, rotações e escalares.

A translação é uma transformação em que um objeto se move em relação à sua


posição atual. Usa-se <x,y,z> para especificar a nova posição.

A rotação é uma transformação que muda a orientação de um objeto. Rotações


são as mais complexas das transformações. Eles estão especificados para POV-Ray pela
seqüência <x,y,z>, onde x, y, e z são o número de graus (não radianos) ao redor do
respectivo eixo de rotação.

Uma forma rápida de se lembrar de que forma os objetos vão rodar pelas é usar a
chamada "regra da mão esquerda.” Basta segurar a sua mão esquerda, dedos e polegar
abertos. Aponte o polegar no sentido positivo do eixo que o objeto irá rodar (se você
estiver rodando sobre mais eixos de uma só vez, isto não irá ajudá-lo - a menos que
você tenha mais de um polegar!). A direção dos dedos indica a direção de rotação,
quando o número de graus é positivo. (Quando o numero de graus é negativos precisa
rodar na direção oposta).

26
Figura 5.11: Exemplificação da regra da mão esquerda para rotações.

A última transformação é a escalar, ela muda o tamanho do objeto com relação


ao seu tamanho atual. A transformação escalar é especificada no POV-Ray pelo vetor
<x,y,z>, onde os elementos especificam o quanto a escala do tamanho do objeto irá
mudar com relação à coordenada do respectivo eixo: uma escala de 1,0 deixa o objeto
do mesmo tamanho, uma escala de 0,0 ou menor é inválida, e uma escala maior irá
aumentar o tamanho do objeto.

As transformações são declaradas no código como qualquer outro atributo. Por


exemplo:

Quadro 5.14: Exemplo de mudança de escala, rotação e translação em um toro.

torus {
3, 1 //raio maior (tamanho da argola), raio menor
(espessura)
pigment { color Yellow }
scale <1.5,1,1>
rotate <-20,0,0>
translate <0,2,0>
}

Esse código faz um toro (argola) amarelo, ligeiramente alargado em torno do


eixo x, rodado -45 graus em torno do eixo x e com o seu centro em <0,2,0>, como
este:

27
Figura 5.12: Toro que passou por transformações.

Note que o objeto toro é criado em torno da origem, por isso, é necessário
aplicar a transformação para usá-lo onde quiser.

6. TEXTURA

6.1 FORMA GERAL

A pigmentação é, na realidade, parte de um atributo maior chamado a textura.


Cada vez que atribuímos uma pigmentação, deveríamos enxergá-la da seguinte forma:

Quadro 6.1.1: Forma correta de declarar a pigmentação.

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

A razão pelo qual o POV-Ray deixa usar o atributo pigmentação fora da textura
é porque a pigmentação é utilizada tão freqüentemente por si só, que facilita o uso se a
textura não precisar ser declarada toda vez. De fato, a maioria das partes do bloco
“texture{}” também pode ser feito dessa maneira, e de qualquer maneira, eles têm o
mesmo efeito.

O atributo textura contém atributos descrevem a aparência externa do objeto:


pigmentação, acabamento e normal. O atributo pigmentação, como já sabemos,

28
descreve a cor do objeto (talvez de um modo mais complicado do que o que foi
mostrado até agora). O atributo acabamento descreve a forma como o objeto "interage
com a luz" (brilho, brilho metálicos, refletividade, etc.). O atributo normal descreve
algumas características tridimensionais dos objetos, tais como ressaltos, ondas e
ondulações.

Vimos, até agora, o uso do atributo cor dentro do atributo pigmentação (por
exemplo, “pigment{ color blue }”). O atributo mais flexível, porém, é o
mapeamento de cor, utilizado para fazer uma grande variedade de coisas. Basicamente,
um mapeamento de cor define faixas de cores em um "mapa" que vão de 0.0 a 1.0
Vejamos um exemplo simples:

Quadro 6.1.2: Exemplo de declaração de mapeamento de cor com informação completa.

Color_map {
[0.0 0.25 color Red]
[0.25 0.9 color Blue]
[0.9 1.0 color Green]
}

Este exemplo define três faixas de cores: vermelho de 0,0 até 0,25, azul de 0,25
até 0,9 e verde e de 0,9 até 1,0. Outro formato comumente utilizado tem o seguinte
aspecto:

Quadro 6.1.3: Exemplo de declaração de mapeamento de cor.

Color_map {
[0.0 color Red]
[0.25 color Blue]
[0.9 color Green]
}

Ambos os exemplos fazem a mesma coisa, o primeiro contém um pouco mais de


informações sobre as bandas de começo e parada.

O POV-Ray pode fazer várias coisas com isto através dos muitos tipos de
pigmentação. Os pigmentos dão vida às imagens de raytracing. O POV-Ray suporta
uma vasta gama de tipos de pigmentação, com um número infinito de maneiras eficazes
para alterá-los conforme as necessidades. E se ainda não for suficiente, é possível
mapear a imagem usando texturas em vez de apenas cores. Enfim, a forma geral para
especificar um pigmento é a seguinte:

29
Quadro 6.1.4: Forma geral da declaração de pigmentação.

pigment {
// É necessário um desses:
pigment tipo /* OU */
color cor /* OU */
image_map {
/* Especificações do mapeamento da imagem */
}
// Todos a seguir são opcionais:
color_map {
/* Entradas do mapeamento de cor */
}
frequency frequência
lambda valor lambda
octaves número de oitavas
omega valor omega
phase fase
quick_color cor
turbulence valor ou vetor de turbulência
/* qualquer transformação aparece aqui */
}

Qualquer número de transformações (rotações, traduções e escalas) pode seguir


a declaração de pigmentação, mas deve ser especificado após o último modificador do
mesmo.

Uma pigmentação é composta por três partes principais, em primeiro lugar o tipo
da pigmentação, então o mapeamento colorido, e finalmente a turbulência. O
mapeamento colorido e a turbulências são opcionais. O tipo de pigmentação pode ser:
ágata (agate), palhaço (bozo), tabuleiro de xadrez (checker), gradiente (gradient),
granito (granite), hexágono (hexagon),leopardo (leopard), mármore (marble), mandel,
cebola (onion), ou madeira (wood).

O segundo tipo de modificador é o mapeamento de cor, visto anteriormente. Os


modificadores são a frequência, que estende ou comprime o mapeamento de cor, e de
fase, que muda as cores do mapa.

A terceira parte da pigmentação é a especificação de turbulência. É usado


basicamente para misturar um pouco o pigmento, o que pode dar vida a ele. Ela pode
assumir qualquer valor ou um vetor de três componentes. Veja o exemplo:

Quadro 6.1.5: Três maneiras diferentes de declarar a turbulência.

turbulence 0.8 //produz uma turbulência o,8 em todas as


// direções

30
turbulence <0, 0.9, 0.3> // nenhuma turbulência na direção
//x, 0.9 na direção y e 0.3 na
//direção z

turbulence x //grande turbulência apenas na direção x

Quanto maior o valor, maior é a turbulência. A maneira que o POV-Ray


implementa a turbulência é bastante interessante. Em uma pigmentação normal, o POV-
Ray simplesmente determina a cor do pixel, em pontos aleatórios da superfície do
objeto. Assim, os pontos que estão próximos entre si tendem a ficar com as mesmas
cores, enquanto pontos que estão distantes tendem a ficar com cores aleatórias (em
relação uns aos outros). Apesar da determinação dos pontos ser aleatória ela é sempre a
mesma quando se está trabalhando com a mesma imagem (bom para a criação de
animações).

O número total de medidas tomadas é controlado pelo parâmetro oitavas. O


número padrão de oitavas é 6, e é um número razoável que irá fazer parte da maioria das
texturas finas. Reduzir o número ou oitavas (a, digamos, 2) pode criar efeitos
interessantes. O comprimento de cada passo decresce exponencialmente e a taxa na qual
o passo comprimento decresce é determinado pelo valor de ômega, que possui, por
padrão, o valor 0,5, valores mais baixos tendem a facilitar a pigmentação, enquanto
valores altos de ômega (0,8, 0,9, qualquer que seja) tendem a tornar a turbulência mais
aleatória. O terceiro modificador de turbulência é o parâmetro lambda, este controla a
"aleatoriedade" de cada etapa. Lambdas que estão próximos a 1,0 fazem com que as
etapas fiquem aproximadamente na mesma direção, enquanto valores maiores
aumentam a aleatoriedade da direção de cada etapa. O valor padrão é 2.0.

Os modificadores lambda, oitavas, e Omega podem ser utilizados para conseguir


exatamente o efeito desejado.

6.2 TIPOS DE PIGMENTAÇÃO

A pigmentação gradiente cria planos paralelos de pigmentações de cor. A


orientação desses planos é controlada com o parâmetro do gradiente. O parâmetro 3 é
um componente normal do vetor que descreve os planos de cor (todos têm a mesma

31
normal, pois são paralelas). Note que a magnitude do vetor é irrelevante, desde que não
seja zero. Para controlar a largura das faixas de cores, use a palavra-chave
“frequency” (frequência).

Quadro 6.2.1: Exemplo de declaração de pigmentação gradiente.

sphere {
<0,0,0>, 5
pigment {
gradient <0, 1, 0>
color_map {
[0.0 color Red]
[0.25 color Blue]
[1.0 color Green]
}
scale 3
}
}

O código fonte requer um pouco de explicação. O vetor após a palavra-chave


gradiente é o vetor normal para a orientação das faixas de cores. A declaração da escala
aplica-se à pigmentação, e não ao objeto.

Figura 6.2.1: Esfera com pigmentação gradiente.

A pigmentação gradiente é muito semelhante á pigmentação mármore. A


principal diferença é a função do mapeamento de cor. O gradiente usa índices de
mapeamento de cor de 0 a 1, sem inversão, enquanto mármore salta para frente e para
trás a partir de 0 a 1 e volta a 0 novamente. Este efeito pode ser simulado usando
gradiente com o mapeamento de cor adequado e escalas. A seguir, dois exemplos de
gradiente padrão, no primeiro usamos "gradient x" e no segundo usamos
"gradient <1,1,1>".

32
Figura 6.2.2: Esferas com diferentes valores de pigmentação gradiente.

Podemos adicionar uma turbulência com o valor 2 e observar o resultado.

Quadro 6.2.2: Exemplo de aplicação de turbulência.

sphere {
<0,0,0>, 5
pigment {
gradient <0, 1, 0>
color_map {
[0.0 color Red]
[0.25 color Blue]
[1.0 color Green]
}
scale 3
turbulence 2
}
}

Figura 6.2.3: Turbulência aplicada em uma esfera.

A pigmentação mármore, como foi dito antes, é bastante semelhante a


pigmentação gradiente x. Porém há uma diferença na mistura das cores, podemos notar
nas figuras da pigmentação gradiente que as cores verde e vermelho se juntam

33
abruptamente, como um corte, isso não ocorre na pigmentação mármore, pois os índices
variam de 0 a 1, na faixa de 0 a x = x = 0,5 e, em seguida, de volta para baixo para
colorir 0 novamente no intervalo x = 0,5 a x = 1.

Quadro 6.2.3: Exemplo de declaração da pigmentação mármore.

sphere {
<0,0,0>,5
pigment {
marble
color_map {
[0.0 color Gray90] // 90% cinza
[0.8 color Gray60] // 60% cinza
[1.0 color Gray20] // 20% cinza
}
scale 0 //quando o valor é 0, não precisa especificar
turbulence 1
}
}

Figura 6.2.4: Esferas com pigmentação mármore


(à direita foram usados tons de cinza e turbulência=1).

O valor da turbulência de 0.8 ou 0.9, em combinação com um bom mapeamento


de cor, pode criar uma textura de pedra bem. Aqui estão duas imagens da amostra
mármore pigmentos, idênticos, exceto para as turbulências. A primeira imagem não tem
nenhuma turbulência, enquanto o segundo tem turbulência 0.8.

A pigmentação ágata possui, por padrão, muita turbulência. É semelhante à


pigmentação mármore, exceto isto. A função do mapeamento de cor utiliza índices de
0,0 a 1,0 e depois volta a 0,0 como no mármore, mas em vez de indexação linear de
cores a ágata utiliza uma onda senoidal, o que resulta numa das extremidades do
mapeamento de cor possuir mais peso do que o centro. Um exemplo está abaixo.

Quadro 6.2.4: Exemplo de declaração da pigmentação ágata.

34
sphere {
<0,0,0>, 5
pigment {
agate
color_map {
[0.0 color Red]
[0.25 color Blue]
[1.0 color Green]
}
agate_turb 1.0 //o valor 1 é padrão
scale 3
}
}

Figura 6.2.5: Esfera com pigmentação ágata.

Outra coisa a notar sobre ágata é o fato de que a turbulência não tem qualquer
efeito sobre a palavra-chave desta pigmentação. A ágata é sempre turbulenta. A
quantidade de turbulência pode ser controlada, em certa medida, com a palavra-chave
“agate_turb”, que possui um valor positivo.

A pigmentação palhaço, basicamente, cria uma série de "manchas" sobre o


objeto. Sua função de mapeamento de cor indexa os valores de 0 a 1, sem inversão. A
pigmentação funciona através da atribuição de cores aleatórias nos pontos inteiros do
espaço e cores de interpolação entre esses pontos. Como resultado, dois pontos que são
próximos tendem a ter cores que são bastante semelhantes, enquanto pontos que são
distantes tendem a ter cores que são aleatórias em relação uns aos outros. A noção de
próximo e distante depende do dimensionamento da pigmentação. Veja o exemplo:

Quadro 6.2.5: Exemplo de declaração da pigmentação palhaço.

sphere {
<0,0,0>, 6
pigment {
bozo

35
color_map {
[0.0 color Red]
[0.25 color Blue]
[1.0 color Green]
}
}
}

Figura 6.2.6: Esfera com pigmentação palhaço.

As pigmentação manchada (spotted), granito (granite), leopardo (leopard) e


madeira (wood) são muito parecidas com as pigmentações descritas acima, portanto,
não vamos exemplificar seus códigos aqui.

Figura 6.2.7: Esferas com as pigmentações manchada, granito, leopardo e madeira respectivamente.

36
A pigmentação tabuleiro de xadrez cria cubos de cor no espaço e suporta
mapeamento de cores; apenas duas cores são especificadas elas formarão um tabuleiro
de xadrez mesmo. Isto difere um pouco do padrão de declaração da pigmentação, aqui
está um exemplo:

Quadro 6.2.6: Exemplo de declaração da pigmentação tabuleiro de xadrez.

sphere {
<0,0,0>, 6
pigment {
checker
color Red //primeira cor
color Blue //segunda cor
scale 6
}
}

Figura 6.2.8: Esfera com pigmentação tabuleiro de xadrez.

Como a maioria das outras pigmentações, o tabuleiro de xadrez responde ao


modificador de turbulência. A pigmentação também pode ser redimensionada para
produzir blocos retangulares de cor.

A pigmentação hexágono é similar a pigmentação tabuleiro de xadrez. Agora,


são especificadas três cores que são usadas para criar um padrão hexagonal sobre os
objetos. Por padrão, o hexágono é projetado para o plano x e z, produzindo um tipo de
pilar hexagonal no eixo y.

Quadro 6.2.7: Exemplo de declaração da pigmentação hexágono.

sphere {
<0,0,0>, 6
pigment {
hexagon
color rgb <0.75, 0, 0>
color rgb <0, 0, 0.75>

37
color rgb <0, 0.75, 0>
scale 0.5
}
}

Figura 6.2.9: Esfera com pigmentação hexágono.

O mapeamento de imagem é uma técnica muito poderosa utilizada para produzir


cores e padrões específicos na superfície de um objeto. Ele, basicamente lê um arquivo
de imagem e, em seguida, projeta essa imagem para o objeto. Por padrão a imagem é
projetada no plano xy. Caso queira mudar a posição da imagem, é possível rodar e
escalar a imagem, também é possível alterá-la (até certo ponto) com os modificadores
do “map_type”. A seguir é mostrado um exemplo de declaração:

Quadro 6.2.8: Forma geral da declaração da pigmentação mapeamento de imagem.

image_map {
tipo "nome_do_arquivo.tipo"
//modificadores (são opcionais)
Interpolate valor
Filter paleta_de_cor, porcentagem_de_tranparência
}

O tipo pode ser “gif”, “tga”, “iff”, ou outro, seguido do nome do arquivo (entre
aspas), que especifica o arquivo de imagem a ser mapeada.

Um desses modificadores é o interpolador, que realiza um nivelamento na


imagem. Por padrão, o POV-Ray tem a localização dos raios de intersecção do pixel e
atribui um valor a ele, quando a imagem é redimensionada ou está com má resolução,
isso pode resultar em uma imagem em que aparecem apenas blocos ou de uma forma
geralmente feia. Usando a interpolação pode-se melhorar esta imagem. Os valores da
palavra-chave “interpolate” podem ser 4 (algoritmo de normalização da distância)

38
ou 2 (para o algoritmo bilinear). A normalização da distância é o algoritmo mais rápido,
enquanto o bilinear faz um trabalho melhor de escolher as cores intermediarias.

O outro modificador é chamado de filtro de valores. Por padrão, todos os


mapeamentos de imagem são opacos. A palavra-chave “filter” pode ser usada para
alterar esta situação, pois o filtro modifica cores específicas, ou atribuir um valor para
toda a imagem.

Quadro 6.2.9: Exemplo de declaração da pigmentação mapeamento de imagem.

//posição da câmera
camera {
location <1.5, 1.5, -2>
look_at <0.5, 0.5, 0.5>
}

//iluminação
light_source { <50, 30, -50> color rgb <1, 1, 1> }

//caixa com a imagem


box {
<0, 0, 0>, <1, 1, 1>
pigment {
image_map {
gif "../gfx/mmap.gif"
}
}
}
//um plano de fundo
plane {
-z, -10
pigment {
checker color rgb <1, 1, 1> color rgb <0, 0, 0>
rotate 45*z
}
}

Figura 6.2.10: Arquivo de imagem (à esquerda) e pigmentação


mapeamento de imagem no POV-Ray (à direita).

39
6.3 FINALIZAÇÃO

A finalização descreve como os objetos interagem com a luz, ou seja, como eles
refletem, como será o brilho, a transparência etc. Todos os atributos de finalização são
fechados em um bloco {}.

Quadro 6.3.1: Forma geral da declaração de finalização.

finish {
/*todos os atributos são opcionais*/
ambient luz_ambiente
brilliance brilho
crand valor_crand
diffuse luz_difusa
ior indice_de_refração
metallic
phong valor_phong
phong_size tamanho_do_phong
reflection luz_de_reflexão
refraction refração
roughness rugosidade
specular polido
}

O atributo ambiente controla o quanto da cor de uma superfície é proveniente da


iluminação ambiente. Seu valor varia no intervalo de 0,0 a 1,0 (tipicamente), o valor
padrão é 0.1 Valores baixos significam que os objetos que não estão diretamente
iluminados e manterão algumas das suas cores, valores maiores podem fazer com que o
objeto pareça estar brilhando (embora ele não emita qualquer luz).

Quadro 6.3.2: Exemplo de declaração de atributo ambiente.

sphere {
<0, 0, 0>, 4
pigment { color rgb <1, 1, 0> }
finish {
ambient 0.6
}
}
As imagens abaixo mostram basicamente como a iluminação ambiente interfere
no objeto. O primeiro é o padrão, o segundo é representado com o ambiente 0.6.

40
Figura 6.3.1: Diferença entre uma esfera padrão e uma com iluminação ambiente.

O atributo brilho modifica o comportamento da iluminação difusa, seu valor


padrão é 1.0. A forma como funciona iluminação difusa consiste em calcular o ângulo
entre a superfície e o raio de luz. Usando o brilho, podemos chegar a um efeito mais
metalizado.

Quadro 6.3.3: Exemplo de declaração do atributo brilho.

sphere {
<0, 0, 0>, 4
pigment { color rgb <1, 1, 0> }
finish {
brilliance 5
}
}

Figura 6.3.2: Esfera com brilho.

O atributo crand pode ser usado para simular superfícies rugosas, como concreto
e areia, pois ele deixa as superfícies com um aspecto granulado. Os valores do crand
variam de 0,0 a 1,0, sendo o padrão 0.0. É bom lembrar que o crand é completamente

41
aleatório, ou seja, possivelmente teremos dois resultados diferentes usando a mesma
imagem (o que é ruim para animações).

Quadro 6.3.4: Exemplo de declaração do atributo crand.

sphere {
<0, 0, 0>, 4
pigment { color rgb <1, 1, 0> }
finish {
crand 0.3
}
}

Figura 6.3.3: Esfera com finalização crand.

O modelo de iluminação difusa é a principal maneira de diferenciar como os


objetos são iluminados. Por padrão a maior parte da coloração de um objeto vem de
iluminação difusa, pois ela é, basicamente, a luz que vem de uma fonte luminosa e
difunde em todas as direções. Uma superfície que tem a fonte luminosa diretamente
voltada para ela irá aparecer mais brilhante do que uma superfície que é iluminada a
partir de um ângulo muito baixo de reflexão de luz. O atributo difusão pode modificar
esses efeitos (em certa medida), seu valor varia de 0,0 (ausência de luz a partir de fontes
de luz) para 1,0 (muito bem iluminado), sendo o valor padrão 0.6.

Quadro 6.3.5: Exemplo de declaração de difusão.

sphere {
<0, 0, 0>, 4
pigment { color rgb <1, 1, 0> }
finish {
diffuse 0.9
}
}

42
Figura 6.3.4: Esferas com difusão (valor 0.3 à esquerda e 0.9 à direita).

O primeiro tem difusão 0.3, o segundo 0.9

Talvez o atributo da finalização mais usado seja o atributo phong. O phong cria
um destaque em um objeto que na verdade é a cor da fonte luminosa, seu valor varia
entre 0.0 e 1.0, quanto maior, mais brilhante será o objeto. Isto é feito através da
comparação do ângulo em que está o observador e o ângulo em que a luz incide na
superfície, caso esses ângulos sejam opostos e aproximadamente iguais, a cor da luz é
misturado na cor do objeto.

Quadro 6.3.6: Exemplo de declaração do atributo phong.

sphere {
<3, 0, 0>, 3
pigment {
color rgb <1, 0, 0>
}
finish { phong 0.9 }
}

box {
<-5, -2, -2>, <-1, 2, 2>
pigment {
color rgb <1, 0.3, 0.6>
}
finish { phong 0.9 }
}

43
Figura 6.3.5: Caixa e esfera com finalização phong.

Note que não há brilho destacado na caixa, porque nenhuma das faces é
orientada de modo a refletir a luz para a câmera.

Existe também um modificador do phong, o parâmetro “phong_size”, ele define o


tamanho do brilho e pode dar impressão de uma superfície muito polida. Os valores
típicos variam entre 1 a 250 (muito brilhante), mas o padrão é 40.

Quadro 6.3.7: Exemplo de declaração do parâmetro “phong_size”.

sphere {
<0, 0, 0>, 4
pigment { color Red }
finish {
phong 1
phong_size 2
}
}

Figura 6.3.6: Esferas com diferentes valores de “phong_size"(valor 200 à esquerda e 2 à direita).

Outro modificador para phong é o metálico, o que significa que o brilho


destacado em um objeto deve ser modificado pela cor da sua superfície, e não apenas

44
determinado unicamente a partir da cor da fonte luminosa. O metálico não possui
parâmetros, ou seja, ou o objeto é metálico ou não é.

Quadro 6.3.8: Exemplo de declaração do modificador metálico.

sphere {
<0, 0, 0>, 4
pigment { color rgb <1, 0, 0> }
finish {
phong 0.9
metallic
}
}

Figura 6.3.7: Esfera com finalização metálica.

Outro atributo da finalização é o polido (specular), muito é semelhante ao


phong, mas este é mais preciso de acordo com as leis físicas, pois produz um destaque
sobre o objeto onde seria o reflexo caso o objeto fosse reflexivo. Seus valores podem
variar entre 0.0 e 1.0 e o padrão é não destacar o brilho (0.0). O tamanho do realce pode
ser controlado (em certa medida), com ao parâmetro rugosidade.

Quadro 6.3.9: Exemplo de declaração do atributo polido.

sphere {
<0, 0, 0>, 4
pigment { color rgb <1, 0.3, 0.7> }
finish {
specular 0.9
roughness 0.75

}
}

45
Figura 6.3.8: Esferas com a finalização polida e diferentes valores de rugosidades (a figura de cima não
possui rugosidade, a da esquerda possui o valor 0,75 de rugosidade e a figura da direita possui 0,001).

A reflexão é outro atributo da finalização, ela dá ao objeto um acabamento


espelhado ou parcialmente espelhado e este objeto irá refletir outros objetos da cena. A
reflexão admite valores entre 0.0 e 1.0, quanto maior o valor, mais espelhado o objeto
fica, sendo que o valor 0.0 desativa a reflexão. Para obter um refletor absolutamente
perfeito, também é preciso especificar "ambient 0" e "diffuse 0” em sua
declaração de finalização. Normalmente os valores de reflexão não precisam ser
elevados em objetos que não são exatamente espelhos, até mesmo para superfícies de
vidro uma reflexão valor de 0,1 é suficiente para torná-la realista. Outra coisa para se
saber é que quanto mais reflexão tiver, mais tempo será necessário para renderizar, pois
para cada raio que atinge um objeto reflexivo, outro raio tem que ser rastreado para
determinar que o primeiro reflete a superfície.

Quadro 6.3.10: Exemplo de declaração do atributo reflexão em uma cena.

//o plano irá funcionar como chão


plane {
y, -4

46
pigment { checker color Black color White }
}

//esfera
sphere {
<0, 2, 0>, 3
pigment { color rgb <0, 0.6, 0.9> }
finish {
phong 1
reflection 0.3
}
}

Figura 6.3.9: Esfera com reflexo.

O atributo refração só tem sentido em objetos que têm pelo menos um pouco de
transparência. A refração é a flexão dos raios luminosos que passam para uma forma
mais densa ou menos densa. Sem refração, os objetos transparentes possuem a
aparência de ar colorido. Ela só possui dois valores: 0 (desativa a refração) e 1 (ativa a
refração). Valores entre 0 e 1 fazem com que a luz escureça, portanto, a forma mais
adequada para reduzir o brilho da luz refratados é mudar a especificação de cores e de
transparência na declaração da pigmentação.

É preciso lembrar que o valor da refração igual a 1 não faz com que um objeto
fique transparente, é necessário usar transparência no seu pigmento para fazer um objeto
transmitir luz.

Agora, indicando "refraction 1" sozinha não irá mudar a forma como a luz
aborda o objeto, ainda parecerá um ar colorido. Isto porque, por padrão, o ior (índice de
refração) é o mesmo que o de espaço vazio. O índice de refração descreve o quanto luz
“dobra” quando ela passa para dentro e para fora de um objeto. Seus valores são
positivos e, normalmente, superiores a 1.0 (espaço vazio é 1.0).

47
Quadro 6.3.11: Exemplo de declaração do atributo refração.

//o plano irá funcionar como chão


plane {
y, -4
pigment { checker color Black color White }
}
//esfera
sphere {
<0, 2, 0>, 3
pigment { color rgbf <0, 0.6, 0.9, 0.9> }
finish {
refraction 1
ior 1.33

}
}

Figura 6.3.10: Esferas com refração e diferentes valores de ior (à esquerda ior = 1,33; à direita ior = 1,5).

6.4 NORMAL

A componente normal de uma textura permite que você crie efeitos 3D sobre a
superfície de um objeto. Uma vez que grande parte do nosso modo de perceber objetos
baseia-se na forma como eles refletem luz, é possível enganar o olho, fazendo uma
superfície ficar acidentada apenas modificando o vetor normal. Isto é o que o
modificador "normal" faz. Digamos que se quisesse criar um lago com ondulações em
toda a sua superfície, fazer isso matematicamente seria muito trabalhoso, então o POV-
Ray oferece a habilidade de modificar a maneira como luz reflete fora da superfície.
Apesar de não ser 100% realista, é bom o suficiente para a maioria dos fins. Vale
lembrar que especificar um modificador normal para um objeto na realidade não muda a
localização da superfície, apenas o torna diferente na observação.

48
Quadro 6.4.1: Forma geral da declaração da norma.

Normal {
tipo /* OU */
bump_map {
/* especificação do mapeamento de batida*/
}
/* modificadores aqui*/
/* qualquer rotação, escala, e translação vem aqui */
}

A normal possui três partes, o tipo, os modificadores e, em seguida, as


transformações. Uma normal só pode ter um tipo: batida (bumps), acidentes (dents),
ondulações (ripples), oscilações (waves) ou rugas (wrinkles). Cada um possui valores
entre 0,0 (calmo) e 1,0 (violento).

Um modificador que a normal pode ter é a turbulência (vista anteriormente), ela


realmente pode criar normais malucas. Apenas dois tipos de normal (ondulações e
oscilações) respondem aos modificadores "frequnce" e "phase", a freqüência controla a
densidade das ondulações ou oscilações, enquanto a fase controla sua localização.
Incrementando fase de 0,0 a 1,0 trará de volta para o normal quando se iniciou a partir

As transformações que são aplicadas a normal só alteram as localizações dos


componentes normais.

Normais são divertidas e fáceis de especificar. Elas devem ser adicionadas por
último, no "ajuste final" do cenário, e podem transformar um objeto que parece ótimo
em um objeto que parece absolutamente espetacular.

A seguir, os exemplos de tipos de normal serão baseados na figura:

Quadro 6.4.2: Código base para os próximos exemplos.

//a posição da câmera


camera {
location <0, 4, -1>
look_at <0, 0, 0>
}

//cor de fundo preta


background {
color rgb <0, 0, 0> //fundo preto
}

// luz
light_source { <200, 200, -200> color rgb <1, 1, 1> }

49
//plano (chão)
plane {
y, -2
pigment { checker color rgb <1, 1, 1> color rgb <0, 0, 0> }
rotate y*30
}
//esfera
sphere {
<0, 0, 0>, 1.5
pigment { color rgb <1, 0.6, 1> }
finish { phong 0.8 }
normal {
//bumps 0 -> nem é preciso colocar, pois significa liso
}
}

Figura 6.4.1: Cena de uma esfera comum (sem aplicação de normal).

A normal batida cria um padrão aleatório acidentado sobre o objeto. Na verdade,


ele usa um padrão semelhante à pigmentação palhaço. Os valore variam de 0,0 (liso)
para 1,0 (Serrilhado), eles que descrevem a profundidade das batidas. O exemplo a
seguir é uma batida com o valor 1.0.

Quadro 6.4.3: Exemplo de declaração de batida.

Normal {
bumps 1
scale 1/4
}

50
Figura 6.4.2: Esfera batida.

A normal acidente faz, basicamente, com que o objeto fique como se tivesse sido
atacado com uma marreta. Veja o exemplo:

Quadro 6.4.4: Exemplo de declaração da normal acidente.

Normal {
dents 1
scale 1/4
}

Figura 6.4.3: Esfera acidentada.

A normal ondulação cria suaves ondulações na superfícies. Veja o exemplo:

Quadro 6.4.5: Exemplo de declaração de ondulação.

Normal {
ripples 1.0
scale 1/4
translate <0, 2, 0>
}

51
Figura 6.4.4: Esfera com a normal ondulação.

Assim como a ondulação, a oscilação cria ondas na superfície, porém as ondas


são embaralhadas. Teoricamente estas parecem profundas ondas do mar.

Quadro 6.4.6: Exemplo de declaração da oscilação.

normal {
waves 1.0
scale 1/4
translate <0, 2, 0>
}

Figura 6.4.5: Esfera com a normal oscilação.

A normal ruga faz com que o objeto pareça que foi esticado e amassado no lugar
novamente. Veja o exemplo:

Quadro 6.4.7: Exemplo de declaração da normal ruga.

Normal {
wrinkles 1
scale 1/4
translate <0, 2, 0>
}

52
Figura 6.4.6: Esfera com a normal ruga.

O mapeamento de batida é uma espécie de cruzamento entre um mapeamento de


imagem e um campo alto. Ele permite que se mapeiem as normais em torno de um
objeto a partir de um arquivo de imagem. A intensidade do valor do pixel (valor da
escala de cinza) determina a "altura" do ponto correspondente. Podemos alterar esse
mapeamento usando a palavra-chave "use_index”. Eis a sintaxe geral de um
solavanco mapa.

Quadro 6.4.8: Exemplo da declaração do mapeamento de batida.

Normal {
bump_map {
tipo "nome_do_arquivo.tipo"
[bump_size tamanho]
[interpolate modo]
[use_color]
[use_index]
[once]
[map_type modelo_do_mapa]
//todos os parâmetros entre [] são opcionais
}
}
O tipo especifica o tipo de arquivo fonte usado para fazer o mapeamento de
batida, deve ser “gif”, “iff”, “tga”... Em seguida vem o nome completo do arquivo, em
aspas duplas. A imagem será mapeada para o plano xy e redimensionada para que caiba
na gama (0, 0), (1, 1). Para mudar este mapeamento padrão, pode-se usar a palavra-
chave “map_type”. Aumentar a imagens não irá produzir um mapeamento de batidas
maior, mas sim deixá-lo com uma resolução melhor.

O parâmetro “bump_size” é utilizado para controlar a profundidade aparente


das batidas geradas pelo mapeamento de batidas, ele pode assumir qualquer valor desde

53
que não seja 0.0, pois esse valor é ruim. Valores altos vão garantir grandes
profundidades, enquanto os baixos apenas poucas rugas. Valores negativos farão com
que níveis baixos se tornem altos e níveis altos se tornem baixos.

Normalmente, a relação altura de cada ponto da superfície mapeada é


determinada pela intensidade do pixel correspondente, a aparência é de que a imagem
está gravada na superfície. Se preferir ter a altura do mapeamento de batida baseada na
paleta índice da cor (como nos campos altos) você pode incluir a palavra-chave
"use_index". A palavra-chave "use_color" pode ser incluída especificamente para
indicar que um mapeamento de batida usa o comportamento padrão, fora isso ela não
possui efeito algum.

Para suavizar recortes ou baixa resolução do mapeamento de batidas (superfície


parece blocos) usa-se a interpolação. O parâmetro de interpolação diz ao POV-Ray que
tipo de interpolação a utilizar, seu valor pode ser tanto 2 (bilinear) ou 4 (normalizado
pela distância), a interpolação bilinear é melhor, mas a normalizada pela distância é
mais rápida, por padrão, nenhuma interpolação é utilizada.

Apenas para praticar, abaixo temos mais alguns exemplos de aplicação de


textura.

Quadro 6.4.9: Código de um cone com finalização normal.

Cone {
<0,-3,0>,2
<0,3,0>,0.1
texture {
normal {
bumps 1/2
scale 1/6
}
pigment { color rgb <.5,.7,.2> }
}
}

54
Figura 6.4.7: Cone com finalização normal.

Quadro 6.4.10: Código de um plano com finalização normal.

plane {
y, 0
texture {
pigment { color rgb <.1,.9,.9> }
normal {
ripples 0.5
}
}
}

Figura 6.4.8: Plano com finalização normal.

Aprendemos, então, a incluir texturas nos objetos. Mas devemos saber que o
POV-Ray possui uma biblioteca completa de texturas chamada “textures.inc”, que
pode ser incluída como já vimos antes:

Quadro 6.4.11: Exemplo de inclusão da biblioteca “textures.inc”.

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

55
Note que é preciso incluir “colors.inc” antes de “textures.inc”, pois
“textures.inc” utiliza a biblioteca de cor.

O exemplo mostra uma esfera usando uma textura Jade.

Quadro 6.4.12: Exemplo de declaração da textura “jade” inclusa na biblioteca “testure.inc”.

Sphere {
<0, 0, 0>, 4
texture { Jade }
}

Figura 6.4.9: Esfera com a textura “jade”.

A seguir temos uma tabela de texturas existentes nesta biblioteca:

56
Figura 6.4.10: Texturas contidas na biblioteca “texture.inc” (parte1)

6.4.11: Texturas contidas na biblioteca “texture.inc” (parte2)

57
Tabela 6.4.1: Tabela de texturas inclusas na biblioteca “texture.inc”.

//---------- PEDRAS ------- // ------ VIDROS------- // EFEITOS ESPECIAIS


pigment { texture { pigment {
Jade Glass Candy_Cane
Red_Marble Glass2 //”Plexiglas” Y_Gradient
White_Marble Glass3 //”Bleiglas” X_Gradient
Blood_Marble Green_Glass texture {
Blue_Agate NBglass Peel
Sapphire_Agate Nboldglass Water
Brown_Agate Nbwinebottle Cork
Pink_Granite Nbbeerbottle Lightening1
texture { //--------- PEDRAS Ruby_Glass Lightening2
PinkAlabaster Dark_Green_Glass Starfield
Vicks_Bottle_Glass
Yellow_Glass
Orange_Glass
// -------- MADEIRAS -------- // ------ METAIS -------- // --- CÉU e NUVENS ---
pigment { texture { pigment {
Cork Chrome_Metal Blue_Sky
Cherry_Wood Brass_Metal Bright_Blue_Sky
Pine_Wood Bronze_Metal Blue_Sky2
Dark_Wood Gold_Metal Blue_Sky3
Tan_Wood Silver_Metal Blood_Sky
White_Wood Copper_Metal Apocalypse
Tom_Wood Polished_Chrome Clouds
DMFWood1 Polished_Brass FBM_Clouds
DMFWood2 New_Brass texture { // -------Céu
DMFWood3 Spun_Brass Shadow_Clouds
DMFWood4 Brushed_Aluminum
DMFWood5 Silver1 Silver2 Silver3
DMFLightOak Brass_Valley
DMFDarkOak Rust
texture { // ------ Madeira Rusty_Iron
DMFWood6 Soft_Silver
EMBWood1 New_Penny
Yellow_Pine Tinny_Brass
Rosewood Gold_Nugget
Sandalwood Aluminum
Bright_Bronze

7. CSG

CSG (Constructive Solid Geometry) é uma poderosa técnica de POV-Ray que


cria novos objetos a partir de combinações de outros objetos. Desse modo, objetos
primitivos podem assumir formas mais construtivas, é possível retirar partes de objetos,
adicionar partes (mantendo dois objetos juntos) e outras coisas mais, esculpindo-o da
maneira que desejar. A sintaxe é muito simples:

58
CSG_operator {
object_1
object_2
etc.
}

Na realidade, não é preciso colocar nenhum objeto entre as chaves, mas não faz
sentido ter menos de dois objetos (lembrando que o CSG cria novos objetos
combinando outros). A seguir, teremos exemplos e explicações de todos os operadores
(união, intersecção, inverso, diferença e junção).

A união é, talvez, o operador de CSG mais simples, ela é usada para combinar
grupos de objetos juntos em um objeto lógico. Este objeto pode então ser texturizado e
transformado como um todo, de modo que você não tem que lidar com um monte de
pequenos objetos.

Figura 7.1: Exemplo matemático de união.

Quadro 7.1: Exemplo de declaração da união utilizando triângulos.

Union {
triangle { <0,0,1>, <0.866,0,0.5>, <0.2676,0.8236,0.5> }
triangle { <0,0,1>, <0.2676,0.8236,0.5>,
<-0.7006,0.5090,0.5> }
triangle { <0,0,1>, <-0.7006,0.5090,0.5>,
<-0.7006,-0.5090,0.5> }
triangle { <0,0,1>, <-0.7006,-0.5090,0.5>,
<0.2676,-0.8236,0.5> }
triangle { <0,0,1>, <0.2676,-0.8236,0.5>,
<0.8660,0,0.5> }
triangle { <0.8660,0,0.5>, <0.2676,0.8236,0.5>,
<0.7006,0.5090,-0.5> }
triangle { <0.2676,0.8236,0.5>, <-0.7006,0.5090,0.5>,
<-0.2676,0.8236,-0.5> }
triangle { <-0.7006,0.5090,0.5>, <-0.7006,-0.5090,0.5>,
<-0.8660,0,-0.5> }
triangle { <-0.7006,-0.5090,0.5>, <0.2676,-0.8236,0.5>,
<-0.2676,-0.8236,-0.5> }
triangle { <0.2676,-0.8236,0.5>, <0.8660,0,0.5>,
<0.7006,-0.5090,-0.5> }
triangle { <0.7006,0.5090,-0.5>, <-0.2676,0.8236,-0.5>,
<0.2676,0.8236,0.5> }
triangle { <-0.2676,0.8236,-0.5>, <-0.8660,0,-0.5>,

59
<-0.7006,0.5090,0.5> }
triangle { <-0.8660,0,-0.5>, <-0.2676,-0.8236,-0.5>,
<-0.7006,-0.5090,0.5> }
triangle { <-0.2676,-0.8236,-0.5>,
<0.7006,-0.5090,-0.5>,
<0.2676,-0.8236,0.5> }
triangle { <0.7006,-0.5090,-0.5>, <0.7006,0.5090,-0.5>,
<0.8660,0,0.5> }
triangle { <0,0,-1>, <0.7006,0.5090,-0.5>,
<-0.2676,0.8236,-0.5> }
triangle { <0,0,-1>, <-0.2676,0.8236,-0.5>,
<-0.8660,0,-0.5> }
triangle { <0,0,-1>, <-0.8660,0,-0.5>,
<-0.2676,-0.8236,-0.5> }
triangle { <0,0,-1>, <-0.2676,-0.8236,-0.5>,
<0.7006,-0.5090,-0.5> }
triangle { <0,0,-1>, <0.7006,-0.5090,-0.5>,
<0.7006,0.5090,-0.5> }
//texturas, rotações, escalas e translações vem aqui
pigment { color rgb <0, 1, 0> }
}

Figura 7.2: União feita com triângulos.

Podemos criar um objeto com um grande número de componentes e agrupá-los


todos juntos em uma união, depois disso, transformá-los, transformando apenas a união
em vez de ter de transformar todos os objetos individuais. Além disso, a textura também
pode ser usada no objeto como um todo.

O operador junção é muito semelhante à união, pois possui basicamente a


mesma finalidade, juntando um grupo de objetos e formando apenas um. A junção, no
entanto, difere da união pelo fato de que as superfícies que estão dentro do objeto são
removidas. De qualquer maneira, isso não tem importância em objetos opacos, porque
as superfícies internas não são visíveis.

Quadro 7.2: Exemplo de declaração da junção.

60
merge{sphere{<0,1,0>,0.35}
cone{<0,-1,0>,1,<0,1.2,0>,0}
pigment{color rgbf <0,0,1,0.6>}
translate <-0.5, 0, 0>
}

Figura 7.3: Diferença entre união e junção (à esquerda foi aplicada a união e à direita a junção).

Note que na primeira imagem, onde usamos a união, a ponta do cone é visível, já
na segunda, usando a junção a ponta do cone desapareceu, como se os dois objetos
fossem realmente um só.

A diferença é utilizada para esculpir as formas de um objeto. A diferença é


especificada da mesma forma que as outras especificações de CSG. O primeiro objeto
especificado é o objeto na qual se quer esculpir, os objetos subsequentes são utilizados
para esculpir o primeiro objeto. A diferença é o único objeto CSG em que a ordem dos
objetos importa.

Figura 7.4: Exemplo matemático de diferença.

Veja o exemplo:

Quadro 7.3: Exemplo de declaração da diferença.

difference {
sphere { <0, 0, -1>, 1
translate 0.5*x
pigment { Red }
rotate 90*y
finish { Shiny }
}

61
cylinder { <-0.5, 0, -2> <0, 0, 1>, .35
pigment { Blue }
}
}

Figura 7.5: Diferença entre união e diferença (à esquerda há uma união entre
os objetos e à esquerda uma diferença).

A primeira figura é a união de uma esfera com um cilindro, já a segunda é a


diferença, podemos notar que permaneceu o “encaixe” do cilindro na circunferência.

Outra coisa a notar é que boa parte da superfície do cilindro está pra fora da
esfera (mais comprido), isso porque, ocasionalmente, o POV-Ray vai ficar confuso
quando se tem dois objetos que ocupam exatamente o mesmo espaço.

Lembrando que mais uma vez, todos os atributos colocados no final da


declaração da diferença serão aplicados a todo o objeto.

A intersecção de dois ou mais objetos é composta por todos os pontos que estão
dentro de todos os objetos ao mesmo tempo. A ordem dos objetos enumerados na
declaração não importa.

Figura 7.6: Exemplo matemático da intersecção.

Vejamos o exemplo:

Quadro 7.4: Exemplo de declaração da intersecção.

intersection{
box {<-0.5,-0.5,-0.5>,< 0.5,0.5,0.5>
texture{pigment{color rgb<1,0.65,0>}

62
finish {ambient 0.15
diffuse 0.85}}
}
sphere{<0,0,0>,0.66
texture{pigment{color Red}
finish {ambient 0.15
diffuse 0.85}}
}
rotate<0,-30,0> translate<0,0.5,0>}

Figura 7.7: Diferença entre união e intersecção (à esquerda há uma união entre
os objetos e à direita uma intersecção).

O resultado é o volume corresponde ao espaço que está contido no interior de


ambos os objetos. Podemos notar a diferença das cores na fronteira do objeto, o que é
vermelho está no limite da esfera e o que é laranja está no limite da caixa. A interseção,
juntamente com o seu parente próximo, a diferença, é provavelmente a mais poderosa
diretiva CSG e é muito interessante para a criação de novos objetos.

O inverso não é utilizado com muita frequência, mas existem momentos em que
ele será essencial. Seu objetivo é inverter o que o POV-Ray considera ser o interior do
objeto com o exterior. Considere a interseção de uma esfera e um caixa. Se a esfera for
invertida teremos a intersecção da caixa com um objeto definido como "todo o universo
com exceção da esfera." Veja que este efeito pode ser feito também com a diferença:

Figura 7.8: Exemplo matemático de inversão.

Quadro 7.5: Exemplo de declaração da inversão.

intersection{

63
box {<-0.5,-0.5,-0.5>,< 0.5,0.5,0.5>
texture{pigment{color rgb<1,0.65,0>}
finish {ambient 0.15
diffuse 0.85}}
}
sphere{<0,0,0>,0.66
texture{pigment{color Red}
finish {ambient 0.15
diffuse 0.85}}
}
cylinder{<0,0,-1>,<0,0,1>,0.3
inverse
texture{pigment{color YellowGreen}
finish {ambient 0.15
diffuse 0.85}}}
cylinder{<0,-1,0>,<0,1,0>,0.3
inverse
texture{pigment{color YellowGreen}
finish {ambient 0.15
diffuse 0.85}}}
cylinder{<-1,0,0>,<1,0,0>,0.3
inverse
texture{pigment{color YellowGreen}
finish {ambient 0.15
diffuse 0.85}}}
rotate<0,-30,0> translate<0,0.5,0>}

Figura 7.9: Diferença entre união e inversão (à esquerda há uma união


entre os objetos e à direita uma inversão).

Apesar de todos os recursos, pode ocorrer uma situação em que nem as


primitivas geométricas do POV-Ray usando CSG serão suficientes para descrever um
objeto. Neste caso, existem duas opções:

A primeira será especificar o objeto em termos matemáticos. Obviamente, essa


opção é muito difícil, a não ser que se saiba o que está fazendo.

A segunda opção é usar um programa modelador. O programa pode fazer uma


modelagem extremamente complexa usando indicações simples, como as primitivas

64
geométricas. É possível encontrar bons programas de modelação (muitos gratuitos e
shareware), assim você irá economizar tempo e esforço.

8. ILUMINAÇÃO

Já percebemos que a luz é um fator fundamental para visualizarmos objetos na


terceira dimensão, além de ser essencial para o uso da maioria dos efeitos da textura,
fazendo com que os objetos pareçam reais. Vamos, então, falar um pouco mais sobre
iluminação no POV-Ray.

A declaração “light_source” permite declarar vários tipos de luzes para a sua


cena. Existem quatro tipos de fontes de luz que podem ser definidas. A mais básica é a
luz pontual, que é (como vimos) um ponto geométrico a partir do qual emanam raios
luminosos para todos os lados. Suas propriedades são apenas a sua cor e a sua posição.
O segundo tipo é o foco de luz, estes são, basicamente, fontes de luz pontuais que
emanam raios luminosos apenas em certas direções. O terceiro tipo é a área luminosa,
estas não são mais simples pontos de luz, mas sim um conjunto de luz que pode ser
utilizado para tornar as sombras mais realista. O quarto tipo é uma área de foco de luz,
que nada mais é do que uma área de luz direcional. A seguir mostramos a forma geral:

Quadro 8.1: Forma geral para a declaração dos tipos de iluminação.

light_source {
/* o vetor posição e a cord a luz são sempre necessários */
<localização>
color especificação_da_cor

/* especificações de focos de luz (opcional) */


spotlight
point_at <vetor_da_direção>
radius valor
falloff valor
tightness valor //opcional

/* especificações da area luminosa (opcional) */


area_light <lado-1>, <lado-2>, len-1, len-2
adaptive valor //opcional
jitter //opcional

/* mais especificações opcionais */


looks_like {
object { obj }
}
}

65
Como sabemos, os dois componentes necessários de uma fonte de luz são a sua
localização e sua cor, portanto, todas as fontes de luz deve ter estes dois definidos. A
localização é um vetor de três posições <x, y, z>. A cor é parâmetro utilizado para
definir a cor da fonte luminosa (a declaração de cor já foi explicada anteriormente).

Os focos de luz são utilizados para, como o nome já diz, criar focos de luz. Eles
servem para enfatizar partes de uma cena, ou apenas selecionar os objetos que serão
iluminados.

A área luminosa cria uma área que emite luz, muito bom para criar cenas mais
reais. Ela pode ser usada em conjunto com o foco de luz, desse modo os dois efeitos são
somados para uma determinar a iluminação da cena.

O parâmetro “looks_like” pode ser usado para atribuir uma "forma" para a
luz.

Vamos declarar uma cena com a iluminação simples, como a conhecemos:

Quadro 8.2: Exemplo de declaração de iluminação pontual simples.

// luz
light_source {
<0,20,-30>
color rgb <1,1,1>
}
union {
torus {
5, 0.5
rotate <90, 0, 0>
}
cylinder {
<0, 0, 0>, <0, 10, 0>, 0.5
}
pigment { color rgb <0.5, 0.5, 1> }
}
plane {
y, 0
pigment {
checker color rgb <0.75, 0, 0.75> color rgb <0.5, 0, 0.5>
scale 3
}
}

66
Figura 8.1: Cena com iluminação pontual simples.

Vamos começar conhecendo os focos de luz. Focos de luz permitem especificar


luzes que possuem determinadas direções. Qualquer luz pode ser transformada em um
foco de luz.

Todos os parâmetros do foco de luz precisam ser especificados com exceção do


tightness, este é opcional. Em um foco de luz, podem ser considerados dois cones de luz
coaxiais. O cone interno é totalmente iluminado pela luz e seu raio angular é indicado
pela palavra-chave "radius". O cone externo é a região em que a luz não chega(falloff).
A palavra chave “tightness” pode ser usada para controlar o modo como a luz cai na
parte apagada, entre os ângulos radius e falloff. Veja o exemplo:

Quadro 8.3: Exemplo de declaração de foco de luz pontual.

light_source {
<0,20,-30>
color rgb <1,1,1>

spotlight
point_at <0, 0, 0>
radius 20
falloff 20
}

67
Figura 8.2: Cena com foco de luz pontual (valor do radius igual ao valor de fallof).

O “point_at” é similar ao “look_at” na declaração da câmera, ele define a


direção do foco de luz. O valor do radius indica, como foi dito, o ângulo da parte
iluminada, portanto se ele for menor, um feixe menor de luz irá incidir na cena, caso
seja maior um feixe maior de luz incidirá na cena. O valor de falloff indica o ângulo da
parte que está apagada, caso o valor seja menor do que o do radius nada irá mudar, pois
a parte apagada fica iluminada. Caso o valor de falloff seja maior que o valor do radius
haverá uma leve sombra entre a parte acesa e a parte apagada conforme o exemplo:

Figura 8.3: Cena com foco de luz pontual com fallof maior que radius (fallof = 30 e radius = 20).

Um efeito parecido pode ser simulado pelo modificador opcional tightness. Ele
controla como a forma da luz decresce a zero na borda do falloff. Também controla, um
pouco, a queda de luz no centro do foco de luz. O seu valor padrão é 10.

Quadro 8.4: Exemplo de declaração do modificador tightness.

light_source {
<0,20,-30>

68
color rgb <1,1,1>

spotlight
point_at <0, 0, 0>
radius 20
falloff 20
tightness 50
}

Figura 8.4: Cena com foco de luz e tightness.

As áreas luminosas são utilizadas para espalhar a sombra e torná-la mais realista.
Quando a luz é pontual, ou ela é visível ou não é, portanto ou uma área é sombreada, ou
não é. A área luminosa tenta mudar essa situação espalhando a intensidade da luz para
fora em um retângulo, uma vez que a luz tem um espaço, ela pode ser parcialmente
bloqueada, deixando as sombras com bordas suaves.

lado-1 e lado-2 são vetores <x, y, z> que descrevem a orientação dos lados,
como a área luminosa é retangular, estes vetores devem ser perpendiculares. Os
comprimentos desses vetores correspondem aos comprimentos dos lados. len-1 e len-2
são o número de luzes ao longo das dimensões correspondentes da luz. A intensidade da
luz é dividida entre esses pontos.

Quadro 8.5: Exemplo de declaração de área luminosa.

light_source {
<0,20,-30>
color rgb <1,1,1>

area_light <4, 0, 0>, <0, 0, 4>, 8, 8


// 8*8 = 64 pontos de luz
}

69
Figura 8.5: Cena com iluminação feita por uma área luminosa.

A palavra-chave “adaptive” é um controle da área de prestação de luz.


Normalmente, quando se cria uma zona de luz, o POV-Ray tem de testar a visibilidade
de cada ponto na tabela. O adaptative diz ao POV-Ray para usar uma cera área de
amostragem, essa amostragem é na verdade apenas os testes de visibilidades nos cantos
da luz. Se aproximadamente a mesma quantidade de luz é recebida por cada canto, o
POV-Ray assume que a luz será totalmente visível ou totalmente bloqueada, se
quantidades diferentes de luz são recebidas, o POV-Ray assume que a luz é
parcialmente visível e a divide ainda mais a fim de determinar quanta sombra usar. O
parâmetro é um valor inteiro e positivo, que controla a quantidade mínima de
subdivisões a utilizar. Um valor 0, fará seu primeiro teste com apenas quatro raios (cada
um dos cantos), embora rápido, o valor pode levar a erros nas sombras (que se
manifestam como manchas brilhantes onde não deveria haver). Note que o POV-Ray
não fará testes com mais raios do que luzes.

A palavra-chave “jitter” aplica-se somente a áreas luminosas, ela não possui


parâmetro algum, ou se usa, ou não. Caso use, cada raio da fonte de luz será modificado
por um pequeno valor aleatório. Isto cria sombras suaves que não possuem faixas de
intensidades diferentes. Esta funcionalidade pode ser usada para criar sombras suaves,
sem gigantescos espaços de luz que levam muito tempo para serem renderizados. No
entanto, jitter é uma característica completamente aleatória (como o crand) e não será a
mesma se usarmos duas vezes na mesma cena. Por esta razão, não é uma boa idéia usá-
lo em animações.

Como já foi dito, podemos juntar o foco de luz com a área luminosa, o efeito
fica muito bom.

70
Quadro 8.6: Exemplo de declaração de área de foco de luz.

light_source {
<0,20,-30>
color rgb <1,1,1>

spotlight
point_at <0, 0, 0>
radius 20
falloff 30
tightness 20

area_light <4, 0, 0>, <0, 0, 4>, 8, 8


//adaptive 20
jitter
}

Figura 8.6: Cena com iluminação feita por uma área de foco luminoso.

9. A LINGUAGEM

Até agora, a criação de um grande número de objetos similares tem sido um


exercício de “copiar e colar”. Veremos, então, que o POV-Ray proporciona uma
funcionalidade poderosa e flexível para criar muitos objetos similares usando uma
declaração. A declaração de vê ser do tipo “#declare” e pode ser utilizada para criar
um novo tipo de objeto (ou pigmentos, ou textura, ou quase tudo) que você pode usar e
re-usar sempre que quiser. Dê uma olhada no seguinte código:

Quadro 9.1: Exemplo de declaração de objeto.

#declare minha_esfera =
sphere {
<0, 0, 0>, 5
pigment{ color rgbf <0.5, 0.2, 0.4, 0.667>}

71
}

Esta é uma declaração de um novo tipo de objeto chamado "minha_esfera",


que agora podemos usar mais tarde no código fonte, desta maneira:

Quadro 9.2: Exemplo de referência à declaração.

object {
minha_esfera
translate <-2, 0, 0>
}

A declaração do objeto diz ao POV-Ray para criar um objeto do tipo


"minha_esfera". Podemos colocar na declaração qualquer objeto que iremos usar.

Note que todos os atributos que você coloca dentro do objeto substitui aqueles
que estão na declaração do mesmo, neste exemplo, a nossa esfera é deslocado da sua
localização original em <0,0,0> para <-2,0,0>. Isso é valido também para os outros
atributos (pigmentação, finalização, etc.).

Os programadores de VRML devem tomar nota que esta declaração difere


ligeiramente do DFN no VRML. “#declare” não cria uma instância do objeto (função
do DFN), e sim uma definição. Em outras palavras, a declaração não adiciona quaisquer
objetos por conta própria, ela faz apenas a definição, então, é preciso instanciar os
objetos (usando a palavra-chave “object”) para adicioná-los.

Mas, para que finalidade a declaração seria útil? Simples, imagine, por exemplo,
que se queira fazer um templo grego, seria preciso muitos pilares. Ou quem sabe fazer
um círculo de balas:

Quadro 9.3: Exemplo de cena simplificada pela declaração de objeto.

#declare bala =
sphere {
<0,0,0>,0.25
texture{ pigment{ color rgb<1,0,0.35>}
finish { phong 1}
}
scale<1.5,1,1>
translate<1,0.25,0>
}

union{
object{ bala rotate<0,0,0>}

72
object{ bala rotate<0,18,0>}
object{ bala rotate<0,36,0>}
object{ bala rotate<0,54,0>}
object{ bala rotate<0,72,0>}
object{ bala rotate<0,90,0>}
object{ bala rotate<0,108,0>}
object{ bala rotate<0,126,0>}
object{ bala rotate<0,142,0>}
object{ bala rotate<0,160,0>}
object{ bala rotate<0,178,0>}
object{ bala rotate<0,196,0>}
object{ bala rotate<0,214,0>}
object{ bala rotate<0,232,0>}
object{ bala rotate<0,250,0>}
object{ bala rotate<0,268,0>}
object{ bala rotate<0,286,0>}
object{ bala rotate<0,304,0>}
object{ bala rotate<0,322,0>}
object{ bala rotate<0,340,0>}

rotate<0,0,0>
translate<0,0,0>
}

Figura 9.1: Cena feita utilizando declaração de objetos.

Note que os atributos do objeto “bala” não precisaram ser repetidos. Podemos
declarar, não só objetos, como também tipos de pigmentação, finalizações...

Quadro 9.4: Exemplo de cena simplificada pela declaração de texturas.

#declare filtro_azul = rgbf <0, 0.5, 0.5, 0.5>

#declare vidro_vermelho =
texture {
finish {
refraction 1.0
reflection 0.1
ior 1.5
}

73
pigment {
color rgbf <1, 0.7, 0.7, 0.7>
}
}

sphere {
<-3, 0, -3>, 3
pigment { filtro_azul }
}

cone {
<-2, -4, 16>, 5
<0, -3, 1>, 1
texture { vidro_vermelho }
}

Figura 9.2: Cena feita utilizando declaração de texturas.

Simples, e podemos personalizar bastante, até mesmo usando o “#declare”


para declarar números únicos. Isto irá poupar-lhe um pouco de digitação!

Os programadores de C e C++ podem ser induzidos ao erro pelo fato do


“#declare” ter certa semelhança com o pré-processador “#define” do C/C++.
Lembre-se que o seu comportamento é bastante diferente, pois “ #define” é compilado
antes e realmente modifica o código fonte que. O POV-Ray não tem um pré-
processador, e, portanto não fará nenhuma modificação no código fonte.

A linguagem de descrição de cenas (SDL) do POV-Ray aceita, como a maioria


das linguagens, comandos de controle de fluxo, ou seja, aqueles comandos que
permitem ao programador alterar a sequência de execução do programa. Vamos dar
uma breve introdução dos comandos de controle de fluxo.

O comando “if” representa uma tomada de decisão do tipo "SE isto ENTÃO
aquilo". Já o “if-else” representa dois comandos de tomada de decisão ("SE isto

74
ENTÃO aquilo SENÃO aquilo lá"). Ambos representam uma condição. Veja a forma
geral:

Quadro 9.5: Exemplo de condição if.

#if (Condição)
... declaração
#else // (opcional)
... declaração 2
#end

A condição do comando “if” é uma expressão que será avaliada. Se ela for
falsa a declaração não será executada ou (se houver”else”) em seu lugar será
executada a declaração a partir do “else” (declaração 2), e, se for verdadeira a
declaração será executada. A declaração pode ser um bloco de código ou apenas um
comando.

Outro comando que representa uma condição é o swith. O comando switch é


próprio para se testar uma variável em relação a diversos valores pré-estabelecidos. Sua
forma geral é:

Quadro 9.6: Exemplo de condição switch.

#switch (variável)
#case (variável_valor1)
... declaração
#break
#case (variável_valor2)
... declaração
#break
#range (variável_valor_inicio,variável_valor_fim)
... declaração
#break
#else // (opcional)
... declaração
#break
#end // fim da #switch

Podemos fazer uma analogia entre o switch e uma estrutura “if-else-if”. A


diferença fundamental é que a estrutura switch não aceita expressões, ela aceita apenas
constantes. O switch testa a variável e executa a declaração cujo “#case” corresponda
ao valor atual da variável. No caso de range, o valor da variável precisa estar entre dois
valores. A declaração de “#else” é opcional e será executada apenas se a variável, que
está sendo testada, não for igual a nenhuma das constantes.

75
O comando “#break” faz com que o switch seja interrompido assim que uma
das declarações seja executada, mas ele não é essencial ao comando switch. Se após a
execução da declaração não houver um “#break”, o POV-Ray continuará executando.
Isto pode ser útil em algumas situações, mas é bom tomar cuidado.

Na (SDL) do POV-Ray, existem outras estruturas de condição que dependem do


fato da variável ter sido declarada ou não. A seguir temos um exemplo de uma condição
que checa se a variável foi declarada, caso tenha sido a declaração será executada, caso
contrário ela não será e (opcionalmente) outra declaração será executada (a
declaração2).

Quadro 9.7: Exemplo de condição afirmativa de declaração.

#ifdef (variável)
... declaração
#else // (opcional)
... declaração2
#end

Agora vamos exemplificar o oposto, uma condição que checa se a variável não
foi declarada:

Quadro 9.8: Exemplo de condição negativa de declaração.

#ifndef (variável)
... declaração
#else // (opcional)
... declaração2
#end

Falando de declaração, a SDL do POV-Ray possui um comando que destrói uma


declaração de variável. Caso haja mais variáveis com o mesmo nome, o comando
destrói a declaração mais recente no código.

Quadro 9.9: Exemplo de destruição de declaração.

#undef (Variável)

O loop (laço) “#while” é um comando de controle de fluxo usado para repetir


um comando, ou bloco de comandos, diversas vezes, de maneira que se possa ter um
bom controle sobre o loop. Na SDL do POV-Ray, o comando “#while” pode ser usado

76
de várias formas, de modo que substitui outros tipos de loops encontrados outras
linguagens de programação. A forma geral é esta:

Quadro 9.10: Exemplo de loop.

#while (condição)
... declaração
#end

Ao pé da letra, este comando seria “ENQUANTO condição FAÇA isto”. Note


que a declaração se repete enquanto a condição for verdadeira. O “#while” pode ser
usado como “repeat-until” da linguagem C, se em vez da condição em si,
colocarmos uma condição contrária. Também pode ser usado como comando “for”, se
a condição for a comparação de uma variável e incrementarmos ela na declaração.

Vamos, então, exemplificar o uso desses comandos de controle de fluxo.

Quadro 9.11: Exemplo de cena utilizando comandos de controle de fluxo.

union{
#local Nr = 0; // numero começo
#local EndNr = 20; // numero fim
#while (Nr< EndNr) //enquanto começo for menor que fim, faça:
sphere{ <0,0,0>,0.25
#if( Nr/2 = int(Nr/2) )//se começo for um numero par
texture{ pigment{ color rgb<1,0.65,0>}
finish { phong 1}
}
scale<1,1.5,1>

#else // se começo for ímpar


texture{ pigment{ color rgb<1,0,0.35>}
finish { phong 1}
}
scale<1.5,1,1>

#end // fim do "if"


translate<1,0.25,0>
rotate<0,Nr * 360/EndNr,0>}

#local Nr = Nr + 1; // proximo numero


#end // --------------- fim do loop

rotate<0,0,0>
translate<0,0,0>
} // fim da união -------------------

77
Figura 9.3: Cena feita utilizando comandos de controle de fluxo.

10. ANIMAÇÕES

Bem, é isso mesmo que você leu. Além de ter a possibilidade de construir cenas
incríveis com o POV-Ray, ele também oferece a você a possibilidade de criar
animações.

Para uma animação com o POV-Ray, são necessários dois tipos de arquivos:

• um arquivo de cena no POV-Ray (extensão: .pov, aquela que utilizamos até


agora), que usa um valor de clock;

• um arquivo de animação no POV-Ray (extensão:. ini), que define o valor do


clock.

O clock no POV-Ray pode ser usado para animar um grande número de coisas,
objetos, câmera, texturas etc. A melhor maneira de entender como a animação funciona
é ver um exemplo de como tudo acontece. Para isso, vamos utilizar uma cena simples
como esta:

Quadro 10.1: Exemplo de cena que pode ser animada.

#include "colors.inc"
#include "textures.inc"
//global_settings { assumed_gamma 1.0 }
//---------------------------------------
camera{ location <0.0 , 1.0 ,-3.0>
look_at <0.0 , 0.0 , 0.0> }
//---------------------------------------
light_source{ <1500,2500,-2500>

78
color rgb<1,1,1> }
//---------------------------------------
plane{ z, 10
texture { Shadow_Clouds }}
//---------------------------------------
// a esfera que será animada:
sphere{ <0,0,0>, 0.5
texture {DMFWood3//textura de madeira
finish { diffuse 0.9
phong 1}}
translate < 1, 0, 0>
rotate < 360*clock 0>
}

Figura 10.1: Cena que será utilizada para animação.

Note que a esfera é deslocado para o lado direito pela declaração translate
<1,0,0>. Em seguida, ela será animada, rodando em torno do eixo y (rotate
<0,360*clock 0>). Lembre-se de que é preciso certificar que a translação é feita
antes da rotação, para que a animação fique correta.

O valor do "clock" (nulo por padrão) será definido pelo arquivo de animação,
portando não é necessário declará-lo, mas declarando-o podemos ver como nossa cena
muda com o tempo, substituindo o valor do clock.

Agora vamos criar um arquivo de animação, note que este arquivo precisa estar
no mesmo diretório que o arquivo de descrição da cena. Nesse arquivo de animação
(.ini) ao invés dos comentários serem escritos após “//”, eles são escritos após “;”.

Quadro 10.2: Exemplo de arquivo de animação .ini.

; arquivo de anomação
Antialias=Off
Antialias_Threshold=0.1
Antialias_Depth=2

79
Input_File_Name=esfera.pov

Initial_Frame=1
Final_Frame=30
Initial_Clock=0
Final_Clock=1

Cyclic_Animation=on
Pause_when_Done=off
Para iniciarmos a apresentação da animação, temos que rodar o arquivo de
animação e não o arquivo da cena. O POV-Ray irá iniciar a renderização do arquivo
"sesfera.pov" com o valor do "clock" igual a 0 e guardará a imagem resultante
como “frame#1”, o nome do arquivo será "esfera101.bmp".

Em seguida, o programa calcula o próximo valor do "clock" (novo clock =


clock final + 1/Final_Frame, aqui fica: 0 + 1 / 30) e começa a transformação da nossa
cena "esfera.pov" novamente. A saída será guardada como "esfera102.bmp". E este
processo continua até que o valor do "clock" seja igual a 1 é alcançado e o arquivo de
saída seja "esfera130.bmp".

esfera101.bmp esfera102.bmp esfera103.bmp

esfera104.bmp esfera105.bmp esfera106.bmp

esfera107.bmp esfera108.bmp esfera109.bmp

80
esfera110.bmp esfera111.bmp esfera112.bmp

esfera113.bmp esfera114.bmp esfera115.bmp

esfera116.bmp esfera117.bmp esfera118.bmp

esfera119.bmp esfera120.bmp esfera121.bmp

esfera122.bmp esfera123.bmp esfera124.bmp

esfera125.bmp esfera126.bmp esfera127.bmp

81
esfera128.bmp esfera129.bmp esfera130.bmp
Figura 10.2: Frames gerados pela animação no POV-Ray.

O POV-Ray não é capaz de salvar a saída de uma animação de outra forma, a


não ser frames enumerados. Mas podemos usar um visualizador gráfico rápido para vê-
la. Para salvar a animação em um formato animado (gif, avi, mov ou mpeg) temos de
utilizar outros programas.

11. CONCLUSÃO

Caminhamos ao longo do tutorial e muitas funcionalidades do POV-Ray, assim


como seus exemplos foram mostrados para que você possa familiarizar-se com a
linguagem e construir sua própria cena. No entanto, este é apenas o começo de sua
jornada através do pleno POV-Ray. Este tutorial ajuda você na medida do possível,
agora é preciso experiência. A principal diferença entre um bom artista POV-Ray e um
fabuloso artista POV-Ray é a experiência com raios e, eventualmente, um hardware
melhor, mas isso não é tão importante. Há um grande número de bibliotecas na internet
e muitas delas incluem código fonte, procurá-las e ver como grandes artistas fazem uso
das funcionalidades seria um bom começo. A seguir temos algumas cenas criadas pelos
melhores artistas de POV-Ray:

82
Figura 11.1: “Christmas Baubles” feita felo artista Jaime Vives Piqueres.

Figura 11.2: “Glasses” feita pelo artista Grilles Tran.

83
Figura 11.3: “Boreal” feita por Norbert Kern.

Figura 11.4: “Distant Shores” feita pelo artista Christoph Gerber.

Boa sorte em sua jornada POV-Ray.

11. BIBLIOGRAFIA

84
LOHMÜLLER, Andrea; LOHMÜLLER, Friendrich A. <http://www.f-
lohmueller.de/index.htm>. (21/06/09).

MANSSOUR, Isabel Harb. <http://www.inf.pucrs.br/~manssour/CG/index.html>.


(21/06/09).

MORAES, Cícero. <http://computacaograficabrasil.com/>. (21/06/09).

Aftreth, Owen; Emery, Grant; Morgan, William. <http://library.thinkquest.org/3285/>.


(21/06/09).

Site Oficial. <http://www.povray.org/>. (21/06/09)

85

Vous aimerez peut-être aussi