tutorial pov ray

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

Upload: andrsantana8059

Post on 27-Jun-2015

1.112 views

Category:

Documents


73 download

TRANSCRIPT

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

3

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

4

LISTA DE QUADROS

Quadro 4.1 Exemplo de comentário............................................................14Quadro 5.1 Exemplo de posicionamento da câmera...................................14Quadro 5.2 Exemplo de declaração da cor de fundo...................................15Quadro 5.3 Exemplo de inclusão da biblioteca “colors.inc”.......................15Quadro 5.4 Exemplo de uma cena contendo uma esfera vermelha.............17Quadro 5.5 Exemplo de luz pontual na cena da esfera vermelha................19Quadro 5.6 Exemplo de um cilindro...........................................................20Quadro 5.7 Exemplo de cone......................................................................21Quadro 5.8 Exemplo de caixa.....................................................................22Quadro 5.9 Exemplo de triângulo...............................................................22Quadro 5.10 Exemplo de bolha...................................................................23Quadro 5.11 Exemplo de disco...................................................................24Quadro 5.12 Exemplo de plano infinito......................................................24Quadro 5.13 Exemplo de campos altos.......................................................25Quadro 5.14 Exemplo de mudança de escala, rotação e translação em um toro..........................................................................................27Quadro 6.1.1 Forma correta de declarar a pigmentação..............................28Quadro 6.1.2 Exemplo de declaração de mapeamento de cor com informação completa..............................................................29Quadro 6.1.3 Exemplo de declaração de mapeamento de cor.....................29Quadro 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...............30Quadro 6.2.1 Exemplo de declaração da pigmentação gradiente................32Quadro 6.2.2 Exemplo de aplicação de turbulência....................................33Quadro 6.2.3 Exemplo de declaração da pigmentação mármore................34Quadro 6.2.4 Exemplo de declaração da pigmentação ágata......................34Quadro 6.2.5 Exemplo de declaração da pigmentação palhaço..................35Quadro 6.2.6 Exemplo de declaração da pigmentação tabuleiro de xadrez....................................................................................37Quadro 6.2.7 Exemplo de declaração da pigmentação hexágono...............37Quadro 6.2.8 Forma gera da declaração de mapeamento de imagem.........38Quadro 6.2.9 Exemplo de declaração da pigmentação mapeamento de Imagem..................................................................................39Quadro 6.3.1 Forma gera da declaração de finalização..............................40Quadro 6.3.2 Exemplo de declaração do atributo ambiente........................40Quadro 6.3.3 Exemplo de declaração do atributo brilho.............................41Quadro 6.3.4 Exemplo de declaração do atributo crand.............................42Quadro 6.3.5 Exemplo de declaração de difusão........................................42Quadro 6.3.6 Exemplo de declaração do atributo phong............................43Quadro 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.................45Quadro 6.3.9 Exemplo de declaração do atributo polido............................45Quadro 6.3.10 Exemplo de declaração do atributo reflexão em uma cena.46Quadro 6.3.11 Exemplo de declaração do atributo refração.......................48Quadro 6.4.1 Forma geral da declaração da normal....................................49Quadro 6.4.2 Código base para os próximos exemplos..............................49Quadro 6.4.3 Exemplo de declaração de batida..........................................50Quadro 6.4.4 Exemplo de declaração da normal acidente..........................51Quadro 6.4.5 Exemplo de declaração de ondulação...................................51Quadro 6.4.6 Exemplo de declaração da oscilação.....................................52Quadro 6.4.7 Exemplo de declaração da normal ruga................................52Quadro 6.4.8 Exemplo de declaração do mapeamento de batida................53Quadro 6.4.9 Código de um cone com finalização normal.........................54Quadro 6.4.10 Código de um plano com finalização normal......................55Quadro 6.4.11 Exemplo de inclusão da biblioteca “texture.inc”................55Quadro 6.4.12 Exemplo de declaração da textura “Jade” inclusa na biblioteca “texture.inc”........................................................56Quadro 7.1 Exemplo de declaração da união utilizando triângulos............59Quadro 7.2 Exemplo de declaração de junção............................................60Quadro 7.3 Exemplo de declaração da diferença........................................61Quadro 7.4 Exemplo de declaração da intersecção.....................................62Quadro 7.5 Exemplo de declaração da inversão.........................................63Quadro 8.1 Forma geral para a declaração dos tipos de iluminação...........65Quadro 8.2 Exemplo de declaração de iluminação pontual simples...........66Quadro 8.3 Exemplo de declaração de foco de luz pontual........................67Quadro 8.4 Exemplo de declaração do modificador tightness....................68Quadro 8.5 Exemplo de declaração de área luminosa.................................69Quadro 8.6 Exemplo de declaração de área de foco de luz.........................71Quadro 9.1 Exemplo de declaração de objeto.............................................71Quadro 9.2 Exemplo de referência à declaração.........................................72Quadro 9.3 Exemplo de cena simplificada pela declaração de objeto........72Quadro 9.4 Exemplo de cena simplificada pela declaração de texturas.....73Quadro 9.5 Exemplo de condição if............................................................75Quadro 9.6 Exemplo de condição switch....................................................75Quadro 9.7 Exemplo de condição afirmativa de declaração.......................76Quadro 9.8 Exemplo de condição negativa de declaração..........................76Quadro 9.9 Exemplo de destruição de declaração......................................76Quadro 9.10 Exemplo de loop.....................................................................77Quadro 9.11 Exemplo de cena utilizando comandos de controle de fluxo.77Quadro 10.1 Exemplo de cena que pode ser animada.................................78Quadro 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”..................16Tabela 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âmeracamera { location <2,5,-10> look_at <0,0,0>}

