16. Iluminação e Sombreamento

Vimos nas aulas passadas como criar e manipular formas de objetos bi e tridimensionais associando uma cor sólida para cada vértice.

Agora vamos estudar iluminação, mais um elemento muito importante para dar maior realismo às imagens geradas por computador e o efeito de sombreamento causado pela luz ao interagir com as superfícies dos objetos.

Esse tópico também marca uma mudança de foco no tratamento do problema de renderização. Até aqui tratamos basicamente de questões matemáticas e computacionais para representar e manipular formas em duas e três dimensões usando elementos geométricos primitivos como pontos, linhas e polígonos. A cor foi simplificada para um array RGB ou RGBA. Agora vamos entender um pouco melhor como a luz interage com os objetos afetando a cor que percebemos. Para isso, vamos introduzir alguns elementos da física sobre luz e cor.

16.1. Modelos de iluminação global e local

O que “vemos” é uma função da luz que entra em nossos olhos. As fontes de luz geram energia, que podemos pensar como sendo compostas de pacotes extremamente pequenos de energia, chamados fótons. Os fótons são refletidos e transmitidos de várias maneiras por todo o ambiente. Eles se chocam e podem ser refletidos por várias superfícies, podendo ser espalhados por outros elementos da cena como fumaça ou poeira no ar. Eventualmente, alguns fótons entram em nosso olho e estimulam nossa retina. Percebemos a combinação resultante desses fótons, cada um com um nível diferente de energia, como uma cor. Quanto mais precisamente pudermos simular esse processo físico, mais realista será a iluminação no desenho produzido pelo computador. Infelizmente, os computadores ainda não são rápidos o suficiente para produzir uma simulação verdadeiramente realista de reflexões indiretas em tempo real e, portanto, teremos que nos contentar com aproximações muito mais simples (embora isso possa mudar rapidamente, com a introdução de placas gráficas capazes de renderizar imagens por ray tracing em tempo real).

Assim como fizemos com elementos da geometria, em nossos programas gráficos (usando WebGL) vamos utilizar um modelo de iluminação e sombreamento muito simples e, portanto, vamos criar desenhos com um realismo limitado. Parte dessa limitação é devida a eficiência dos algoritmos para gerar animações em tempo real em aplicações interativas. Assim, a primeira simplificação que vamos adotar em nossos programas é um modelo de iluminação local, que assume que o sombreamento de um ponto depende apenas de sua relação com as fontes de luz, sem considerar os demais objetos da cena.

Isso contrasta com um modelo de iluminação global que assume que a luz refletida ou passando por um objeto pode afetar a iluminação de outros objetos. Os modelos de iluminação global lidam com muitos efeitos, como sombras, iluminação indireta, esparramento de cores (color bleeding, onde as cores refletindo de um objeto alteram a cor de objetos próximos), cáusticos (caustics, que resultam quando a luz passa por uma lente e é focada em outra superfície) etc..

Por exemplo, o modelo de iluminação que vamos estudar não modela sombras, não trata a reflexão indireta de outros objetos (onde a luz reflete em um objeto e ilumina outro) e não trata objetos que refletem ou refratam a luz (como esferas de metal e bolas de vidro). No entanto, esse modelo foi projetado para ser muito eficiente.

16.2. Luz: reflexão, absorção e transmissão

Você pode procurar discussões mais detalhada sobre luz e suas propriedades em textos de física. Para nossos propósitos, vamos adotar um modelo simples de luz consistindo em um grande número de fótons sendo emitidos continuamente de cada fonte de luz. Cada fóton tem uma energia associada que, quando agregada em milhões de diferentes fótons refletidos e que chegam aos nossos olhos, percebemos como cor. Embora a cor seja um fenômeno complexo, para nossos propósitos é suficiente considerar a cor modelada como uma tripla de componentes: R (red ou vermelho), G (green ou verde) e B (blue ou azul).

A intensidade da luz em qualquer local pode ser modelada em termos de fluxo, ou seja, a quantidade de energia luminosa que passa por uma área fixa durante um período fixo de tempo. Assumindo que a luz na cena se propaga em um vácuo (em particular, não há fumaça ou neblina), um fóton viaja sem impedimentos até atingir uma superfície, após o que um dos seguintes três fenômenos pode acontecer: reflexão, absorção ou transmissão. A Figura Fig. 16.1 ilustra esses comportamentos.

Interação de um fóton com uma superfície

Fig. 16.1 Formas de interação da luz com uma superfície.

16.2.1. Reflexão

