The Book of Shaders by Patricio Gonzalez Vivo & Jen Lowe

日本語 - 中文版 - 한국어 - Español - Portugues - Français - Italiano - Deutsch - Русский - English


Algoritmos de desenho

Modelagem de funções

Este capítulo poderia se chamar "Lição de pintar a cerca com o Sr. Miyagi". Anteriormente, nós mapeamos as posições normalizadas de x e y para os canais red e green. Essencialmente, nós criamos uma função que recebe um vetor bidimensional (x e y) e retornamos um com quatro dimensões (vermelho, verde, azul e alpha). Mas antes de irmos além de transformações dos dados entre as dimensões, precisamos fazer algo mais simples... muito mais simples: entender como criar uma função unidimensional. Quanto mais energia e tempo que você gastar dominando isso, mais forte seu karatê de shader será.

The Karate Kid (1984)

A estrutura do código a seguir será nossa cerca. Nela, nós visualizaremos os valores normalizados da coordenada x (st.x) de dois jeitos: uma com a claridade (observe o belo gradiente de branco para preto) e a outra é traçando uma linha verde por cima (neste caso, o valor de x será atribuído diretamente a y). Não foque tanto na função de traçar, nós a veremos com mais detalhes em alguns minutos.

Nota rápida: O construtor do tipo vec3 "entende" que você quer atribuir o mesmo valor aos três canais de cores, enquanto vec4 entende que você quer construir um vetor quadridimensional usando um vetor tridimensional um somado a um quarto valor (neste caso, o valor que controlará o alpha ou opacidade). Veja as linhas 20 e 26 acima por exemplo.

Este código é a sua cerca: É importante observar e entendê-lo. Você voltará algumas vezes para este espaço entre 0.0 e 1.0. Aprenderá a arte de mesclar e dar forma a esta linha.

Essa relação de um pra um entre x e y (ou de brilho) é conhecida como interpolação linear. A partir daqui, nós usaremos algumas funções matemáticas para dar forma a linha. Por exemplo, nós podemos elevar x à quinta potência para criar uma linha curvada.

Interessante, não é? Na linha 22, tente diferentes expoentes: 20.0. 2.0, 1.0, 0.0, 0.2 e 0.02 por exemplo. Entender essa relação entre o valor e o expoente será de grande ajuda. Usar esses tipos de funções matemáticas aqui e ali nos dará um controle significativo do nosso código, uma espécie de acumpultura de dados que permite que você controle a fluência dos valores.

pow() é uma função nativa no GLSL e existem muitas outras. A maioria delas são aceleradas em nível de hardware, o que significa que se elas forem usadas da forma certa e com juízo, farão seu código mais rápido.

Substitua a função de potência na linha 22. Tente outras como: exp(), log() e sqrt(). Algumas destas funções são mais interessantes quando você experimenta utilizando PI. Você pode ver na linha 8 que eu defini uma macro que retornará qualquer chamada de PI com o valor de 3.14159265359.

Step e smoothstep

GLSL também tem algumas exclusivas funções nativas de interpolação que são aceleradas pelo hardware.

A interpolação step() recebe dois parâmetros. O primeiro é para o limite ou limiar, enquanto o segundo é o valor que nós queremos passar. Qualquer valor acima do limite retornará 0.0 e qualquer um acima do limite retornará 1.0.

Experimente mudar este valor de limiar na linha 20 do código a seguir.

A outra função exclusiva é conhecida como smoothstep(). Dado um intervalo de dois números, está função irá interpolar os valores entre o intervalo definido. Os dois primeiros parâmetros são para o início e o final da transição, enquanto o terceiro é o valor que será interpolado.

No exemplo anterior, na linha 12, veja que estamos usando smoothstep para desenhar a linha verde na função plot(). Pra cada posição dentro do eixo x, esta função faz uma marcação num valor específico de y. Como? Conectando duas smoothstep() juntas. Dê uma olhada na seguinte função, troque a linha 20 acima por esta, e imagine-a como um corte vertical. O fundo se parece com uma linha, certo?

float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);

Seno e Cosseno

Quando queremos usar um pouco de matemática para animar, dar forma e mesclar valores, não há nada melhor que ser amigo do seno e cosseno.

Essas duas funções trigonométricas básicas trabalham juntas para construir circunferências que são tão úteis como o canivete suíço de MacGyver. É importante entender como elas se comportam e de quais formas elas podem ser combinadas. Em poucas palavras, dado um ângulo (em radianos), elas retornarão a posição correta de x (cosseno) e y (seno) de um ponto na linha de uma circunferência de raio igual a 1. O fato de elas retornarem valores normalizados (que vão de 1 a -1) de maneira suave faz delas, ferramentas incríveis.

Enquanto é difícil descrever todas as relações entre as funções trigonométricas e circunferências, a animação acima faz um ótimo trabalho em exemplificar visualmente esta relação.

Preste muita atenção nesta onda de seno. Note como o valor de y flui suavemente entre +1 e -1. Como vimos nos exemplos de tempo no capítulo anterior, podemos usar esse movimento rítmico do sin() para animar propriedades. Se você estiver lendo este exemplo em um navegador, você verá que você pode alterar o código da fórmula acima para observar como as ondas mudam. (Nota: não se esqueça do ponto e vírgula no final das linhas).

Experimente com os seguintes exercícios e veja o que acontece:

Outras funções úteis

No final do último exercício nós apresentamos algumas novas funções. Agora é hora de experimentar cada uma descomentando as linhas abaixo, uma de cada vez. É importante entender o funcionamento e comportamento destas funções. Eu sei, você deve estar se perguntando... Por quê? Uma rápida pesquisa no google de "arte generativa" (ou generative art) te mostrará. Lembre-se que estas funções são a nossa cerca. Nós estamos dominando o movimento em uma dimensão, para cima e para baixo. Logo, usaremos duas, três quatro dimensões!

Anthony Mattox (2009)

Modelando funções avançadas

Golan Levin tem uma ótima documentação de modelagem de funções complexas que são de extraordinária ajuda. Portá-las para GLSL é uma excelente forma para começar seu próprio banco de trechos de códigos.

Como chefs que coletam temperos e ingredientes exóticos, artistas digitais e programadores criativos tem um amor único por trabalhar nas suas próprias funções.

Iñigo Quiles tem uma grande coleção de funções úteis. Depois de ler este artigo, dê uma olhada na seguinte na seguinte tradução destas funções para GLSL. Preste atenção nas pequenas mudanças necessárias, como colocar o "." (ponto) nos números de ponto flutuantes ou usar o nome em GLSL para as Funções em C; por exemplo, em vez de powf(), usamos pow():

Para mantermos sua motivação lá em cima, aqui temos um exemplo elegante (feito por Danguafer) em masterizar o karatê das funções.

No Próximo >> capítulo, nós começaremos a usar nossos novos movimentos. Primeiro misturando cores e em seguida, desenhando formas.

Exercício

Dê uma olhada na seguinte tabela de equações feita por Kynd. Veja como ele está combinando as funções e suas propriedades para controlar os valores entre 0.0 e 1.0. Agora é a hora de você praticar replicando estas funções. Lembre-se que quanto mais você praticar, melhor será o seu karatê de shaders.

Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)

Para sua caixa de ferramentas

Aqui temos algumas ferramentas que facilitarão a visualização destes tipos de funções.

OS X Grapher (2004)

Iñigo Quilez - GraphToy (2010)

Toby Schachman - Shadershop (2014)