//cor de fundo pretabackground { 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âmeracamera { location <2,5,-10> look_at <0,0,0>}

//cor de fundo pretabackground { 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 Copper01 = color White 35 = color MediumGoldenrod 69 = color Bronze02 = color Red 36 = color MediumOrchid 70 = color Bronze203 = color Green 37 = color MediumSeaGreen 71 = color Silver04 = color Blue 38 = color MediumSlateBlue 72 = color BrightGold05 = color Yellow 39 = color MediumSpringGreen 73 = color OldGold

16

06 = color Cyan 40 = color MediumTurquoise 74 = color Feldspar07 = color Magenta 41 = color MediumVioletRed 75 = color Quartz08 = color Black 42 = color MidnightBlue 76 = color NeonPink09 = color Aquamarine 43 = color Navy 77 = color DarkPurple10 = color BlueViolet 44 = color NavyBlue 78 = color NeonBlue11 = color Brown 45 = color Orange 79 = color CoolCopper12 = color CadetBlue 46 = color OrangeRed 80 = color MandarinOrange13 = color Coral 47 = color Orchid 81 = color LightWood14 = color CornflowerBlue 48 = color PaleGreen 82 = color MediumWood15 = color DarkGreen 49 = color Pink 83 = color DarkWood16 = color DarkOliveGreen 50 = color Plum 84 = color SpicyPink17 = color DarkOrchid 51 = color Salmon 85 = color SemiSweetChoc18 = color DarkSlateBlue 52 = color SeaGreen 86 = color BakersChoc19 = color DarkSlateGray 53 = color Sienna 87 = color Flesh20 = color DarkTurquoise 54 = color SkyBlue 88 = color NewTan21 = color Firebrick 55 = color SlateBlue 89 = color NewMidnightBlue22 = color ForestGree 56 = color SpringGreen 90 = color MandarinOrange23 = color Gold 57 = color SteelBlue 91 = color VeryDarkBrown24 = color Goldenrod 58 = color Tan 92 = color DarkBrown25 = color GreenYellow 59 = color Thistle 93 = color GreenCopper26 = color IndianRed 60 = color Turquoise 94 = color DkGreenCopper27 = color Khaki 61 = color Violet 95 = color DustyRose28 = color LightBlue 62 = color VioletRed 96 = color HuntersGreen29 = color LightSteelBlue 63 = color Wheat 97 = color Scarlet30 = color LimeGreen 64 = color YellowGreen 98 = color DarkTan31 = color Maroon 65 = color SummerSky 99 = color White32 = color MediumAquamarine 66 = color RichBlue33 = 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_objetoAlguns_atributos_simples_do_objetoAlguns_outros_atributos_simplesAlguns_atributos_complexos{

Alguns_atributosAlguns_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 pretabackground { color rgb <0, 0, 0> //fundo preto}

//esfera vermelha no centrosphere { <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âmeracamera { location <2,5,-10> look_at <0,0,0>}

//cor de fundo pretabackground { color rgb <0, 0, 0> //fundo preto}

// agora, um pouco de luzlight_source { <0,10,-10> color rgb <1,1,1>}

// a esfera vermelhasphere { <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 clarocylinder { <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 primitivocone { <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 componentsblob { 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 centrodisc { <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>, 6pigment { 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>, 6pigment { 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âmeracamera { location <1.5, 1.5, -2> look_at <0.5, 0.5, 0.5>}

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

//caixa com a imagembox { <0, 0, 0>, <1, 1, 1> pigment { image_map { gif "../gfx/mmap.gif" } }} //um plano de fundoplane { -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ãoplane { y, -4

46

pigment { checker color Black color White } } //esferasphere { <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ãoplane { y, -4 pigment { checker color Black color White } }//esferasphere { <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âmeracamera { location <0, 4, -1> look_at <0, 0, 0>}

//cor de fundo pretabackground { color rgb <0, 0, 0> //fundo preto}

// luzlight_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 -------pigment {JadeRed_MarbleWhite_MarbleBlood_MarbleBlue_AgateSapphire_AgateBrown_AgatePink_Granitetexture { //--------- PEDRASPinkAlabaster

// ------ VIDROS-------texture {GlassGlass2 //”Plexiglas”Glass3 //”Bleiglas”Green_GlassNBglassNboldglassNbwinebottleNbbeerbottleRuby_GlassDark_Green_GlassVicks_Bottle_GlassYellow_GlassOrange_Glass

// EFEITOS ESPECIAIS pigment {Candy_CaneY_GradientX_Gradienttexture {PeelWaterCorkLightening1Lightening2Starfield

// -------- MADEIRAS --------pigment {CorkCherry_WoodPine_WoodDark_WoodTan_WoodWhite_WoodTom_WoodDMFWood1DMFWood2DMFWood3DMFWood4DMFWood5DMFLightOakDMFDarkOaktexture { // ------ MadeiraDMFWood6EMBWood1Yellow_PineRosewoodSandalwood

// ------ METAIS --------texture {Chrome_MetalBrass_MetalBronze_MetalGold_MetalSilver_MetalCopper_MetalPolished_ChromePolished_BrassNew_BrassSpun_BrassBrushed_AluminumSilver1 Silver2 Silver3Brass_ValleyRustRusty_IronSoft_SilverNew_PennyTinny_BrassGold_NuggetAluminumBright_Bronze

// --- CÉU e NUVENS ---pigment {Blue_SkyBright_Blue_SkyBlue_Sky2Blue_Sky3Blood_SkyApocalypseCloudsFBM_Cloudstexture { // -------CéuShadow_Clouds

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.

// luzlight_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çãoAntialias=OffAntialias_Threshold=0.1Antialias_Depth=2

79

Input_File_Name=esfera.pov

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

Cyclic_Animation=onPause_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