Merge branch 'master' of https://github.com/patriciogonzalezvivo/thebookofshaders
# Conflicts: # 00/README-pt.md # 01/README-pt.md # 02/README-pt.md # 03/README-pt.md # 05/README-pt.md # 06/README-pt.md # README-pt.mdpull/272/head
commit
e90e260ab2
@ -1,50 +1,48 @@
|
||||
# Começando
|
||||
## O que é um shader?
|
||||
## O que é um fragment shader?
|
||||
|
||||
No capítlo anterior, nós descrevemos shaders como o equivalente da imprensa de Gutenberg para os gráficos. Por quê? E mais importante: o que é um shader?
|
||||
No capítulo anterior descrevemos shaders como o equivalente dos avanços trazidos pela prensa de Gutenberg. Por que? E mais importante: o que é um shader?
|
||||
|
||||
![From Letter-by-Letter, Right: William Blades (1891). To Page-by-page, Left: Rolt-Wheeler (1920).](print.png)
|
||||
![De letra-por-letra, Right: William Blades (1891). À página-por-página, Left: Rolt-Wheeler (1920).](print.png)
|
||||
|
||||
Se você já tem experiência em desenhar com computadores, já sabe que nesse processo você desenha um círculo, depois um retângulo, uma linha, alguns triângulos, até compor a imagem que você quer. Esse processo é muito similar a escrever uma carta ou livro à mão - é um conjunto de instruções em que se faz uma tarefa depois da outra.
|
||||
Se você já tem experiência em desenhar em computadores, você sabe que nesse processo você desenha um círculo, depois um retângulo, uma linha, alguns triângulos até você finalmente compor a imagem desejada. O processo é muito similar a escrever uma carta ou livro à mão, um conjunto de instruções que executam uma tarefa atrás de outra.
|
||||
|
||||
Shaders também são um conjunto de instruções, mas as instruções são executadas todas de uma vez só para cada pixel na tela. Isso quer dizer que o código que você escreve tem que se comportar de modo diferente dependendo da posição do pixel na tela. Como um tipo na imprensa, seu programa vai funcionar como uma função que recebe uma posição e retorna uma cor, e quando é compilado, vai rodar extraordinariamente rápido.
|
||||
Shaders são também um conjunto de instruções, mas as instruções são executadas todas ao mesmo tempo para cada pixel da tela. Isso significa que o código que você escreve têm que se comportar de maneira diferente, dependendo da posição do pixel na tela. Como uma prensa tipográfica, seu programa funcionará como uma função que recebe uma posição e retorna a respectiva cor, e, quando esse programa é compilado, ele será executado extraordinariamente rápido.
|
||||
|
||||
![Chinese movable type](typepress.jpg)
|
||||
![Prensa tipográfica móvel chinesa](typepress.jpg)
|
||||
|
||||
## Por que os shaders são rápidos?
|
||||
## Por que shaders são rápidos?
|
||||
|
||||
Para responder isso, eu lhe apresento as maravilhas do *processamento paralelo*.
|
||||
Para responder essa pergunta, eu apresento as maravilhas do *processamento paralelo*.
|
||||
|
||||
Imagine a CPU do seu computador como uma grande esteira ou tubo industrial, e cada tarefa como algo que passa por ela - como uma linha de produção. Algumas tarefas são maiores que outras, o que significa que requerem mais tempo e energia para se lidar com elas. Dizemos assim que elas requerem mais poder de processamento. Por causa da arquitetura dos computadores, os trabalhos são forçados a serem executados em série; cada tarefa tem que ser terminada uma de cada vez. Computadores modernos geralmente têm grupos de quatro processadores que trabalham como essas linhas de produção, completando tarefas uma após a outra para manter as coisas rodando suavemente. Cada esteira é conhecida como *thread*.
|
||||
Imagine a CPU do seu computador como um grande tubo (ou ducto) industrial, e cada tarefa como algo que passa por ele - como uma linha de produção. Algumas tarefas são maiores que outras, o que signica que elas requerem mais tempo e energia que as outras. Digamos que elas requerem mais poder de processamento. Por causa da arquitetura dos computadores, as tarefas são forçadas a serem executadas em série; cada tarefa é finalizada uma de cada vez. Computadores modernos geralmente tem grupos de quatro processadores para trabalhar com tais tubos, completando as tarefas sequencialmente e mantendo a linha de produção em movimento. Cada tubo é também conhecido como *thread*.
|
||||
|
||||
![CPU](00.jpeg)
|
||||
|
||||
Videogames e outras aplicações gráficas requerem muito mais poder de processamento que outros programas. Por causa de seu conteúdo gráfico, eles têm que fazer um número gigantesco de operações pixel-a-pixel. Cada pixel na tela precisa ser calculado, e em jogos 3D as geometrias e perspectivas precisam ser calculadas também.
|
||||
Video games e outras aplicações gráficas requerem muito mais poder de processamento que outros programas. Por causa de seu conteúdo gráfico, eles precisam fazer um número enorme de operações pixel-por-pixel. Cada pixel da tela precisa ser computado, e em jogos em 3D geometrias e perspectivas também precisam ser calculadas.
|
||||
|
||||
Vamos voltar à nossa metáfora de tubos e tarefas. Cada pixel na tela representa uma pequena tarefa simples. Individualmente, cada tarefa de pixel não é uma grande questão para a CPU, mas (e esse é o problema) as pequenas tarefas têm que ser feitas em cada pixel na tela. Isso significa, em uma tela antiga em 800x600, que 480.000 pixels têm que ser processados por frame, o que significa 14.400.000 cálculos por segundo! Sim! Isso é um problema grande o suficiente para sobrecarregar um microprocessador. Em uma tela moderna retina 2880x1800, rodando a 60 frames por segundom esse cálculo daria até mais 311.040.000 cálculos por segundo. Como os engenheiros gráficos resolveram esse problema?
|
||||
Vamos voltar para a nossa metáfora de tubos e tarefas. Cada pixel da tela representa uma tarefa pequena e simples. Individualmente, cada tarefa deste tipo não é um problema para o CPU, mas (e aqui mora o perigo) a pequena tarefa precisa ser repetida para cada pixel na tela! Isso significa que em uma tela antiga de 800x600, 480.000 pixels precisam ser processados pada cada frame, o que totaliza em 14.400.000 cálculos por segundo! Sim! Isso é um problema grande o suficiente para sobrecarregar um microprocessador. Em uma tela moderna com retina display medindo 2880x1800, executando a 60 frames por segundo, esse cálculo resulta em até 311.040.000 cálculos por segundo. Como engenheiros gráficos resolvem esse problema?
|
||||
|
||||
![](03.jpeg)
|
||||
|
||||
É aí que o processamento paralelo se torna uma boa solução. Ao invés de ter uma dupla de microprocessadores grandes e poderosos, ou *tubos*, é mais inteligente ter um monte de pequenos microprocessadores rodando em paralelo ao mesmo tempo. É isso que é uma GPU - Unidade de Processamento Gráfico.
|
||||
Neste caso, processamento em paralelo se torna uma boa solução. Em vez de ter alguns microprocessadores grandes e poderosos, ou *tubos*, é mais inteligente ter um monte de minúsculos microprocessadores rodando em paralelo ao mesmo tempo. Isso é o que a Unidade de Processamento Gráfico (Graphic Processor Unit ou GPU) é.
|
||||
|
||||
![GPU](04.jpeg)
|
||||
|
||||
Imagine os minúsculos processadores como uma mesa de tubos, e os dados de cada pixel como sendo uma bola de ping-pong. 14.400.000 bolas de ping-pong por segundo podem obstruir quase qualquer tubo. Mas uma mesa de 800x600 pequenos tubos recebendo 30 ondas de 480.000 pixels por segundo pode ser manuseado suavemente. Isso funciona do mesmo jeito para resoluções mais altas - quanto mais hardware paralelo você tem, maior o stream que ele pode gerenciar.
|
||||
Imagine os minúsculos microprocessadores como uma mesa de tubos, e os dados de cada pixel como uma bola de ping-pong. 14.400.000 bolas de ping-pong por segundo podem obstruir quase qualquer tubo. Mas a mesa com 800x600 pequenos tubos recebendo 30 ondas de 480.000 pixels por segundo pode manejar esse fluxo tranquilamente. Funciona do mesmo jeito em resoluções maiores - quanto mais hardware em paralelo você tem, maior o fluxo que eles podem manejar.
|
||||
|
||||
Um outro "super poder" da GPU são funções especiais matemáticas aceleradas via hardware, de modo que operações matemáticas complicadas são resolvidas diretamente pelos microchips ao invés de serem por software. Isso significa operações trigonométricas e de matrix extra rápidas - tanto quanto a eletricidade pode ir.
|
||||
Outro "super poder" da GPU são funções matemáticas especiais aceleradas via hardware, logo operações matemáticas mais complicadas são resolvidas diretamente pelos microchips em vez do software. Isso resulta em operações trigonométricas e matriciais extra rápidas - tão rápidas quanto a eletricidade.
|
||||
|
||||
## O que é GLSL?
|
||||
|
||||
GLSL é a sigla de openGL Shading Language, o que é o padrão específico de shader que você verá nos próximos capítulos. Existem outros tipos de shaders, dependendo do hardware ou sistemas operacionais. Aqui trabalharemos com as specificações do openGL, reguladas por [Khronos Group](https://www.khronos.org/opengl/). Entender a história do OpenGL pode ser útil se compreender a maior parte das estranhas convenções, para isso eu te recomendo a dar uma olhada em: [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html)
|
||||
|
||||
GLSL significa "openGL Shading Language", que é o padrão específico dos programas shader que você vai ver nos próximos capítulos. Existem outros tipos de shaders, dependendo do hardware and Sistema Operacional. Aqui vamos trabalhar com as especificações openGL reguladas pelo [Khronos Group](https://www.khronos.org/opengl/). Entender a história do OpenGL pode ser de muita ajuda para entender a maioria das convenções estranhas que ele tem, e para isso eu recomendo dar uma olhada em: [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html)
|
||||
## Por que shaders têm uma má reputação?
|
||||
|
||||
## Por que os shaders são tão dolorosos?
|
||||
Como disse o Tio Ben “com grandes poderes vêm grandes responsabilidades” e computação em paralelo segue essa regra; o poderoso design aquitetônico da GPU vem com suas próprias limitações e restrições.
|
||||
|
||||
Como o Tio Ben disse, “com grandes poderes vêm grandes responsabilidades,” e computação paralela segue essa regra; o design arquitetural poderoso da GPU vem com suas restrições e dificuldades.
|
||||
Para cada tubo - ou thread - ser executado em paralelo, eles têm que ser independentes de outras threads. Podemos dizer que threads são *cegas* com relação ao que as outras threads estão fazendo. Essa restrição faz com que todos os dados devem fluir na mesma direção. Deste modo é impossível checar o resultado de outra thread, modificar o input de dados ou passar o resultado de uma thread para outra. Permitir comunicação entre as threads coloca a integridade dos dados em risco.
|
||||
|
||||
Para rodar em paralelo, cada tubo, ou thread, precisa ser independente dos demais. Digamos que as threads são *cegas* para o que o resto das threads está fazendo. Esta restrição implica em que todo o dado deve fluir na mesma direção. Então, é impossível checar o resultado de outra thread, modificar os dados de entrada, ou passar a saída de uma thread para outra. Permitir comunicação entre threads coloca a integridade dos dados em risco.
|
||||
Além disso, a GPU mantém os microprocessadores (os tubos) constantemente ocupados; assim que eles ficam livres eles recebem novas informações para serem processadas. É impossível para uma thread saber o que ela estava fazendo num momento anterior. Isso poderia ser desenhar um botão para a UI do sistema operacional, depois renderizar uma porção do céu em um jogo, seguido de mostrar o texto de um email. Cada thread não é só **cega** como **sem memória**. Apesar da abstração requerida para programar uma função genérica que muda o resultado pixel por pixel dependendo da posição do mesmo, as limitações desta cegueira e falta de memória faz com que os shaders não sejam muito populares entre programadores iniciantes.
|
||||
|
||||
|
||||
Além disso, a GPU mantém o microprocessador (os tubos) constantemente ocupado; assim que ficam livres, já recebem nova informação para processar. É impossível para uma thread saber o que ela estava fazendo no momento anterior. Ela poderia estar desenhando um botão da UI do Sistema Operacional, então renderizar uma parte do céu num jogo, e depois mostrar o texto de um email. Cada thread não é apenas **cega** mas também **sem memória**. Além da abstração requerida para codificar uma função geral que muda o resultado pixel a pixel dependendo de sua posição, as restrições de cegueira e falta de memória tornam os shaders pouco populares entre os programadores principiantes.
|
||||
|
||||
Não se preocupe! Nos capítulos seguintes, vamos aprender passo a passo como sair de um nível simples ao avançado nas computações de shaders. Se você está lendo isso com um browser moderno, vai poder brincar com exemplos interativos. Então, não vamos mais demorar com a diversão, e aperte *Próximo >>* para pular para o código!
|
||||
Não se preocupe! Nos capítulos seguintes aprenderemos passo-a-passo a trabalhar com shaders com exemplos que vão de simples a avançados. Se você está lendo este livro em um navegador moderno, você pode poderá brincar com os exemplos interativos. Então clique em *Next >>* e mãos à obra!
|
||||
|
@ -1,61 +1,61 @@
|
||||
## Uniformes
|
||||
## Uniforms
|
||||
|
||||
Até agora, nós vimos como a GPU gerencia um grande número de threads, cada uma responsável por associar a cor a uma fração da imagem. Embora cada thread paralela seja cega às outras, precisamos conseguir enviar entradas da CPU para todas as threads. Por causa da arquitetura das placas gráficas, essas entradas vão ser iguais (*uniform*) para todas as threads e necessariamente setadas como *read only*. Em outras palavrasm cada thread recebe os mesmos dados que pode ler, mas não pode mudar.
|
||||
Até agora, vimos como a GPU lida um grande número de threads em paralelo, cada uma sendo responsável por atribuir a cor a uma porção da imagem.Apesar de cada thread paralela não saber da existência das outras, precisamos ser capazes de enviá-las algumas entradas (inputs) da CPU. Devido à arquitetura das placas de vídeo, essas entradas serão iguais (*uniform*) para todas as threads e necessariamente determinadas como *somente leitura*. Em outras palavras, cada thread recebe os mesmos dados, os quais se podem ler mas não podem se alterar.
|
||||
|
||||
Essas entradas são chamadas de `uniform` em vêm na maioria dos tipos suportados: `float`, `vec2`, `vec3`, `vec4`, `mat2`, `mat3`, `mat4`, `sampler2D` e `samplerCube`. Uniformes são definidos com o tipo correspondente no topo do shader, logo depois de associar a precisão default.
|
||||
Essas entradas são chamamadas de `uniform` e podem ser de tipos diferentes, como: `float`, `vec2`, `vec3`, `vec4`, `mat2`, `mat3`, `mat4`, `sampler2D` e `samplerCube`. Uniformes são definidas com o tipo correspondente no começo do código, logo após atribuir a precisão padrão de pontos flutuantes,
|
||||
|
||||
```glsl
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution; // Tamanho do Canvas (width,height)
|
||||
uniform vec2 u_mouse; // posição do mouse em pixels da tela
|
||||
uniform float u_time; // Tempo em segundos desde carregado
|
||||
uniform vec2 u_resolution; // Canvas size (width,height)
|
||||
uniform vec2 u_mouse; // mouse position in screen pixels
|
||||
uniform float u_time; // Time in seconds since load
|
||||
```
|
||||
|
||||
Você pode imaginar nos uniforms como sendo pequenas pontes entre a CPU e a GPU. Os nomes vão variar de uma implementação para outra, mas nessa série de exemplos eu sempre vou passar `u_time` (tempo em seguntos desde que shader começou), `u_resolution` (tamanho do 'letreiro' onde o shader está sendo desenhado) e `u_mouse` (posição do mouse dentro do letreiro, em pixels). Vou seguir convenção de colocar `u_` antes do nome do uniform para ser explícito sobre a natureza dessa variável, mas você vai encontrar todos os tipos de nomes para os uniformes. Por exemplo [ShaderToy.com](https://www.shadertoy.com/) usa os mesmos uniformes, mas com os seguintes nomes:
|
||||
Imagine os uniforms como pequenas pontes entre a CPU e a GPU. Os nomes variam dependendo da implementação, mas nessa série de exemplos estarei sempre usando: `u_time` (tempo em segundos desde que o shader foi iniciado), `u_resolution` (tamanho da tela onde o shader está sendo desenhado) and `u_mouse` (posição em pixels do mouse dentro da tela). Estarei seguindo a convenção ao colocar `u_` antes do nome da uniform para evidenciar a natureza desta variável mas você encontrará outros tipos de nomenclatura para uniforms. Por exemplo [ShaderToy.com](https://www.shadertoy.com/) utiliza os mesmos uniforms mas com os seguintes nomes:
|
||||
|
||||
```glsl
|
||||
uniform vec3 iResolution; // resolução da viewport (em pixels)
|
||||
uniform vec4 iMouse; // coordenadas dos pixels do mouse . xy: atual, zw: clique
|
||||
uniform float iTime; // tempo de execução do shader (em segundos)
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform vec4 iMouse; // mouse pixel coords. xy: current, zw: click
|
||||
uniform float iTime; // shader playback time (in seconds)
|
||||
```
|
||||
|
||||
Chega de papo, vamos ver os uniforms em ação. No código a seguir, usamos `u_time` - o número de segundos desde que o shader começou a executar - junto com uma função seno para animar a transição da quantidade de vermelho no letreiro.
|
||||
Chega de conversa, vamos ver os uniforms em ação. No código abaixo, usamos `u_time` - o número de segundos desde que o shader começou a ser executado - junto com uma função de seno para animar a transição da quantidade de vermelho na tela.
|
||||
|
||||
<div class="codeAndCanvas" data="time.frag"></div>
|
||||
|
||||
Como você pode ver, GLSL tem mais surpresas. A GPU tem funções de ângulo, trigonométricas e exponenciais, aceleradas por hardware. Algumas dessas funções são: [`sin()`](../glossary/?search=sin), [`cos()`](../glossary/?search=cos), [`tan()`](../glossary/?search=tan), [`asin()`](../glossary/?search=asin), [`acos()`](../glossary/?search=acos), [`atan()`](../glossary/?search=atan), [`pow()`](../glossary/?search=pow), [`exp()`](../glossary/?search=exp), [`log()`](../glossary/?search=log), [`sqrt()`](../glossary/?search=sqrt), [`abs()`](../glossary/?search=abs), [`sign()`](../glossary/?search=sign), [`floor()`](../glossary/?search=floor), [`ceil()`](../glossary/?search=ceil), [`fract()`](../glossary/?search=fract), [`mod()`](../glossary/?search=mod), [`min()`](../glossary/?search=min), [`max()`](../glossary/?search=max) and [`clamp()`](../glossary/?search=clamp).
|
||||
Como você pode ver, GLSL tem mais surpresas. A GPU tem funções angulares, trigonométricas e exponenciais aceleradas pelo hardware. Algumas dessas funções são: [`sin()`](../glossary/?search=sin), [`cos()`](../glossary/?search=cos), [`tan()`](../glossary/?search=tan), [`asin()`](../glossary/?search=asin), [`acos()`](../glossary/?search=acos), [`atan()`](../glossary/?search=atan), [`pow()`](../glossary/?search=pow), [`exp()`](../glossary/?search=exp), [`log()`](../glossary/?search=log), [`sqrt()`](../glossary/?search=sqrt), [`abs()`](../glossary/?search=abs), [`sign()`](../glossary/?search=sign), [`floor()`](../glossary/?search=floor), [`ceil()`](../glossary/?search=ceil), [`fract()`](../glossary/?search=fract), [`mod()`](../glossary/?search=mod), [`min()`](../glossary/?search=min), [`max()`](../glossary/?search=max) e [`clamp()`](../glossary/?search=clamp).
|
||||
|
||||
Agora é a hora de brincar de novo com o código acima.
|
||||
Agora é novamente a hora de experimentar com o código acima.
|
||||
|
||||
* Diminua a frequência até que a mudança de cor seja quase imperceptível.
|
||||
* Diminua a frequência até a mudança de cor se tornar quase imperceptível.
|
||||
|
||||
* Acelere até você ver cada cor sem efeito de flicker.
|
||||
* Aumente a velocidade até que seja possível ver somente uma cor sem oscilações.
|
||||
|
||||
* Brinque com os três canais (RGB) em frequências diferentes para conseguir padrões e comportamentos interessantes.
|
||||
* Experimente alterar os valores dos três canais de cores (RGB) em diferentes frequências a fim de obter padrões e comportamentos interessantes.
|
||||
|
||||
## gl_FragCoord
|
||||
|
||||
Da mesma forma que a GLSL nos dá um output default, `vec4 gl_FragColor`, ela também nos dá um input default, `vec4 gl_FragCoord`, que contém aos coordenadas na tela do *pixel* ou *fragmento da tela* que a thread ativa está trabalhando. Com `vec4 gl_FragCoord`, sabemos onde uma thread está trabalhando dentro do letreiro. Neste caso, não chamamos de `uniform` porque ela será diferente de uma thread para a outra, então a `gl_FragCoord` é chamada de *variante*.
|
||||
Da mesma maneira que GLSL nos dá um output padrão, `vec4 gl_FragColor`, ele também nos dá um input padrão, `vec4 gl_FragCoord`, que possui as coordenadas de um *pixel* ou *screen fragment* com que a thread ativa está processando. Com `vec4 gl_FragCoord` podemos saber onde a thread está trabalhando dentro da tela. Neste caso, não chamaremos isso de `uniform` porque seu valor será diferente para cada thread, logo `gl_FragCoord` é chamada de *varying*.
|
||||
|
||||
<div class="codeAndCanvas" data="space.frag"></div>
|
||||
|
||||
No código acima, nós *normalizamos* a coordenada do fragmento dividindo-a pela resolução total do letreiro. Fazendo isso, os valores ficarão entre `0.0` e `1.0`, o que torna mais fácil mapear os valores X e Y para os canais RED e GREEN.
|
||||
No código acima nós *normalizamos* as coordenadas do fragmento ao dividi-las pela resolução total da tela. Fazendo isso, os valores serão entre `0.0` e `1.0`, o que facilita mapear os valores de X e Y para os canais RED e GREEN.
|
||||
|
||||
Na "shaderlândia", não temos muitos recursos para depurar, além de associar cores fortes a variáveis e tentar fazer um sentido com elas. Você vai descobrir que, às vezes, codificar em GLSL é muito parecido com colocar navios dentro de garrafas. É igualmente difícil, bonito e gratificante.
|
||||
No mundo dos shaders, não temos muitos recursos para depurar bugs além de atribuir uma cor marcante às variáveis e tentar entender o que está acontecendo com as mesmas. Você descobrirá que, às vezes, programar em GLSL é bem similar a construir navios dentro de garrafas. É igualmente difícil, bonito e gratificante.
|
||||
|
||||
![](08.png)
|
||||
|
||||
Agora é a hora de tentar e desafiar nosso entendimento desse código.
|
||||
Agora é a hora de tentar e desafiar a nossa compreensão desse código.
|
||||
|
||||
* Você pode dizer onde fica a coordenada `(0.0, 0.0)` em nosso canvas?
|
||||
* Você pode dizer onde a coordenada `(0.0, 0.0)` está em nossa tela?
|
||||
|
||||
* E as coordenadas `(1.0, 0.0)`, `(0.0, 1.0)`, `(0.5, 0.5)` e `(1.0, 1.0)`?
|
||||
* E quanto `(1.0, 0.0)`, `(0.0, 1.0)`, `(0.5, 0.5)` e `(1.0, 1.0)`?
|
||||
|
||||
* Você consegue imaginar como usar `u_mouse` sabendo que os valores são em pixels e NÃO valores normalizados? Você pode usar isso para mover as cores ao redor?
|
||||
* Você pode adivinhar como se usa o uniform `u_mouse`, sabendo que os valores são em pixel e NÃO em valores normalizados? Você pode usá-lo para mover as cores ao longo da tela?
|
||||
|
||||
* Você pode imaginar uma forma interessante de mudar esse padrão de cores usando as coordenadas `u_time` e `u_mouse`?
|
||||
* Você consegue imaginar uma maneira interessante para mudar esse padrão de cor usando `u_time` e as coordenadas de `u_mouse`?
|
||||
|
||||
Depois de fazer esses exercícios, você poderia pensar em que mais poderia tentar seus novos poderes de shader. No capítulo seguinte, vamos ver como fazer sua própria ferramenta de shader em three.js, Processing, e openFrameworks.
|
||||
Após completar estes exercícios, você talvez se pergunte onde mais você pode aplicar seu novo superpoder de shader. No próximo capítulo veremos como fazer as nossas próprias ferramentas de shader em three.js, Processing, e openFrameworks.
|
@ -0,0 +1,92 @@
|
||||
# Designs Generativos
|
||||
|
||||
It is not a surprise that after so much repetition and order the author is forced to bring some chaos.
|
||||
|
||||
## Random
|
||||
|
||||
[![Ryoji Ikeda - test pattern (2008) ](ryoji-ikeda.jpg) ](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set)
|
||||
|
||||
Randomness is a maximal expression of entropy. How can we generate randomness inside the seemingly predictable and rigid code environment?
|
||||
|
||||
Let's start by analyzing the following function:
|
||||
|
||||
<div class="simpleFunction" data="y = fract(sin(x)*1.0);"></div>
|
||||
|
||||
Above we are extracting the fractional content of a sine wave. The [```sin()```](../glossary/?search=sin) values that fluctuate between ```-1.0``` and ```1.0``` have been chopped behind the floating point, returning all positive values between ```0.0``` and ```1.0```. We can use this effect to get some pseudo-random values by "breaking" this sine wave into smaller pieces. How? By multiplying the resultant of [```sin(x)```](../glossary/?search=sin) by larger numbers. Go ahead and click on the function above and start adding some zeros.
|
||||
|
||||
By the time you get to ```100000.0``` ( and the equation looks like this: ```y = fract(sin(x)*100000.0)``` ) you aren't able to distinguish the sine wave any more. The granularity of the fractional part has corrupted the flow of the sine wave into pseudo-random chaos.
|
||||
|
||||
## Controlling chaos
|
||||
|
||||
Using random can be hard; it is both too chaotic and sometimes not random enough. Take a look at the following graph. To make it, we are using a ```rand()``` function which is implemented exactly like we describe above.
|
||||
|
||||
Taking a closer look, you can see the [```sin()```](../glossary/?search=sin) wave crest at ```-1.5707``` and ```1.5707```. I bet you now understand why - it's where the maximum and minimum of the sine wave happens.
|
||||
|
||||
If look closely at the random distribution, you will note that the there is some concentration around the middle compared to the edges.
|
||||
|
||||
<div class="simpleFunction" data="y = rand(x);
|
||||
//y = rand(x)*rand(x);
|
||||
//y = sqrt(rand(x));
|
||||
//y = pow(rand(x),5.);"></div>
|
||||
|
||||
A while ago [Pixelero](https://pixelero.wordpress.com) published an [interesting article about random distribution](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/). I've added some of the functions he uses in the previous graph for you to play with and see how the distribution can be changed. Uncomment the functions and see what happens.
|
||||
|
||||
If you read [Pixelero's article](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/), it is important to keep in mind that our ```rand()``` function is a deterministic random, also known as pseudo-random. Which means for example ```rand(1.)``` is always going to return the same value. [Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) makes reference to the ActionScript function ```Math.random()``` which is non-deterministic; every call will return a different value.
|
||||
|
||||
## 2D Random
|
||||
|
||||
Now that we have a better understanding of randomness, it's time to apply it in two dimensions, to both the ```x``` and ```y``` axis. For that we need a way to transform a two dimensional vector into a one dimensional floating point value. There are different ways to do this, but the [```dot()```](../glossary/?search=dot) function is particulary helpful in this case. It returns a single float value between ```0.0``` and ```1.0``` depending on the alignment of two vectors.
|
||||
|
||||
<div class="codeAndCanvas" data="2d-random.frag"></div>
|
||||
|
||||
Take a look at lines 13 to 15 and notice how we are comparing the ```vec2 st``` with another two dimensional vector ( ```vec2(12.9898,78.233)```).
|
||||
|
||||
* Try changing the values on lines 14 and 15. See how the random pattern changes and think about what we can learn from this.
|
||||
|
||||
* Hook this random function to the mouse interaction (```u_mouse```) and time (```u_time```) to understand better how it works.
|
||||
|
||||
## Using the chaos
|
||||
|
||||
Random in two dimensions looks a lot like TV noise, right? It's a hard raw material to use to compose images. Let's learn how to make use of it.
|
||||
|
||||
Our first step is to apply a grid to it; using the [```floor()```](../glossary/?search=floor) function we will generate an integer table of cells. Take a look at the following code, especially lines 22 and 23.
|
||||
|
||||
<div class="codeAndCanvas" data="2d-random-mosaic.frag"></div>
|
||||
|
||||
After scaling the space by 10 (on line 21), we separate the integers of the coordinates from the fractional part. We are familiar with this last operation because we have been using it to subdivide a space into smaller cells that go from ```0.0``` to ```1.0```. By obtaining the integer of the coordinate we isolate a common value for a region of pixels, which will look like a single cell. Then we can use that common integer to obtain a random value for that area. Because our random function is deterministic, the random value returned will be constant for all the pixels in that cell.
|
||||
|
||||
Uncomment line 29 to see that we preserve the floating part of the coordinate, so we can still use that as a coordinate system to draw things inside each cell.
|
||||
|
||||
Combining these two values - the integer part and the fractional part of the coordinate - will allow you to mix variation and order.
|
||||
|
||||
Take a look at this GLSL port of the famouse ```10 PRINT CHR$(205.5+RND(1)); : GOTO 10``` maze generator.
|
||||
|
||||
<div class="codeAndCanvas" data="2d-random-truchet.frag"></div>
|
||||
|
||||
Here I'm using the random values of the cells to draw a line in one direction or the other using the ```truchetPattern()``` function from the previous chapter (lines 41 to 47).
|
||||
|
||||
You can get another interesting pattern by uncommenting the block of lines between 50 to 53, or animate the pattern by uncommenting lines 35 and 36.
|
||||
|
||||
## Master Random
|
||||
|
||||
[Ryoji Ikeda](http://www.ryojiikeda.com/), Japanese electronic composer and visual artist, has mastered the use of random; it is hard not to be touched and mesmerized by his work. His use of randomness in audio and visual mediums is forged in such a way that it is not annoying chaos but a mirror of the complexity of our technological culture.
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/76813693?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
Take a look at [Ikeda](http://www.ryojiikeda.com/)'s work and try the following exercises:
|
||||
|
||||
* Make rows of moving cells (in opposite directions) with random values. Only display the cells with brighter values. Make the velocity of the rows fluctuate over time.
|
||||
|
||||
<a href="../edit.php#10/ikeda-00.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-00.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
* Similarly make several rows but each one with a different speed and direction. Hook the position of the mouse to the threshold of which cells to show.
|
||||
|
||||
<a href="../edit.php#10/ikeda-03.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-03.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
* Create other interesting effects.
|
||||
|
||||
<a href="../edit.php#10/ikeda-04.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-04.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
Using random aesthetically can be problematic, especially if you want to make natural-looking simulations. Random is simply too chaotic and very few things look ```random()``` in real life. If you look at a rain pattern or a stock chart, which are both quite random, they are nothing like the random pattern we made at the begining of this chapter. The reason? Well, random values have no correlation between them what so ever, but most natural patterns have some memory of the previous state.
|
||||
|
||||
In the next chapter we will learn about noise, the smooth and *natural looking* way of creating computational chaos.
|
Binary file not shown.
Before Width: | Height: | Size: 265 KiB After Width: | Height: | Size: 265 KiB |
Binary file not shown.
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 144 KiB |
@ -1,109 +1,111 @@
|
||||
<canvas id="custom" class="canvas" data-fragment-url="src/moon/moon.frag" data-textures="src/moon/moon.jpg" width="350px" height="350px"></canvas>
|
||||
|
||||
# The Book of Shaders
|
||||
*by [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) and [Jen Lowe](http://jenlowe.net/)*
|
||||
*por [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) e [Jen Lowe](http://jenlowe.net/)*
|
||||
|
||||
Este é um guia passo a passo através do universo complexo e abstrato dos Fragment Shaders.
|
||||
Este é um guia passo-a-passo pelo universo abstrato e complexo de Fragment Shaders.
|
||||
|
||||
<div class="header">
|
||||
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=B5FSVSHGEATCG" style="float: right;"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" alt=""></a>
|
||||
</div>
|
||||
|
||||
## Contents
|
||||
## Conteúdo
|
||||
|
||||
* [Sobre este livro](00/)
|
||||
|
||||
* Começando
|
||||
* Início
|
||||
* [O que é um shader?](01/)
|
||||
* [“Hello world!”](02/)
|
||||
* [Uniformes](03/)
|
||||
* [“Olá mundo!”](02/)
|
||||
* [Uniforms](03/)
|
||||
* [Executando seu shader](04/)
|
||||
|
||||
* Desenho algorítmico
|
||||
* Desenho algorítmico
|
||||
* [Funções de forma](05/)
|
||||
* [Cores](06/)
|
||||
* [Formas](07/)
|
||||
* [Matrizes](08/)
|
||||
* [Padrões](09/)
|
||||
|
||||
* Designs generativos
|
||||
* [Aletório](10/)
|
||||
* [Ruído](11/)
|
||||
* [Ruído celular](12/)
|
||||
* [Movimento browniano fractal](13/)
|
||||
* Design generativo
|
||||
* [Aleatório](10/)
|
||||
* [Noise](11/)
|
||||
* [Cellular noise](12/)
|
||||
* [Movimento browniano fracionário](13/)
|
||||
* Fractais
|
||||
|
||||
* Processamento de imagem
|
||||
* Texturas
|
||||
* Operações com imagens
|
||||
* Convoluções núcleo (kernel
|
||||
* Operações de imagem
|
||||
* Convoluções do kernel
|
||||
* Filtros
|
||||
* Outros efeitos
|
||||
|
||||
* Simulação
|
||||
* Pingpong
|
||||
* Conway
|
||||
* Ripples
|
||||
* Cor de água
|
||||
* Difusão de reação
|
||||
* Ondulações
|
||||
* Aquarela
|
||||
* Reação-Difusão
|
||||
|
||||
* Gráficos 3D
|
||||
* Gráficos em 3D
|
||||
* Luzes
|
||||
* Normal-maps
|
||||
* Bump-maps
|
||||
* Ray marching
|
||||
* Environmental-maps (esféricas e cúbicas)
|
||||
* Environmental-maps (esférico e cúbico)
|
||||
* Reflexão e refração
|
||||
|
||||
* [Apêndice:](appendix/) Outras formas de usar este livro
|
||||
* [Como posso navegar esse livro offline?](appendix/00/)
|
||||
* [Como rodar os exemplo em um Raspberry Pi?](appendix/01/)
|
||||
* [Como imprimir esse livro?](appendix/02/)
|
||||
* [Como posso colaborar?](appendix/03/)
|
||||
* [Uma introdução para quem vem do JS](appendix/04/) por [Nicolas Barradeau](http://www.barradeau.com/)
|
||||
* [Como eu posso ler este livro offline?](appendix/00/)
|
||||
* [Como eu posso rodar os exemplos em um Raspberry Pi?](appendix/01/)
|
||||
* [Como imprimir este livro?](appendix/02/)
|
||||
* [Como eu posso colaborar?](appendix/03/)
|
||||
* [Uma introdução para quem é familiarizado com JS](appendix/04/) por [Nicolas Barradeau](http://www.barradeau.com/)
|
||||
|
||||
* [Galeria de Exemplos](examples/)
|
||||
* [Galeria de exemplos](examples/)
|
||||
|
||||
* [Glossário](glossary/)
|
||||
|
||||
## Sobre os Autores
|
||||
## Sobre os autores
|
||||
|
||||
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Buenos Aires, Argentina) é um artista e desenvolvedor, atualmente morando em New York. Ele explora os espaços entre o orgânico e sintético, analógico e digital, individual e coletivo. Em seu trabalho, ele usa código como linguagem de expressão com a intenção de desenvolver uma melhor união.
|
||||
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Buenos Aires, Argentina) é um artista e desenvolvedor residente em New York. Ele explora os espaços intersticiais entre o orgânico e sintético, analógico e digital, individual e coletivo. Em seu trabalho utiliza código como linguagem expressiva com a intenção de desenvolver uma melhor conexão entre as pessoas.
|
||||
|
||||
Patricio estudou e praticou psicoterapia e terapia em arte expressiva. Tem um MFA em Design & Tecnologia pela Parsons The New School, onde ele agora leciona. Atualmente ele trabalha como Engenheiro Gráfico na Mapzen criando ferramentas openSource de mapeamento.
|
||||
Patricio estudou e praticou psicoterapia e terapia de arte expressiva. Ele possui MFA em Design & Technologia pela Parsons The New School, onde hoje leciona. Atualmente trabalha como Engenheiro Gráfico na Mapzen, criando ferramentas open source de mapeamento.
|
||||
|
||||
<div class="header"> <a href="http://patriciogonzalezvivo.com/" target="_blank">WebSite</a> - <a href="https://twitter.com/patriciogv" target="_blank">Twitter</a> - <a href="https://github.com/patriciogonzalezvivo" target="_blank">GitHub</a> - <a href="https://vimeo.com/patriciogv" target="_blank">Vimeo</a> - <a href="https://www.flickr.com/photos/106950246@N06/" target="_blank"> Flickr</a></div>
|
||||
|
||||
[Jen Lowe](http://jenlowe.net/) é uma cientista de dados independente e comunicadora de dados na Datatelling onde ela junta pessoas + números + palavras. Ela dá aulas no programa Design for Social Innovation da SVA, co-fundou a School for Poetic Computation, ensinou Matemática para Artistas na NYU ITP, pesquisouno Spatial Information Design Lab da Columbia University, e contribuiu com ideias na White House Office of Science and Technology Policy. Já falou na SXSW e Eyeo. Seu trabalho já foi coberto pelo The New York Times e a Fast Company. Sua pesquisa, escrita, e discurso exploram as promessas e implicações dos dados e a tecnologia na sociedade. Ela tem um B.S. em Matemática Aplicadae e Master's em Ciência da Informação. Geralmente em oposição a isso tudo, ela sempre está do lado do amor.
|
||||
[Jen Lowe](http://jenlowe.net/) é uma cientista de dados independente e comunicadora de dados na Datatelling, onde une pessoas + números + palavras. Ela leciona no SVA's Design for Social Innovation program, co-fundou a School for Poetic Computation, ensinou Math for Artists na NYU ITP, pesquisou no Spatial Information Design Lab na Columbia University, e contribuiu com ideias na White House Office of Science and Technology Policy. Ela discursou no SXSW e Eyeo. Seu trabalho foi coberto pelo The New York Times e Fast Company. Sua pesquisa, escritos, e palestras exploram as promessas e implicações dos dados e da technologia na sociedade. Ela é bacharel em Matemática Aplicada e mestre em Ciência da Informação. Frequentemente oposicionista, ela está sempre do lado do amor.
|
||||
|
||||
<div class="header"> <a href="http://jenlowe.net/" target="_blank">WebSite</a> - <a href="https://twitter.com/datatelling" target="_blank">Twitter</a> - <a href="https://github.com/datatelling" target="_blank">GitHub</a></div>
|
||||
|
||||
## Agradecimentos
|
||||
## Acknowledgements
|
||||
|
||||
Obrigado a [Scott Murray](http://alignedleft.com/) pela inspiração e conselhos.
|
||||
Obrigado [Scott Murray](http://alignedleft.com/) pela inspiração e conselhos.
|
||||
|
||||
Obrigado a [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo), [Nicolas Barradeau](https://twitter.com/nicoptere), [Karim Naaji](http://karim.naaji.fr/) por contribuir com apoio, boas ideia e código.
|
||||
Obrigado [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo), [Nicolas Barradeau](https://twitter.com/nicoptere), [Karim Naaji](http://karim.naaji.fr/) por contribuir com apoio, boas ideias e código.
|
||||
|
||||
Obrigado a [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) e [Sawako](https://twitter.com/sawakohome) pela [tradução japonesa (日本語訳)](?lan=jp)
|
||||
Obrigado [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) e [Sawako](https://twitter.com/sawakohome) pela [tradução em Japonês (日本語訳)](?lan=jp)
|
||||
|
||||
Obrigado a [Tong Li](https://www.facebook.com/tong.lee.9484) e [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) pela [tradução chinesa (中文版)](?lan=ch)
|
||||
Obrigado [Tong Li](https://www.facebook.com/tong.lee.9484) e [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) pela [tradução em Chinês (中文版)](?lan=ch)
|
||||
|
||||
Obrigado a [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) pela tradução [coreana (한국어)](?lan=kr)
|
||||
Obrigado [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) pela [tradução em Koreano (한국어)](?lan=kr)
|
||||
|
||||
Obrigado a [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) pela tradução [espanhola](?lan=es)
|
||||
Obrigado [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) pela [tradução em Espanhol (español)](?lan=es)
|
||||
|
||||
Obrigado a [Nicolas Barradeau](https://twitter.com/nicoptere) e [Karim Naaji](http://karim.naaji.fr/) pela tradução [francesa](?lan=fr)
|
||||
Obrigado [Nicolas Barradeau](https://twitter.com/nicoptere) e [Karim Naaji](http://karim.naaji.fr/) pela [tradução em Francês (français)](?lan=fr)
|
||||
|
||||
Obrigado a [Andrea Rovescalli](https://www.earove.info) pela tradução [italiana](?lan=it)
|
||||
Obrigado [Andrea Rovescalli](https://www.earove.info) pela [tradução em Italiano (italiano)](?lan=it)
|
||||
|
||||
Obrigado a [Michael Tischer](http://www.mitinet.de) pela tradução [alemã](?lan=de)
|
||||
Obrigado [Michael Tischer](http://www.mitinet.de) pela [tradução em Alemão (deutsch)](?lan=de)
|
||||
|
||||
Obrigado a [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) pela tradução [russa](?lan=ru)
|
||||
Obrigado [Sergey Karchevsky](https://www.facebook.com/sergey.karchevsky.3) pela [tradução em Russo (russian)](?lan=ru)
|
||||
|
||||
Obrigado a todos que acreditaram nesse projeto e [contribuiram com acertos](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) ou doações.
|
||||
Obrigado [Andy Stanton](https://andy.stanton.is/) por corrigir e melhorar [a pipeline para exportar pdf/epub](https://thebookofshaders.com/appendix/02/)
|
||||
|
||||
## Get new chapters
|
||||
Obrigado a todos que acreditaram neste projeto e [contribuíram com correções](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) ou doações.
|
||||
|
||||
Assine as newsletters ou [siga no Twitter](https://twitter.com/bookofshaders)
|
||||
## Receba novos capítulos
|
||||
|
||||
<form style="border:1px solid #ccc;padding:3px;text-align:center;" action="https://tinyletter.com/thebookofshaders" method="post" target="popupwindow" onsubmit="window.open('https://tinyletter.com/thebookofshaders', 'popupwindow', 'scrollbars=yes,width=800,height=600');return true"><a href="https://tinyletter.com/thebookofshaders"><p><label for="tlemail">Entre com seu email</label></p></a><p><input type="text" style="width:140px" name="email" id="tlemail" /></p><input type="hidden" value="1" name="embed"/><input type="submit" value="Subscribe" /><p><a href="https://tinyletter.com" target="_blank"></a></p></form>
|
||||
Assine a newsletter ou [nos siga no Twitter](https://twitter.com/bookofshaders)
|
||||
|
||||
<form style="border:1px solid #ccc;padding:3px;text-align:center;" action="https://tinyletter.com/thebookofshaders" method="post" target="popupwindow" onsubmit="window.open('https://tinyletter.com/thebookofshaders', 'popupwindow', 'scrollbars=yes,width=800,height=600');return true"><a href="https://tinyletter.com/thebookofshaders"><p><label for="tlemail">Insira seu e-mail</label></p></a><p><input type="text" style="width:140px" name="email" id="tlemail" /></p><input type="hidden" value="1" name="embed"/><input type="submit" value="Enviar" /><p><a href="https://tinyletter.com" target="_blank"></a></p></form>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 558 KiB |
Binary file not shown.
@ -0,0 +1,5 @@
|
||||
<dc:title>The Book of Shaders</dc:title>
|
||||
<dc:language>en-US</dc:language>
|
||||
<dc:creator opf:file-as="Gonzalez Vivo, Patricio" opf:role="aut">Patricio Gonzalez Vivo</dc:creator>
|
||||
<dc:creator opf:file-as="Lowe, Jen" opf:role="aut">Jen Lowe</dc:creator>
|
||||
<dc:rights>Copyright 2015 by Patricio Gonzalez Vivo & Jen Lowe</dc:rights>
|
Loading…
Reference in New Issue