O fóton pode ser refletido ou espalhado de volta para a cena. Se a superfície do objeto for perfeitamente lisa (como um espelho ou metal polido) o reflexo deve satisfazer à regra que o ângulo de incidência é igual ao ângulo de reflexão em relação à normal da superfície no ponto de reflexão. Nesse caso, o resultado seria uma aparência espelhada e muito brilhante. Por outro lado, se a superfície for áspera (a nível microscópico, como uma borracha por exemplo), os fótons serão espalhados quase uniformemente em todas as direções. Podemos ainda distinguir diferentes variedades de reflexão:

  • Reflexão perfeita: reflete a luz perfeitamente, como espelhos;
  • Reflexão especular: reflete a luz mas não perfeitamente, como metais escovados e plásticos brilhantes;
  • Reflexão difusa: espalha a luz uniformemente e, portanto, não brilhante.

16.2.2. Absorção

O fóton pode ser absorvido pela superfície. Nesse caso ele tipicamente se dissipa na forma de energia térmica, por exemplo. Não vemos esta luz. Assim, um objeto parece ser verde, pois reflete fótons na parte verde do espectro e absorve fótons nas outras regiões do espectro visível.

16.2.3. Transmissão

O fóton pode atravessar a superfície. Isso acontece perfeitamente com objetos transparentes, como vidro e pedras preciosas polidas. Objetos translúcidos como a pele humana ou um pedaço fino de papel de seda, permitem que apenas parte dos fótons atravesse a superfície, ainda assim sofrendo espalhamento e absorção.

É claro que superfícies reais possuem várias combinações desses elementos, e esses elementos podem interagir de maneiras complexas. Por exemplo, a pele humana e muitos plásticos são caracterizados por um fenômeno complexo chamado espalhamento de subsuperfície (subsurface scattering), no qual a luz é transmitida, refletida e absorvida sob a superfície, propagando pelas camadas subcutâneas.

Assim, esses três fenômenos descrevem como a luz incidente reage com uma superfície. Mas, além disso, uma superfície pode ser uma fonte de luz, com veremos a seguir.

16.3. Fontes de luz

Antes de discutirmos como um fóton se comporta ao bater em uma superfície, vamos discutir a origem dos raios de luz.

A luz é um tipo de energia que se propaga por um meio, em uma certa direção, e que pode ser caracterizada pela sua intensidade e comprimento de onda. A intensidade da energia luminosa é distribuída em um espectro contínuo de comprimentos de onda. As fontes de luz podem apresentar muitos tamanhos e formas, podendo emitir luz com intensidades e comprimentos de onda diferentes, em diferentes direções. Assim, um holofote pode emitir luz dentro de uma região definida por um cone, que é mais intensa no centro do cone que nas bordas e no espectro vermelho apenas.

Para simplificar as coisas, vamos assumir que uma fonte de luz é um ponto e que a energia emitida pode ser modelada como uma tripla RGB, que vamos chamar de função de luminância. Isso é descrito por um vetor com três componentes \(L = (Lr,Lg,Lb)\), que indicam as intensidades da luz vermelha, verde e azul, respectivamente. Não vamos nos preocupar com as unidades de medida, até devido a simplicidade do modelo. Mas observe que, embora seu monitor ou tela de exibição tenha um valor limite de energia por pixel que é capaz de exibir, em teoria não há limite superior da intensidade luminosa. Por exemplo, há diferença de energia quando olhamos diretamente para o sol (não faça isso!) e quando vemos uma imagem do sol na tela do seu computador? Na prática, o número de níveis de energia é limitado também pelo número de bits usados para representar cada componente. Vimos que, para um monitor raster, é apropriado representar cada componente de cor usando 8 bits, ou seja, cada componente pode assumir 256 níveis de intensidade, mas podemos também representar cada componente no intervalo contínuo [0.0, 1.0], onde 1.0 indica o nível máximo de energia e 0.0 o mínimo.

A iluminação em ambientes reais geralmente envolve uma quantidade considerável de reflexão indireta entre os objetos da cena. Se ignorarmos esse efeito e considerarmos que um ponto só é iluminado se receber luz diretamente de uma fonte de luz, a imagem resultante pode conter objetos nas sombras que são desenhados usando a cor RBG=(0, 0, 0), ou seja, com regiões totalmente pretas. Em cenas com iluminação natural estamos acostumados a ver sombreamentos muito mais suaves, de modo que até os objetos que estão ocultos da fonte de luz são parcialmente iluminados. Em nossos programas usando WebGL (e na maioria dos modelos de iluminação local) esse espalhamento da luz é modelado quebrando a intensidade da fonte de luz em duas componentes: emissão ambiente e emissão pontual.

  • Emissão ambiente: Refere-se à luz que não vem de nenhum local específico. Assim como o calor, supõe-se que seja espalhado uniformemente em todos os locais e direções. Um ponto é iluminado pela emissão ambiente mesmo que não seja visível da fonte de luz.
  • Emissão pontual: Refere-se à luz que se origina de um único ponto. Em teoria, a emissão pontual afeta apenas os pontos que são diretamente visíveis pela fonte de luz. Ou seja, um ponto \(P\) é iluminado pela fonte de luz em \(Q\) se e somente se o segmento de reta \(PQ\) não intercepta nenhum dos objetos da cena.

