diff --git a/00/README-pt.md b/00/README-pt.md index f2c8e77..d675a43 100644 --- a/00/README-pt.md +++ b/00/README-pt.md @@ -1,47 +1,47 @@ -# Introdução +# Introduction -As imagens acima foram feitas de maneiras diferentes. A primeira foi feita pelas mãos de Van Gogh aplicando camada sobre camada de tinta. Ele levou horas para pintá-la. A segunda foi produzida em segundos por uma combinação de quatro matrizes de pixels: uma para ciano, uma para magenta, uma para amarelo e uma para preto. A diferença chave entre ambas é que a segunda imagem foi produzida de uma maneira não-serializada (o que significa que não foi feita passo-a-passo, mas simultaneamente). +As imagens acima foram feitas de maneiras diferentes. A primeira foi feita pela mão do Van Gogh, aplicando-se camada a camada de tinta. Levou horas. A segunda foi produzida em segundos pela combinação de quatro matrizes de pixel: uma para ciano, uma para magenta, um para amarelo e outro pra preto. A diferença chave é que a segunda imagem é produzida de forma não-serial (ou seja, não foi passo a passo, mas todos ao mesmo tempo). -Este livro é sobre a revolucionária técnica computacional - *fragment shaders* - que eleva imagens geradas digitalmente a um outro nível. Essa revolução é comparável ao que a prensa de Gutenberg, na época, representou para as gráficas. +Este livro é sobre a técnica computacional revolucionária, *fragment shaders*, que está levando imagens geradas digitalmente a um nível mais alto. Você pode pensar nisso como sendo o equivalente à impressa de Gutenberg para gráficos. -![Prensa de Gutenberg](gutenpress.jpg) +![Gutenberg's press](gutenpress.jpg) -Fragment shaders te dá controle total sobre os pixels renderizados na tela com uma rapidez impressionante. Por isso eles são usados em todo o tipo de casos, de filtros de video em celulares à incríveis jogos em 3D. +Fragment shaders te dão controle total sobre os pixels rendereizados na tela, em velocidade super. É por isso que eles são usados para todas as finalidades, desde filtros de vídeo em celulares até videogames 3D incríveis. -![Journey por That Game Company](journey.jpg) +![Journey by That Game Company](journey.jpg) -Nos próximos capítulos você descobrirá o qual inacreditavelmente rápida e poderosa essa técnica é e como aplicá-la aos seus trabalhos profissionais e pessoais. +Nos capítulos seguintes, você vai descobrir o quão incrivelmente rápida e poderosa é essa técnica, e como aplicá-la para seu trabalho pessoal e profissional. -## Para quem é esse livro? +## Para quem é este livro? -Esse livro foi escrito para programadores criativos, desenvolvedores de jogos e engenheiros com experiencia em desenvolvimento, conhecimento básico de álgebra linear e trigonometria, e quem gostaria de elevar a qualidade gráfica de seu trabalho a níveis fascinantes. (Se você gostaria de aprender a programar, recomendo que você comece com [Processing](https://processing.org/) e retorne quando você se sentir mais apto.) +Este livro é escrito para programadores criativos, desenvolvedores de jogos e engenheiros que têm experiência em codificação, um conhecimento básico de álgebra linear e trigonometria, e quem quiser levar seu trabalho a um novo nível excitante de qualidade gráfica (se você quer aprender como programar, eu recomendo fortemente que comece com o [Processing](https://processing.org/) e volte mais tarde quando estiver comfortável com isso.). -Esse livro te ensinará como usar e integrar shaders nos seus projetos, melhorando sua performance e qualidade gráfica. Porque os shaders GLSL (OpenGL Shading Language) compilam e executam numa variedade de plataformas, você poderá aplicar o que aprender aqui em qualquer meio que utilize OpenGL, OpenGL ES ou WebGL. Em outras palavras, você será capaz de aplicar e usar seu conhecimento com sketches em [Processing](https://processing.org/), aplicações em [openFrameworks](http://openframeworks.cc/), instalações interativas em [Cinder](http://libcinder.org/) e websites ou jogos para iOS/Android em [Three.js](http://threejs.org/). +Este livro vai te ensinar como usar e integrar shaders em seus projetos, melhorando a qualidade gráfica e performance. Devido ao fato de shaders GLSL (OpenGL Shading Language) compilarem e rodarem em grande variedade de plataformas, você vai poder aplicar o que aprendeu aqui para qualquer ambiente que usar OpenGL, OpenGL ES ou WebGL. Em outras palavras, você vai poder aplicar e usar seu conhecimento com sketches do [Processing](https://processing.org/), aplicações [openFrameworks](http://openframeworks.cc/) , instalações interativas [Cinder](http://libcinder.org/) , websites [Three.js](http://threejs.org/) ou jogos iOS/Android. -## O que abrange esse livro? +## O que este livro cobre? -Esse livro focará no uso de pixel shaders GLSL. Primeiro vamos definir o que são shaders; então aprenderemos a fazer figuras, padrões, texturas e animações procedurais com eles. Você aprenderá os fundamentos da linguagem de shading e a aplicará em cenários mais úteis como: processamento de imagem (operações de imagem, convoluções matriciais, desfocamento, filtros de cor, lookup tables e outros efeitos) e simulações (o jogo da vida de Conway, reação-difusão de Gray-Scott, ondulações de água, efeitos de aquarela, células de Voronoi, etc.). Mais para o final do livro veremos um conjunto de técnicas avançadas baseadas em Ray Marching. +Este livro vai focar no uso de shaders de pixel em GLSL. Primeiro vamos definir o que são os shaders; então vamos aprender como fazer formas proceduralmente, padrões, texturas e animações com eles. Você vai aprender as fundações da linguagem de shaders e como aplicar em cenários mais úteis, como: processamento de imagens (operações com imagens, convoluções de matrizes, blurs, filtros de cores, tabelas de lookup, e outros efeitos) e simulações (jogo da vida de Conway, reação e difusão de Gray-Scott, ondas em água, efeitos de cores de água, células de Voroni, etc). Em direção ao fim do livro, vamos ver um conjunto de técnicas avançadas baseadas em Ray Marching. -*Haverão exemplos interativos para você experimentar com em cada capítulo.* Quando você mudar o código, você verá as mudanças imediatamente. Os conceitos podem ser abstratos e confusos, por isso os exemplos interativos são essenciais para te ajudar a entender o material. Quanto mais rápido você pôr a mão na massa, mais fácil o aprendizado será. +*Existem exemplos interativos para você brincar em cada capítulo.* Quando você muda o código, vai ver as mudanças imediatamente. os conceitos podem ser abstratos e confusos, então os exemplos interativos são essenciais para ajudá-lo a aprender o material. Quanto mais rápido você colocar os conceitos em movimento, mais fácil será o processo de aprendizagem. -O que esse livro não abrange: +O que esse livro não cobre: -* Este *não é* um livro sobre openGL ou webGL. OpenGL/webGL são assuntos maiores que GLSL ou fragment shaders. Para aprender mais sobre openGL/webGL eu recomendo checar: [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (também conhecido como o livro vermelho) ou [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) +* Este *não é* um livro de openGL ou webGL. OpenGL/webGL é um assunto maior que GLSL ou fragment shaders. Para aprender mais sobre openGL/webGL eu recomendo dar uma olhada em: [OpenGL Introduction](https://open.gl/introduction), [the 8th edition of the OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (também conhecido como o livro vermelho) ou [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl) -* Este *não é* um livro de matemática. Apesar de cobrirmos um número de algorítmos e técnicas que dependem da compreensão de álgebra e trigonometria, não as explicaremos em detalhes. Para dúvidas relacionadas à matemática eu recomendo manter um destes livros por perto: [3rd Edition of Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) ou [2nd Edition of Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers). +* Este *não é* um livro de matemática. Embora venhamos a cobrir um bom número de algoritmos e técnicas que se baseiam no entendimento de álgebra e trigonometria, não vamos explicá-los em detalhes. Para questões relacionadas com matemática eu recomendo que você tenha um desses livros por perto: [3rd Edition of Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) ou [2nd Edition of Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers). ## O que você precisa para começar? -Nada demais! Se você tem um navegador moderno com WebGL (como Chrome, Firefox ou Safari) e conexão à internet, clique em "Next" no fim desta página para começar. +Não muito! Se você tem um browser modernos que possa rodar WebGL (como Chrome, Firefox ou Safari) e uma conexão à internet, clique no botão para o próximo capítulo no fim desta página para começar. -Alternativamente, baseado no que você tem ou precisa nesse livro, você pode: +Alternativamente, baseado no que você tem, ou no que você precisa deste livro você pode: - [Fazer uma versão offline deste livro](https://thebookofshaders.com/appendix/00/) -- [Executar os exemplos em um Raspberry Pi sem um navegador](https://thebookofshaders.com/appendix/01/) +- [Rodar os exemplos em um Raspberry Pi sem um browser](https://thebookofshaders.com/appendix/01/) -- [Fazer um PDF do livro para impressão](https://thebookofshaders.com/appendix/02/) +- [Fazer um PDF do livro para imprimir](https://thebookofshaders.com/appendix/02/) -- Use o [repositório no GitHub](https://github.com/patriciogonzalezvivo/thebookofshaders) para nos ajudar a resolver problemas e compartilhar código. +- Checar o [repositório GitHub](https://github.com/patriciogonzalezvivo/thebookofshaders) deste livro para ajudar a resolver questões e compartilhar código. diff --git a/00/TITLE-pt.md b/00/TITLE-pt.md new file mode 100644 index 0000000..0d340c9 --- /dev/null +++ b/00/TITLE-pt.md @@ -0,0 +1 @@ +# Introdução diff --git a/01/TITLE-pt.md b/01/TITLE-pt.md new file mode 100644 index 0000000..2c66c5d --- /dev/null +++ b/01/TITLE-pt.md @@ -0,0 +1,2 @@ +# Começando +## O que é um shader? diff --git a/03/SUMMARY-pt.md b/03/SUMMARY-pt.md new file mode 100644 index 0000000..7a2089c --- /dev/null +++ b/03/SUMMARY-pt.md @@ -0,0 +1,7 @@ +Aprenda como usar variáveis Uniform. Variáveis uniform, ou simplesmente *uniformes* são as variáveis que carregam informação acessível igualmente de todas as threads do seu shader. O [editor GSLS](http://editor.thebookofshaders.com/) tem três uniformes setados para você. + +```glsl +uniform vec2 u_resolution; // Tamanho do canvas (largura,altura) +uniform vec2 u_mouse; // posição do mouse em pixels da tela +uniform float u_time; // Tempo em segundos desde carregamento +``` diff --git a/04/README-pt.md b/04/README-pt.md new file mode 100644 index 0000000..32cb0e6 --- /dev/null +++ b/04/README-pt.md @@ -0,0 +1,190 @@ +## Rodando o seu shader + +Como parte da construção deste livro, e minha prática de arte, eu fiz um ecossistema de ferramentas para criar, exibir e realizar curadoria de shaders. Essas ferramentas trabalham consistentemente em Linux, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) e browsers sem a necessidade de mudar seu código. + +**Exibir**: todos os exemplos ao vivo deste livro são exibidos usando o [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) que faz o processo de executar um shader standalone incrivelmente fácil. + +```html + +``` + +Como você pode ver, só precisa de um elemento `canvas` com `class="glslCanvas"` e a url para seu shader no `data-fragment-url`. Aprenda mais sobre isso [aqui](https://github.com/patriciogonzalezvivo/glslCanvas). + +Se você é como eum provavelmente vai querer rodar shaders diretamente da console, e nesse caso você deveria dar uma olhada no [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Esta aplicação lhe permite incorporar shaders em seus scripts `bash` ou pipelines do unix e usá-los de modo similiar ao [ImageMagick](http://www.imagemagick.org/script/index.php). Também, o [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) é uma boa forma de compilar shaders no seu [Raspberry Pi](https://www.raspberrypi.org/), razão pela qual o [openFrame.io](http://openframe.io/) o utiliza para exibir artes em shader. Aprenda mais sobre essa aplicação [aqui](https://github.com/patriciogonzalezvivo/glslViewer). + +```bash +glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png +``` + +**Criar**: de modo a trazer mais luz para a experiência de codificação de shaders, eu fiz um editor online chamado [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). Este editor está embutido nos exemplos ao vivo do livro, e traz uma série de widgets bem convenientes para tornar mais tangível a experiência abstrata de trabalhar com código GLSL. Você também pode executá-lo como uma aplicação web standalone no endereço [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Saiba mais sobre isso [aqui](https://github.com/patriciogonzalezvivo/glslEditor). + +![](glslEditor-01.gif) + +Se você prefere trabalhar offline usando o [SublimeText](https://www.sublimetext.com/) você pode instalar esse [pacote para glslViewer](https://packagecontrol.io/packages/glslViewer). Saiba mais sobre isso [aqui](https://github.com/patriciogonzalezvivo/sublime-glslViewer). + +![](glslViewer.gif) + +**Compartilhar**: o editor online ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) pode compartilhar seus shaders! Tanto a versão embedded quanto standalone têm um botão para exportar, onde você pode obter uma URL única para o seu shader. Eles têm também a capacidade de exportar diretamente para um [openFrame.io](http://openframe.io/). + +![](glslEditor-00.gif) + +**Curadoria**: Compartilhar o seu código é o começo para você compartilhar seus shaders como artwork! Além da opção de exportar para [openFrame.io](http://openframe.io/) eu fiz uma ferramenta para lhe permitir criar uam curadoria de seus shaders numa galeria que pode ser embutida em qualquer site, e seu nome é [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Saiba mais [aqui](https://github.com/patriciogonzalezvivo/glslGallery). + +![](glslGallery.gif) + +## Rodando seus shaders em seu framework favorito + +Para o caso de você já ter experiência em programar em um framework como [Processing](https://processing.org/), [Three.js](http://threejs.org/) ou [OpenFrameworks](http://openframeworks.cc/), você provavelmente está animado para tentar os shaders nessas plataformas que você se sente confortável. Os exemplos a seguir são formas de como configurar os shaders em alguns frameworks populares com os mesmos uniforms que vamos usar ao longo desse livro. (No [Repositório GitHub para esse capítulo](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), você encontra o código completo para esses três frameworks.) + +### Em **Three.js** + +O brillhante e humilde Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob) ) tem desenvolvido com outros [contribuidores](https://github.com/mrdoob/three.js/graphs/contributors) o que é provavelmente um dos mais famosos frameworks para WebGL, chamado de [Three.js](http://threejs.org/). Você vai encontrar muitos exemplos, tutoriais e livros que ensinam a usar essa biblioteca em JavaScript para fazer gráficos 3D muito legais. + +Abaixo, um exemplo do HTML e JS que você precisa para começar com shaders em three.js. Preste atenção ao script `id="fragmentShader"`, é aqui que você pode copiar os shaders que encontrar neste livro. + +```html + +
+ + + + + +``` + +### Em **Processing** + +Iniciado por [Ben Fry](http://benfry.com/) e [Casey Reas](http://reas.com/) em 2001, o [Processing](https://processing.org/) é um ambiente extraordinariamente simples e poderoso para você dar seus primeiros passos no código (pelo menos, pra mim, foi). [Andres Colubri](https://codeanticode.wordpress.com/) tem feito atualizações importantes no openGL e video em Processing, facilitando ainda mais que nunca o uso e diversão com shaders GLSL nesse ambiente amigável. O Processing vai procurar pelo shader chamado `"shader.frag"` na pasta `data`. Tenha certeza de copiar os exemplos que encontrar aqui para essa pasta, e renomear o arquivo. + +```cpp +PShader shader; + +void setup() { + size(640, 360, P2D); + noStroke(); + + shader = loadShader("shader.frag"); +} + +void draw() { + shader.set("u_resolution", float(width), float(height)); + shader.set("u_mouse", float(mouseX), float(mouseY)); + shader.set("u_time", millis() / 1000.0); + shader(shader); + rect(0,0,width,height); +} +``` + +De modo a fazer o shader funcionar em versões anteriores à 2.1, você precisa de adicionar a seguinte linha no começo de seu shader: `#define PROCESSING_COLOR_SHADER`. De modo que se pareça com isso: + +```glsl +#ifdef GL_ES +precision mediump float; +#endif + +#define PROCESSING_COLOR_SHADER + +uniform vec2 u_resolution; +uniform vec3 u_mouse; +uniform float u_time; + +void main() { + vec2 st = gl_FragCoord.st/u_resolution; + gl_FragColor = vec4(st.x,st.y,0.0,1.0); +} +``` + +Para mais informações sobre os shaders no Processing veja esse [tutorial](https://processing.org/tutorials/pshader/). + +### No **openFrameworks** + +Todo mundo tem um lugar onde se sente confortável, e no meu caso, ainda é a [comunidade openFrameworks](http://openframeworks.cc/). Esse framework C++ envolve o OpenGL e outras bibliotecas opensource C++. De muitas formas, é bem parecida com o Processing, mas com as complicações óbvias de se lidar com compiladores C++. Da mesma forma que o Processing, openFrameworks vai procurar o seu shader no diretório data, então não se esqueça de copiar os arquivos `.frag` que quiser usar, e mudar o nome quando for carregar. + +```cpp +void ofApp::draw(){ + ofShader shader; + shader.load("","shader.frag"); + + shader.begin(); + shader.setUniform1f("u_time", ofGetElapsedTimef()); + shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight()); + ofRect(0,0,ofGetWidth(), ofGetHeight()); + shader.end(); +} +``` + +Para mais informações sobre shaders em openFrameworks, vá nesse [excelente tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) feito por [Joshua Noble](http://thefactoryfactory.com/). diff --git a/04/TITLE-pt.md b/04/TITLE-pt.md new file mode 100644 index 0000000..5e70ba7 --- /dev/null +++ b/04/TITLE-pt.md @@ -0,0 +1 @@ +## Rodando o seu shader diff --git a/06/SUMMARY-pt.md b/06/SUMMARY-pt.md new file mode 100644 index 0000000..c49443e --- /dev/null +++ b/06/SUMMARY-pt.md @@ -0,0 +1 @@ +Familiarize-se com o modo de se expressar em cores nos shaders. Os exemplos cobrem a maneira de misturar cores e animá-las lindamente ao longo do tempo, bem como a conversão entre dois modelos diferentes (RGB e HSB). Em GLSL, as cores são simplesmente como vetores, o que quer dizer que você pode facilmente aplicar os conceitos e técnicas que aprender aqui para outros. \ No newline at end of file diff --git a/06/TITLE-pt.md b/06/TITLE-pt.md new file mode 100644 index 0000000..95c6c3f --- /dev/null +++ b/06/TITLE-pt.md @@ -0,0 +1 @@ +## Cores diff --git a/07/README-pt.md b/07/README-pt.md new file mode 100644 index 0000000..cf6138a --- /dev/null +++ b/07/README-pt.md @@ -0,0 +1,231 @@ +![Alice Hubbard, Providence, United States, ca. 1892. Photo: Zindman/Freemont.](froebel.jpg) + +## Formas + +Finalmente! A gente vem construindo habilidades para este momento! Você aprendeu a maioria das fundações, tipo s funções GLSL. Você praticou suas equações de formas várias vezes. Agora é a hora de juntar tudo. Você está pronto para este desafio! Neste capítulo, vai aprender como desenhar formas simples, de forma procedural paralela. + +### Retângulo + +Imagine que tenhamos um papel quadriculado como os que usamos nas aulas e exercícios de casa de matemática, e queremos desenhar um quadrado. O tamanho do papel é 10x10 e o quadrado deveria ser 8x8. O que você vai fazer? + +![](grid_paper.jpg) + +Você pintaria tudo, menos a primeira linha e a última, e a primeira coluna e a última, certo? + +E como isso se relaciona com os shaders? Cada quadradinho de nosso papel é uma thread (um pixel). Cada quadradinho sabe sua posição, como as coordenadas de um tabuleiro de xadrez. Em capítulos anteriores, nós mapeamos *x* e *y* para os canais de cores *vermelho* e *verde*, e aprendemos como usar o estreito território bidimensional entre 0.0 e 1.0. Como podemos usar isso para desenhar um quadrado centralizado no meio da nossa tela? + +Vamos começar rascunhando um pseudocódigo que usa vários `if` no campo espacial. Os princípios para fazer isso são notavelmente similares ao modo que pensamos no cenário do papel quadriculado. + +```glsl +if ( (X MAIOR QUE 1) AND (Y MAIOR QUE 1) ) + pinta de branco +else + pinta de preto +``` + +Agora que temos uma ideia melhor de como isos vai funcionar, vamos substituir os `if` com [`step()`](../glossary/?search=step), e, em vez de usar 10x10, vamos usar valores normalizados entre 0.0 e 1.0: + +```glsl +uniform vec2 u_resolution; + +void main(){ + vec2 st = gl_FragCoord.xy/u_resolution.xy; + vec3 color = vec3(0.0); + + // Cada resultado retorna 1.0 (branco) ou 0.0 (preto). + float left = step(0.1,st.x); // Similar a ( X maior que 0.1 ) + float bottom = step(0.1,st.y); // Similar a ( Y maior que 0.1 ) + + // A multiplicação left*bottom vai ser similar ao AND lógico. + color = vec3( left * bottom ); + + gl_FragColor = vec4(color,1.0); +} +``` + +A função [`step()`](../glossary/?search=step) vai tornar cada pixel abaixo de 0.1 preto (`vec3(0.0)`) e o resto branco (`vec3(1.0)`) . A multiplicação entre `left` e `bottom` funciona como um `AND` lógico, onde os dois devem estar 1.0 para retornar 1.0. Isso desenha duas linhas pretas, uma no fundo, e outra na lado esquerdo do canvas. + +![](rect-01.jpg) + +No código anterior, repetimos a estrutura para cada eixo (esquerdo e fundo). Podemos economizar algumas linhas de código, passando 2 vaores diretamente para [`step()`](../glossary/?search=step) ao invés de apenas um. Seria algo assim: + +```glsl +vec2 borders = step(vec2(0.1),st); +float pct = borders.x * borders.y; +``` + +Até agora, só desenhamos duas bordar (fundo-esquerda) de nosso retângulo. Vamos desenhar as outras duas (topo-direita). Veja esse código: + +
+ +Descomente as *linhas 21-22* e veja como invertemos as coordenadas `st` e repetimos a mesma função [`step()`](../glossary/?search=step). Desse jeito, o `vec2(0.0,0.0)` vai estar no canto superior direito. Isso é o equivalente digital a girar a página e repetir o mesmo procedimento. + +![](rect-02.jpg) + +Note que nas *linhas 18 e 22*, todos os lados estão sendo multiplicados juntos. É o mesmo que escrever: + +```glsl +vec2 bl = step(vec2(0.1),st); // bottom-left +vec2 tr = step(vec2(0.1),1.0-st); // top-right +color = vec3(bl.x * bl.y * tr.x * tr.y); +``` + +Interessante, certo? Essa técnica é, basicamente, usar [`step()`](../glossary/?search=step) e multiplicação para operações lógicas, e flipar as coordenadas. + +Antes de prosseguir, tente os exercícios a seguir: + +* Mude o tamanho e as proporções do retângulo. + +* Experimente com o mesmo código, mas usando [`smoothstep()`](../glossary/?search=smoothstep) no lugar de [`step()`](../glossary/?search=step). Note que, ao mudar os valores, você pode ir de beiradas embaçadas até elegantes bordas suaves. + +* Faça uma outra implementação que use [`floor()`](../glossary/?search=floor). + +* Escolha a implementação de que gostar mais, e faça uma função dela, que você possa reutilizar no futuro. Deixe sua função flexível e eficiente. + +* Faça outra função que apenas desenhe o contorno do retângulo. + +* Como você acha que poderia mover e colocar retângulos diferentes na mesma tela? Se descobrir como, mostre suas habilidades fazendo uma composição de retângulos e cores que se pareça com uma pintura de [Piet Mondrian](http://en.wikipedia.org/wiki/Piet_Mondrian). + +![Piet Mondrian - Tableau (1921)](mondrian.jpg) + +### Círculos + +É fácil desenhar quadrados em um papel quadriculado, e retângulos em coordenadas cartesianas, mas círculos requerem outra abordagem, especialmente porque precisamos de um algoritmo "por pixel". Uma solução é *remapear* as coordenadas espaciais de modo que possamos usar uma função [`step()`](../glossary/?search=step) para desenhar um círculo. + +Como? Vamos começar, voltando um pouco às aulas de matemática e o papel quadriculado, onde nós abríamos um compasso até o raio do círculo, apertamos uma das pontas do compasso no centro do círculo, e então tracejamos o contorno do círculo com uma rodada do compasso. + +![](compass.jpg) + +Traduzindo isso para um shader, onde cada quadrado no papel é um pixel, implica em *perguntar* a cada pixel (ou thread) se ele está dentro da área do círculo. Fazemos isso calculando a distância do pixel até o centro do círculo. + +![](circle.jpg) + +Existem várias formas de se calcular essa distância. A mais fácil usa a função [`distance()`](../glossary/?search=distance), que, internamente, calcula o [`length()`](../glossary/?search=length) (comprimento) da diferença entre dois pontos (em nosso caso, a coordenada do pixel, e o centro da tela). A função `length()` nada mais é que um atalho para a [equação de hipotenusa](http://en.wikipedia.org/wiki/Hypotenuse) que usa raiz quadrada ([`sqrt()`](../glossary/?search=sqrt)) internamente. + +![](hypotenuse.png) + +Você pode usar [`distance()`](../glossary/?search=distance), [`length()`](../glossary/?search=length) ou [`sqrt()`](../glossary/?search=sqrt) para calcular a distância até o centro da tela. O código a seguir contém essas três funções e o fato não-surpreendente de que retornam o mesmo resultado. + +* Comente e descomente as linhas para testar as diferentes formar de obter o mesmo resultado. + +
+ +No exemplo anterior, nós mapeamos a distância até o centro para o brilho da cor de cada pixel. Quanto mais ao centro está um pixel, mais escuro ele é (menor valor de cor). Note que os valores não ficam muito altos porque a partir do centro ( `vec2(0.5, 0.5)` ) a distância máxima mal passa de 0.5. Contemple esse mapa e pense: + +* O que você pode inferir disso? + +* Como podemos usar isso para desen um círculo? + +* Modifique o código acima, de modo a conter o gradiente circular inteiro dentro do canvas. + +### Campo de distância + +Também podemos pensar no exemplo acima como um mapa de altitude, onde áreas mais escuras implicam em maior altura. O gradiente nos mostra algo similar ao padrão feito por um cone. Imagine-se no topo desse cone. A distância horizontal até a borda do cone é 0.5. Isso será constante em todas as direções. Escolhendo onde "cortar" o cone, vai te dar uma superfície circular maior ou menor. + +![](distance-field.jpg) + +Basicamente, estamos usando uma reinterpretação do espaço (baseado na distância até o centro) para fazer formas. Essa técnica é conhecida como "campo de distância" e é usada e diferentes modos, desde outlines de fontes até gráficos 3D. + +Tente os seguintes exercícios: + +* Use o [`step()`](../glossary/?search=step) para tornar tudo acima de 0.5 em branco e tudo abaixo para 0.0. + +* Inverta as cores do fundo e do primeiro plano. + +* Usando [`smoothstep()`](../glossary/?search=smoothstep), faça experiências com valores diferentes para conseguir uma borda suave no seu círculo. + +* Uma vez que esteja feliz com uma implementação, faça uma função com ela, para reutilizar no futuro. + +* Adicione cor ao círculo. + +* Você pode animar seu círculo, para crescer e encolher, simulando a batida de um coração? (Você pode ter alguma inspiração, da animação do capítulo anterior) + +* Que tal mover esse círculo? Você consegue movê-lo para lugares diferentes na tela? + +* O que acontece se você combinar campos de distância usando diferentes funções e operações? + +```glsl +pct = distance(st,vec2(0.4)) + distance(st,vec2(0.6)); +pct = distance(st,vec2(0.4)) * distance(st,vec2(0.6)); +pct = min(distance(st,vec2(0.4)),distance(st,vec2(0.6))); +pct = max(distance(st,vec2(0.4)),distance(st,vec2(0.6))); +pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6))); +``` + +* Faça três composições usando essa técnica. Se forem animadas, melhor ainda! + +#### Para sua caixa de ferramentas + +Em termos de poder computacional, a função [`sqrt()`](../glossary/?search=sqrt) - e todas as que dependem dela - pode ser bem cara. Aqui vai outra forma de criar um campo de distância usando [`dot()`](../glossary/?search=dot) (produto escalar). + +
+ +### Propriedades úteis de um Campo de Distância + +![Zen garden](zen-garden.jpg) + +Campos de Distância podem ser usados para desenhar quase tudo. Obviamente, quanto mais complexa for uma forma, mais complicada vai ser a equação, mas uma vez que você tenha a fórmula para fazer um campo de distância de uma forma específica, é muito fácil combinar e/ou aplicar efeitos a ela, como bordas suaves, e múltiplos outlines. Por causa disso, os campos de distância são populares para rendereizar fontes, como [Mapbox GL Labels](https://www.mapbox.com/blog/text-signed-distance-fields/), [Matt DesLauriers](https://twitter.com/mattdesl) [Material Design Fonts](http://mattdesl.svbtle.com/material-design-on-the-gpu) e [ como descrito no capítulo 7 do livro iPhone 3D Programming, O’Reilly](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921). + +Dê uma olhada no código a seguir. + +
+ +Começamos movendo o sistema de coordenadas para o centro e encolhendo-o pela metade, para remapear os valores de posição entre -1 e 1. Também, na *linha 24*, estamos visualizando os valores do campo de distância usando uma função [`fract()`](../glossary/?search=fract) para facilitar que você veja o padrão que eles criam. O padrão do campo de distância se repete o tempo todo, como anéis num jardim Zen. + +Vamos dar uma olhada na fórmula do campo, na *linha 19*. Ali, estamos calculando a distância até a posição `(.3,.3)` ou `vec3(.3)` em todos os nossos quatro quadrantes (é isso o que o [`abs()`](../glossary/?search=abs) está fazendo aqui). + +Se você descomentar a *linha 20*, vai notar que estamos combinando as distâncias para esses quatro pontos usando o [`min()`](../glossary/?search=min) para zero. O resultado produz um novo padrão bem interessante. + +Agora, tente descomentar a *linha 21*; estamos fazendo o mesmo, mas usando a função [`max()`](../glossary/?search=max). O rsultado é um retângulo com cantos arredondados. Note como os anéis do cmapo ditância ficam mais suaves quanto mais disntantes do centro. + +Termine de descomentar as *linhas 27 a 29* uma a uma, para entender os diferentes usos de um padrão de campo de distância. + +### Formas Polares + +![Robert Mangold - Untitled (2008)](mangold.jpg) + +No capítulo sobre sores, nós mapeamos as coordenadas cartesianas para coordenadas polares, calculando o *raio* e os *ângulos* de cada pixel com essa fórmula: + +```glsl +vec2 pos = vec2(0.5)-st; +float r = length(pos)*2.0; +float a = atan(pos.y,pos.x); +``` + +Usamos parte desta fórmula no começo do capítulo para desenhar um círculo. Nós calculamos a distância até o centro usando [`length()`](../glossary/?search=length). Agora que sabemos sobre os os campos de distância, podemos aprender outra forma de desenhar formar, usando coordenadas polares. + +Esta técnica é um pouco restritiva, mas bem simples. Ela consiste em mudar o raio de um círculo dependendo do ângulo, para obter formas diferentes. Como a modulação funciona? Sim, usando funções de formas! + +Abaixo, você vai encontrar as mesmas funções do gráfico cartesiano e em um exemplo shader de coordenadas polares (entre as *linhas 21 e 25*). Descomente as funções uma a uma, prestando atenção na relação entre um sistema de coordenadas e o outro. + +
+ +
+ +Tente: + +* Animar essas formas. +* Combinar funções de formas diferentes para *cortar buracos* na forma, para fazer flores, flocos de neve e engrenagens. +* Use a função `plot()` que usamos no capítulo sobre *Funções de Formas* para desenhar só o contorno. + +### Combinando forças + +Agora que aprendemos como modular o raio de um círculo de acordo com o ângulo, usando [`atan()`](../glossary/?search=atan) para desenhar formas diferentes, podemos aprender a usar `atan()` com campos de distância e aplicar todos os truques e efeitos possíveis com campos de distância. + +O truque vai usar o número de lados de um polígono para construir o campo de distância, usando coordenadas polares. Veja o [seguinte código](http://thndl.com/square-shaped-shaders.html) do [Andrew Baldwin](https://twitter.com/baldand). + +
+ +* Usando este exemplo, faça uma função que tem como entrada a posição e o número de lados de uma forma desejada, e retorna um valor de campo de distância. + +* Misture campos de distância usando [`min()`](../glossary/?search=min) e [`max()`](../glossary/?search=max). + +* Escolha um logo geométrico para replicar, usando campos de distância. + +Parabéns! Você já passou pela parte mais dura! Dê uma pausa e deixe os conceitos assentarem - desenhar formas simples no Processing é fácil, mas não aqui. Na terra dos shaders, desenhar formas é difícil, e pode ser cansativo se adaptar a esse novo paradigma de programação. + +Agora que você já sabe como desenhar formas, tenho certeza de que novas ideias vão pular na sua mente. No capítulo a seguir, você vai aprender como mover, rotacionar e mudar a escala das formas. Isso vai te permitir a fazer composições! diff --git a/07/SUMMARY-pt.md b/07/SUMMARY-pt.md new file mode 100644 index 0000000..7ca2738 --- /dev/null +++ b/07/SUMMARY-pt.md @@ -0,0 +1 @@ +Vamos dar uma olhada em como desenhar formar simples de forma procedural paralela. Em poucas palavras, tudo o que você precisa é determinar se cada pixel pertence à forma que quer desenhar ou não, e aplicar cores diferentes dependendo do caso. Você pode usar o sistema de coordenadas, como um papel quadriculado, para desenhar retângulos e quadrados. Vamos olhar um conceito mais avançado chamado campo de distância para desenhar formar mais complexas. \ No newline at end of file diff --git a/07/TITLE-pt.md b/07/TITLE-pt.md new file mode 100644 index 0000000..d63cef2 --- /dev/null +++ b/07/TITLE-pt.md @@ -0,0 +1 @@ +## Formas diff --git a/08/README-pt.md b/08/README-pt.md new file mode 100644 index 0000000..7d7215f --- /dev/null +++ b/08/README-pt.md @@ -0,0 +1,101 @@ +## Matrizes 2D + + + +### Translação + +No capítulo anterior, aprendemos como fazer algumas formas básicas - o macete para mover essas formas é mover o próprio sistema de coordenadas. Podemos fazer isso simplesmente adicionando um vetor à variável ```st``` que contém a localização de cada fragmento. Isso faz com que todo o sistema de coordenadas espaciais se mova. + +![](translate.jpg) + +Isso é mais fácil de ver do que explicar, então, veja por você mesmo: + +* Descomente a linha 35 do código acima para ver como o espaço se move. + +
+ +Agora, tente o seguinte exercício: + +* Usar ```u_time``` junto com funções de forma, mova a pequena cruz de uma forma interessante. Procure por uma qualidade específica de movimento que você esteja interessado e tente fazer a cruz se mover do mesmo jeito. Gravar algo do "mundo real" primeiro pode ser útil - poderia ser o ir e vir das ondas, um movimento de um pêndulo, uma bola saltitante, um carro acelerando, uma bicicleta parando. + +### Rotações + +Para rotacionar objetos, também precisamos mover o sistema espacial inteiro. Para isso, vamos usar uma [matriz](http://en.wikipedia.org/wiki/Matrix_%28mathematics%29). Uma matriz é um conjunto organizado de números em colunas e linhas. Vetores são multiplicados por matrizes seguindo um conjunto preciso de regras de forma a modificar os valores do vetor de maneira particular. + +[![Wikipedia entry for Matrix (mathematics) ](matrixes.png)](https://en.wikipedia.org/wiki/Matrix) + +GLSL tem suporte nativo para matrizes de duas, três e quatro dimensões: [```mat2```](../glossary/?search=mat2) (2x2), [```mat3```](../glossary/?search=mat3) (3x3) and [```mat4```](../glossary/?search=mat4) (4x4). GLSL também suporta multiplicação de matrizes (```*```) e uma função específica de matrizes ([```matrixCompMult()```](../glossary/?search=matrixCompMult)). + +Baseado em como as matrizes se comportam, é possível construir matrizes para produzir comportamentos específicos. Por exemplo, podemos usar uma matriz para transladar um vetor: + +![](3dtransmat.png) + +Mais interessante ainda: podemos usar uma matriz para rotacionar o sistema de coordenadas: + +![](rotmat.png) + +Dê uma olhada no código a seguir para ver uma função que constrói uma matriz de rotação 2D. Essa função segue a [fórmula](http://en.wikipedia.org/wiki/Rotation_matrix) acima para vetores de duas dimensões, para rotacionar as coordenadas em torno do ponto ```vec2(0.0)```. + +```glsl +mat2 rotate2d(float _angle){ + return mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)); +} +``` + +De acordo com a forma como estamos desanhando nossas formas, não é isso, exatamente, o que queremos. Nossa forma de cruz é desenhada no meio da tela, o que corresponde à posição ```vec2(0.5)```. Então, antes de rodarmos o espaço, precisamos mover a forma do `center` para a coordenada ```vec2(0.0)```, rotacionar o espaço, e finalmente mover de volta para o lugar original. + +![](rotate.jpg) + +Isso se parece com o seguinte código: + +
+ +Tente os exersícios a seguir: + +* Descomente a linha 45 do código acima, e preste atenção no que acontece. + +* Comente as translações antes e depois da rotação, nas linhas 37 e 39, e observe as consequências. + +* Use rotações para melhorar a animação que você simulou no exercício de translação. + +### Escala (scale) + +Vimos como as matrizes são usadas para transladar e rotacionar objetos no espaço (ou, mais precisamente, transformar o sistema de coordenadas para rotacionar e mover objetos). Se você já usou softwares de modelagem 3D ou as funções de push e pop no Processing, já sabe que as matrizes também podem ser usadas para escalar o tamanho de um objeto. + +![](scale.png) + +Seguindo a fórmula anterior, você pode calcular como fazer uma matriz para escalar em 2D: + +```glsl +mat2 scale(vec2 _scale){ + return mat2(_scale.x,0.0, + 0.0,_scale.y); +} +``` + +
+ +Tente os seguintes exersícios para entender mais a fundo como isso funciona. + +* Descomente a linha 42 do código acima, para ver a coordenada de espaço sendo escalada. + +* Veja o que acontece quando você comenta as translações antes e depois de escalar, nas linhas 37 e 39. + +* Tente combinar uma matriz de rotação com uma de escala. Tenha em mente que a ordem faz diferença. Multiplique pela matriz primeiro e então multiplique os vetores. + +* Agora que você sabe como desenhar formas diferentes, e mover, rotacionar e escalá-las, é hora de fazer uma composição bem maneira. Projete e construa um [HUD (heads up display) ou UI falso](https://www.pinterest.com/patriciogonzv/huds/). Use o seguinte ShaderToy de exemplo, do [Ndel](https://www.shadertoy.com/user/ndel) como inspiração e referência. + + + +### Outros usos para matrizes: cores YUV + +[YUV](http://en.wikipedia.org/wiki/YUV) é um espaço de cores usado para codificação analógica de fotos e vídeos, que considera o faixa da percepção humana para reduzir a largura de banda dos componentes de crominância. + +O código a seguir é uma oportunidade interessante para usar operações de matrizes em GLSL para transformar as cores de um modo para outro. + +
+ +Como você pode ver, estamos tratando as cores como vetores, multiplicando-os com matrizes. Dessa forma, nós "movemos" os valores. + +Neste capítulo, aprendemos como usar transformações de matrizes para mover, rotacionar e escalar vetores. Essas transformações serão essenciais para fazer composições com as formas que aprendemos no capítulo anterior. No próximo capítulo, vamos aplicar tudo o que aprendemos para fazer padrões procedurais bem bonitos. Você vai achar que a repetição e variação na programação podem ser uma prática excitante. diff --git a/08/SUMMARY-pt.md b/08/SUMMARY-pt.md new file mode 100644 index 0000000..143ddf1 --- /dev/null +++ b/08/SUMMARY-pt.md @@ -0,0 +1,2 @@ +Matriz é uma ferramenta poderosa para manipular vetores. Ser experiente com matrizes lhe permite a, livremente, transladar, escalar e rotacionar formas. Uma vez que a técnica pode ser aplicada igualmente para qualquer coisa expressada por vetores, vamos dar uma olhada em usos muito mais avançados depois, neste livro. Matrizes podem árecer complexas à primeira vista, mas você vai achá-las bem úteis depois que pegar o conceito. Vamos praticar aqui e aprender o básico com alguns exemplos simples. + diff --git a/08/TITLE-pt.md b/08/TITLE-pt.md new file mode 100644 index 0000000..052b871 --- /dev/null +++ b/08/TITLE-pt.md @@ -0,0 +1 @@ +## Matrizes 2D diff --git a/09/README-pt.md b/09/README-pt.md new file mode 100644 index 0000000..b681d53 --- /dev/null +++ b/09/README-pt.md @@ -0,0 +1,122 @@ +## Patterns (padrões) + +Uma vez que os programas de shaders são executados pixel a pixel, não importa o quanto você repete uma forma, o número de cálculos permanece constante. Isso quer dizer que fragment shaders se encaixam perfeitamente para a criação de padrões "tile patterns". + +[ ![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg) ](../edit.php#09/dots5.frag) + +Neste capítulo, vamos aplicar o que aprendemos até agora, e repetir isso ao longo da tela. Como nos capítulos anteriores, nossa estratégia será baseada em multiplicar as coordenadas espaciais (entre 0.0 e 1.0), de modo que as formas que desenharmos entre os valores 0.0 e 1.0 serão repetidas para fazer um grid. + +*"O grid provê uma framework na qual a intuição e a invenção humana podem operar e que pode subverter. Dentro do caos da natureza, os padrões provêem um contraste e promessa de ordem. Desde padrões mais antigos nas cerâmicas até mosaicos geométricos nos banheiros de Roma, as pessoas têm usado grids para melhorar suas vidas com a decoração."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/) + +Primeiro, vamos nos lembras da função [```fract()```](../glossary/?search=fract). Ela retorna a parte fracionária de um número, tornando ```fract()```, em essência, o módulo de um ([```mod(x,1.0)```](../glossary/?search=mod)). Em outras palavras, [```fract()```](../glossary/?search=fract) retorna o número depois do ponto flutuante. Nossa variável do sistema de coordenadas normalizadas (```st```) já vai de 0.0 a 1.0, então não faz sentido termos algo como: + +```glsl +void main(){ + vec2 st = gl_FragCoord.xy/u_resolution; + vec3 color = vec3(0.0); + st = fract(st); + color = vec3(st,0.0); + gl_FragColor = vec4(color,1.0); +} +``` + +Mas se nós escalarmos o sistema de coordenadas para cima - digamos, aumentar por três - vamos ter três sequências de interpolações lineares entre 0-1: a primeira, entre 0-1, a segunda para os pontos flutuantes entre 1-2, e a terceira para os pontos flutuantes entre 2-3. + +
+ +Agora é horas de desenhar algo em cada subespaço, descomentando a linha 27 (devido ao fato de estarmos multiplicando igualmente os valores de x e y, o aspecto do espaço não muda e as formas serão como esperado). + +Tente os seguintes exercícios para entender mais a fundo: + +* Multiplique o espaço por números diferentes. Tente com valores de ponto flutuante e também com valores diferentes para x e y. + +* Crie uma função reutilizável para esse truque com os padrões. + +* Divida o espaço em três linhas e três colunas. Ache um jeito de saber em que coluna e linha está a thread, e use isso para mudar a forma que está exibindo. tente compor um jogo da velha. + +### Aplique matrizes dentro dos patterns + +Como cada subdivisão ou célula é uma versão menor do sistema de coordenadas normalizadas que já vínhamos usando, podemos aplicar uma transformação de matrizes a ela, de modo a transladar, rotacionar ou escalar o espaço ali dentro. + +
+ +* Pense em modos interessantes de animar esse padrão. Considere animação de cores, formas e movimento. Faça três animações diferentes. + +* Recrie patterns mais complicados, compondo formas diferentes. + + +[![](diamondtiles-long.png)](../edit.php#09/diamondtiles.frag) + +* Combine camadas diferentes de patterns, para compor seus próprios [Scottish Tartan Patterns](https://www.google.com/search?q=scottish+patterns+fabric&tbm=isch&tbo=u&source=univ&sa=X&ei=Y1aFVfmfD9P-yQTLuYCIDA&ved=0CB4QsAQ&biw=1399&bih=799#tbm=isch&q=Scottish+Tartans+Patterns). + +[ ![Vector Pattern Scottish Tartan By Kavalenkava](tartan.jpg) ](http://graphicriver.net/item/vector-pattern-scottish-tartan/6590076) + +### Offset patterns + +Então, digamos que queremos imitar um muro de tijolos. Olhando para o muro, você pode ver um deslocamento de meio tijolo em x, entre as linhas. Como podemos fazer isso? + +![](brick.jpg) + +Como primeiro passo, precisamos saber se a linha de nossa thread é uma linha par ou ímpar, porque podemos usar isso a para determinar se precisamos fazer o deslocamento do x nessa linha. + +____nós temos que consertar esses dois próximos parágrafos, juntos____ + +Para determinar se nossa thread está numa linha par ou ímpar, vamos usar o [```mod()```](../glossary/?search=mod) de ```2.0``` e então ver se se o resultado está abaixo de ```1.0``` ou não. Dê uma olhada na fórmula seguinte e descomente as duas últimas linhas. + +
+ +Como pode ver, usamos um [operador ternário](https://en.wikipedia.org/wiki/%3F: ) para checar se o [```mod()```](../glossary/?search=mod) de ```2.0``` é abaixo de ```1.0``` (segunda linha) ou de modo similar, podemos usar um [```step()```](../glossary/?search=step) que faz a mesma operação, mas mais rápido. Por quê? Embora seja difícil saber como cada placa gráfica otimiza e compila o programa, é seguro assumir que funções built-in são mais rápidas que as outras. Toda vez que puder usar uma função built-in , use! + +Então, agora que temos nossa fórmula para números ímpares, podemos aplicar um deslocamento nas linhas ímpares, para dar um efeito de *tijolos* aos nossos "tiles". A linha 14 do código a seguir é onde estamos usando a função para "detectar" linhas ímpares e dar a elas um offset de meia unidade em ```x```. Note que para linhas pares, o resultado da função é ```0.0```, e multiplicar ```0.0``` pelo offset de ```0.5``` nos dá um offset de ```0.0```. Mas em linhas ímpares, multiplicamos o resultado da função, ```1.0```, pelo offset de ```0.5```, o que move o eixo ```x``` do sistema de coordenadas por ```0.5```. + +Agora, tente descomentar a linha 32 - isso estica a proporção da tela do sistema de coordenadas, para imitar o aspecto de um "tijolo moderno". Comentando a linha 40, você pode ver como o sistema de coordenadas parece mapeado para o vermelho e o verde. + + +
+ +* Tente animar isso, movendo o offset de acordo com o tempo. + +* Faça outra animação onde as linhas pares se movem para a esquerda, e as ímpares para a direita. + +* Você consegue repetir esse efeito, mas com colunas? + +* Tente combinar um offset nos eixos ```x``` e ```y``` para conseguir algo desse tipo: + + + +## Tiles de Truchet + +Agora que já aprendemos como dizer se nossa célula está numa coluna par ou ímpar, é possível reusar um elemento simples dependendo de sua posição. Considere o caso dos [Truchet Tiles](http://en.wikipedia.org/wiki/Truchet_tiles) onde um elemento de design simples pode ser representado em quatro formas diferentes: + +![](truchet-00.png) + +Mudando o padrão ao longo dos tiles, é possível construir um conjunto infinito de designs complexos. + +![](truchet-01.png) + +Preste bastante atenção à função ```rotateTilePattern()```, que subdivide o espaço em quatro célular e associa uma ângulo de rotação a cada um. + +
+ +* Comente, descomente e duplique as linhas 69 a 72 para compor novos designs. + +* Mude o triângulo preto e branco por outro elemento, como: semi-círculos, quadrados rotacionados ou linhas. + +* Programe outros padrões, onde os elementos são rotacionados de acordo com a posição. + +* Faça um pattern que mude outras propriedades, de acordo com a posição dos elementos. + +* Pense em algo mais que não seja necessariamente um pattern onde você pode aplicar os princípios desta seção. (Ex: hexagramas do I Ching) + + + +## Fazendo suas próprias regras + +Fazer padrões procedurais é um exercício mentar para encontrar elementos mínimos reutilizáveis. Esta prática é antiga; como espécie, temos usando grids e padrões para decorar tecidos, pisos e bordas de objetos por muito tempo: desde os padrões de meandros na Grécia antiga, aos designs de treliças chinesas, o prazer da repetição e variações pegam nossa imaginação. Dê uma olhada em [padrões](https://www.pinterest.com/patriciogonzv/paterns/) [decorativos](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) e veja como artistas e designers têm uma longa história de navegar na fina borda entre a previsibilidade da ordem, e a surpresa da variação e o caos. Dos padrões geométricos árabes ao design de lindos tecidos africanos, há um universo inteiro de padrões de onde aprender. + +![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png) + +Com este capítulo, terminamos a seção sobre Desenho Algorítmico. Nos capítulos seguintes vamos aprender como trazer alguma entropia para nossos shaders e produzir designs generativos. + diff --git a/09/SUMMARY-pt.md b/09/SUMMARY-pt.md new file mode 100644 index 0000000..5ee1722 --- /dev/null +++ b/09/SUMMARY-pt.md @@ -0,0 +1 @@ +Padrões repetitivos são um tema perfeito para desenho computacional. Diferente do modo convencional de desenhar, shaders te deixam desenhar tudo em paralelo de uma vez. Em vez de repetir o mesmo procedimento várias vezes, você vai empacotar e repetir o "espaço". Parece sci-fi? Vamos descobrir o que isso quer dizer de verdade. \ No newline at end of file diff --git a/09/TITLE-pt.md b/09/TITLE-pt.md new file mode 100644 index 0000000..3350acc --- /dev/null +++ b/09/TITLE-pt.md @@ -0,0 +1 @@ +## Patterns (padrões) diff --git a/10/README-pt.md b/10/README-pt.md new file mode 100644 index 0000000..f39412c --- /dev/null +++ b/10/README-pt.md @@ -0,0 +1,92 @@ +# Designs Generativos + +Não é uma surpresa que, depois de tanta repetição e ordem, o autor seja forçado a trazer algum caos. + +## Aleatoriedade + +[![Ryoji Ikeda - test pattern (2008) ](ryoji-ikeda.jpg) ](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set) + +Aleatoriedade é uma expressão máxima da entropia. Como podemos gerar aleatoriedade dentro de um ambiente de código tão rídigo e, aparentemente, previsível? + +Vamos começar, analisando a seguinte função: + +
+ +Acima, estamos extraindo o conteúdo fracionário de uma onda de seno. Os valores de [```sin()```](../glossary/?search=sin) que flutuam entre ```-1.0``` e ```1.0``` foram cortados depois do ponto flutuante, retornando todos valores positivos entre ```0.0``` e ```1.0```. Podemos usar esse efeito para obter algums valores pseudo-aleatórios, quebrando essa onda de seno em pedaços menores. Como? Multiplicando o resultante de [```sin(x)```](../glossary/?search=sin) por números maiores. Vá em frente e clique na função acima e comece a adicionar alguns zeros. + +Quando você chegar lá pelo ```100000.0``` ( e a equação parecer com isso: ```y = fract(sin(x)*100000.0)``` ) você não vai mais ser capaz de distinguir a onda do seno. A granularidade da parte fracionária corrompeu o fluxo da onda em um caos pseudo-aleatório. + +## Controlando o caos + +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. + +
+ +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. + +
+ +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. + +
+ +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. + +
+ +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. + + + +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. + + + +* 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. + + + +* Create other interesting effects. + + + +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.