Infelizmente, determinar se um ponto é visível para uma fonte de luz em uma cena complexa com milhares de objetos pode ser computacionalmente bastante caro. Portanto, nossos programas irão simplesmente testar se a superfície está voltada de frente para a luz. As superfícies usadas no WebGL são triângulos, mas vamos considerar isso em uma configuração mais geral.

Suponha um ponto \(P\) contido em alguma superfície. Seja \(\vec{n}\) o vetor normal em \(P\), direcionado para fora do interior do objeto, e seja \(\vec{l}\) o vetor direcional de \(P\) para a fonte de luz (\(\vec{l}=Q-P\)), então \(P\) será iluminado se e somente se o ângulo entre estes vetores é agudo. Podemos determinar isso testando se o resultado do produto escalar é positivo, ou seja, \(\vec{n} \cdot \vec{l} > 0\).

Por exemplo, na Figura Fig. 16.2, o ponto \(P\) está iluminado. O ponto \(P'\) também é iluminado, apesar de estar na sombra de um triângulo, pois outros objetos na cena são ignorados pelo modelo de iluminação local. O ponto \(P''\) não é iluminado porque sua normal está direcionada para longe da luz.

Visibilidade de uma fonte de luz pontual determinada por um modelo de iluminação local.

Fig. 16.2 Visibilidade de uma fonte de luz pontual determinada por um modelo de iluminação local. Note que o ponto P’ é iluminado mesmo que obstruído por um triângulo.

16.4. Atenuação

A luz emitida por uma fonte pontual está sujeita a atenuação, ou seja, a diminuição da intensidade luminosa à medida que a distância da fonte aumenta. A física nos diz que a intensidade da luz de uma fonte (\(I(Q)\)) (em \(Q\)) diminui com o inverso do quadrado da distância. Isso implica que a intensidade em algum ponto (visível, sem oclusão) \(P\) seria

\(I(P,Q) = I(Q) / |P-Q|^2\)

onde \(|P-Q|\) denota a distância euclidiana de \(P\) a \(Q\). No entanto, em nossos programas com WebGL, as várias simplificações já feitas, como a desconsideração de reflexões indiretas, resulta em um enfraquecimento da iluminação pelas fontes de luz, que ficariam ainda mais fracas se considerarmos atenuação. Assim vamos simplificar também a função de atenuação usando 3 constantes \((a, b, c)\), que correspondem aos coeficientes de um polinômio de segundo grau em função da distância \(d=|P-Q|\): \((a + b d + c d^2)\), tal que:

\(I(P,Q) = I(Q) / (a + b d + c d^2)\)

Tipicamente vamos usar \((a=1, b=0, c=0)\), ou seja, não vamos considerar atenuação em nossos programas com WebGL.

16.5. Fontes direcionais e spotlights

Uma fonte de luz pode ser colocada infinitamente longe usando a convenção de geometria projetiva de definir a coordenada homogênea \(w=0\).

Por exemplo, assumindo que o eixo \(z\) aponta para cima, ao meio-dia, as coordenadas do sol seriam modeladas pelo vetor homogêneo:

\((0,0,1,0)^T\).

Essas fontes com \(w=0\) são chamadas de fontes direcionais. Seu uso pode ser vantajoso pois essas fontes simplificam os cálculos envolvendo os ângulos entre a normal à superfície e as direções dos pontos de uma superfície para a fonte de luz. Se a fonte de luz estiver no infinito, então todos os pontos pertencentes a uma região poligonal têm o mesmo ângulo com relação à fonte e, portanto, esse ângulo precisa ser calculado apenas uma vez para todos os pontos do polígono.

Às vezes é necessário utilizar uma componente direcional para as fontes de luz. Um efeito interessante de iluminação é chamado de spotlight (holofote), onde a intensidade é mais forte ao longo de uma determinada direção e diminui de acordo com o ângulo dessa direção.

16.6. Tipos de reflexão da luz

Até aqui discutimos como podemos modelar (e simplificar) a luz que ilumina as superfícies de cada objeto da cena. Agora vamos discutir como a luz se comporta ao bater na superfície e ser refletida na direção do observador. Para isso é necessário entender certas propriedades para modelar a interação da luz com as superfícies dos objetos.

O modelo que vamos descrever é conhecido como modelo de reflexão de Phong, introduzido em 1973 na tese de doutorado de Bui Tuong Phong. O modelo assume que todos os objetos são opacos e que a reflexão da luz é uma combinação das seguintes componentes, como ilustrado na Figura Fig. 16.3.

  • Reflexão ambiente: essa componente modela reflexões indiretas. Todas as superfícies em todas as posições e orientações são igualmente iluminadas por esta componente.
  • Reflexão difusa: componente que modela a iluminação produzida por objetos lisos foscos (ou seja, sem brilho) como borracha.
  • Reflexão especular: modela pontos brilhantes que aparecem em superfícies lisas e brilhantes (por exemplo, metálicas ou polidas). Embora a reflexão especular esteja relacionada à reflexão pura (como nos espelhos), para os propósitos do modelo de Phong, essas duas coisas são diferentes. Em particular, a reflexão especular reflete apenas a luz das fontes, e não reflete os objetos da cena.
Componentes do modelo de reflexão de Phong.

Fig. 16.3 Componentes do modelo de reflexão de Phong. Fonte: Wikipedia.

  • Emissão: essa componente é usada para modelar objetos que possuem brilho próprio (mesmo quando todas as luzes estão apagadas) e não está representada na figura. Essa componente não é afetada pelas fontes de luz. No entanto, como o modelo de iluminação é local, ela não se comporta como uma fonte de luz, no sentido de que não faz com que outros objetos sejam iluminados.

Seja \(L = (Lr,Lg,Lb)\) a intensidade de iluminação da fonte de luz. Para aplicar o modelo de Phong, vamos decompor a luz em três componentes: \(La\) (ambiente), \(Ld\) (difusa) e \(Ls\) (especular). Cada uma dessas componentes possuem três componentes de cor (RGB), então, por exemplo, \(Ld = (Ldr,Ldg,Ldb)\), denota o vetor RGB (ou ainda os componentes RGBA) da componente difusa da luz.

Como vimos, modelar a componente ambiente separadamente é meramente uma conveniência computacional para modelar a reflexão indireta. Para as demais componentes, não parece natural ligar ou desligar a capacidade de uma fonte de luz de gerar reflexão difusa e especular. O modelo apenas captura propriedades da superfície de um objeto, não as propriedades da luz, que determinam se a luz é refletida de forma difusa ou especular. Mas, novamente, isso é apenas um modelo computacional. As intensidades difusa e especular de uma fonte de luz são geralmente iguais entre si.

A cor de um objeto determina quanto de uma determinada intensidade é refletida. Podemos denotar a cor de um objeto por uma tripla \(C = (Cr , Cg , Cb )\). Vamos assumir que esses valores são normalizados para o intervalo [0, 1]. Assim, podemos pensar em \(Cr\) como a fração de luz vermelha que é refletida por um objeto. Assim, se \(Cr = 0\), então nenhuma luz vermelha é refletida. Quando a luz de intensidade \(L\) atinge um objeto de cor \(C\), a quantidade de luz refletida é dada pelo produto componente dos vetores \(L\) e \(C\). Vamos definir \(L \otimes C\) como este produto, ou seja,

\(L \otimes C =(LrCr, LgCg, LbCb)\).

Por exemplo, para um objeto avermelhado com cor \(C\) = (0.25, 0, 0), quando iluminado por uma luz branca \(L\) = (2, 2, 2) então a reflexão é \(L \otimes C\) = (0.5, 0, 0) que corresponde a um tom de vermelho escuro. No entanto, se a luz for azul \(L\) = (0, 0, 1), então \(L \otimes C\) = (0, 0, 0) e, portanto, o objeto aparece como preto.

Para usar o modelo em seus programas, ao invés de especificar uma única cor por objeto, você deve especificar a quantidade de reflexão para cada tipo de iluminação: \(Ca\), \(Cd\) e \(Cs\). Cada uma dessas cores é um vetor RGB (ou RGBA). Isso pode parecer um pouco genérico demais pois, por exemplo, permite especificar que um objeto pode refletir apenas luz ambiente vermelha e apenas luz difusa azul. Novamente, não parece haver uma explicação física para isso. No entanto, observe que é comum que a cor especular (já que ela é causada pela fonte de luz) geralmente é feita da mesma cor da fonte de luz, não do objeto.

16.7. Onde estamos e para onde vamos?

Nessa aula, descrevemos alguns conceitos sobre luz e sombreamento para estabelecer as bases do Modelo de Reflexão de Phong. Apesar de simples, pois também segue um modelo de iluminação local, esse modelo permite a renderização eficiente de imagens tridimensionais com maior realismo.

Na próxima aula, veremos como o modelo Phong é usado para calcular as cores de cada pixel.

16.8. Para saber mais