mirror of
https://github.com/patriciogonzalezvivo/thebookofshaders
synced 2024-11-01 21:40:27 +00:00
commit
41c8492d0f
@ -2,7 +2,7 @@
|
||||
|
||||
<canvas id="custom" class="canvas" data-fragment-url="cmyk-halftone.frag" data-textures="vangogh.jpg" width="700px" height="320px"></canvas>
|
||||
|
||||
Las imágenes que aparecen arriba fueron creadas de diferentes formas. La primera fue hecha por la mano de Van Gogh, aplicando capa por capa la pintura. Le tomó horas pintarla. La segunda fue producida en segundos mezclando cuatro matrices de pixeles: una para el cyan, otra para el magenta, otra para el amarillo y otra para el negro. La diferencia clave entre ambas es que la segunda imágen fue hecha de una manera no serializada (es decir que el proceso no fue paso a paso, sino de manera simultánea).
|
||||
Las imágenes que aparecen arriba fueron creadas de diferentes formas. La primera fue hecha por la mano de Van Gogh, aplicando capa por capa la pintura. Le tomó horas pintarla. La segunda fue producida en segundos mezclando cuatro matrices de pixeles: una para el cyan, otra para el magenta, otra para el amarillo y otra para el negro. La diferencia clave entre ambas es que la segunda imagen fue hecha de una manera no serializada (es decir que el proceso no fue paso a paso, sino de manera simultánea).
|
||||
|
||||
Este libro trata sobre una técnica computacional revolucionaria, que lleva a las imágenes generadas digitalmente a un nuevo nivel, los *fragment shaders*. Esta revolución es comparable a lo que fue en su momento la imprenta de Gutemberg para la gráfica.
|
||||
|
||||
@ -18,24 +18,24 @@ En los próximos capítulos descubrirás cuán increíblemente rápida y poderos
|
||||
|
||||
Este libro está escrito para creative coders, desarrolladores de videojuegos e ingenieros que tengan alguna experiencia con la programación, un conocimiento básico de álgebra lineal y trigonometría, y que quieran llevar su trabajo a un nuevo y emocionante nivel gráfico. (Si te interesa aprender a programar, te recomiendo comenzar con [Processing](https://processing.org/) y volver cuando te sientas cómodo).
|
||||
|
||||
Este libro te enseñará a integrar shaders en tus proyectos, mejorando la performance y la calidad gráfica. Como los shaders GLSL (OpenGL Shading Language) se pueden compilar y correr en diferentes plataformas, podrás aplicar lo que aprendas aquí en cualquier entorno que que use OpenGL, OpenGL ES o WebGL. En otras palabras podrás utilizarlo en sketches de [Processing](https://processing.org/), aplicaciones de [openFrameworks](http://openframeworks.cc/), instalaciones interactivas con [Cinder](http://libcinder.org/), incluso en web o en juegos iOS/Android con [Three.js](http://threejs.org/).
|
||||
Este libro te enseñará a integrar shaders en tus proyectos, mejorando la performance y la calidad gráfica. Como los shaders GLSL (OpenGL Shading Language) se pueden compilar y correr en diferentes plataformas, podrás aplicar lo que aprendas aquí en cualquier entorno que use OpenGL, OpenGL ES o WebGL. En otras palabras podrás utilizarlo en sketches de [Processing](https://processing.org/), aplicaciones de [openFrameworks](http://openframeworks.cc/), instalaciones interactivas con [Cinder](http://libcinder.org/), incluso en web o en juegos iOS/Android con [Three.js](http://threejs.org/).
|
||||
|
||||
|
||||
## ¿Qué temas se tratan en este libro?
|
||||
|
||||
Este libro se enfoca en el uso de los pixel shaders GLSL. Primero definiremos qué son los shaders; luego aprenderemos a crear formas procedurales, patrones, texturas y animaciones con ellos. Aprenderás los fundamentos básicos del lenguaje y cómo aplicarlos en escenarios más útiles cómo: el procesamiento de imágenes (operaciones de imágen, convoluciones de matrices, desenfocado, filtros de color, lookup tables y otros efectos) y simulaciones (El juego de la vida de Conway, la reacción-difusión de Gray-Scott, ondas de agua, efecto de acuarela, celdas de Voronoi, etc). Hacia el final del libro veremos un conjunto de técnicas avanzadas basadas en ray marching.
|
||||
Este libro se enfoca en el uso de los pixel shaders GLSL. Primero definiremos qué son los shaders; luego aprenderemos a crear formas procedurales, patrones, texturas y animaciones con ellos. Aprenderás los fundamentos básicos del lenguaje y cómo aplicarlos en escenarios más útiles cómo: el procesamiento de imágenes (operaciones de imagen, convoluciones de matrices, desenfocado, filtros de color, lookup tables y otros efectos) y simulaciones (El juego de la vida de Conway, la reacción-difusión de Gray-Scott, ondas de agua, efecto de acuarela, celdas de Voronoi, etc). Hacia el final del libro veremos un conjunto de técnicas avanzadas basadas en ray marching.
|
||||
|
||||
*Habrá ejemplos interactivos en cada uno de los capítulos para que puedas jugar con ellos.* Cuando modifiques el código, podrás ver al instante los cambios reflejados en la pantalla. Los conceptos expuestos pueden ser abstractos y confusos, por lo que los ejemplos interactivos son esenciales para comprender el material. Cuanto más rápido pongamos manos a la obra en el código, mejor lo entenderemos.
|
||||
|
||||
Que cosas no vas a encontrar en este libro:
|
||||
|
||||
* Este *no es* un libro sobre OpenGL o webGL. OpenGL/webGL son temas mucho mas grandes que GLSL o el uso fragment shaders. Si estás interesado en aprender openGL/webGL te recomiendo mirar: [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) (también conocido como el libro rojo) o [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 *no es* un libro sobre OpenGL o webGL. OpenGL/webGL son temas mucho más grandes que GLSL o el uso fragment shaders. Si estás interesado en aprender openGL/webGL te recomiendo mirar: [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) (también conocido como el libro rojo) o [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 *no es* un libro de matemáticas. A pesar de que cubriremos un número de algoritmos y técnicas que están íntimimante relacionados con el álgebra y la trigonometría, no las explicaremos en profundidad. Si tienes alguna duda con respecto a la mátemática empleada en este libro te recomiendo tener cerca alguno de estos libros: [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) o [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 *no es* un libro de matemáticas. A pesar de que cubriremos un número de algoritmos y técnicas que están íntimimante relacionados con el álgebra y la trigonometría, no las explicaremos en profundidad. Si tienes alguna duda con respecto a la matemática empleada en este libro te recomiendo tener cerca alguno de estos libros: [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) o [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).
|
||||
|
||||
## ¿Qué necesito para comenzar?
|
||||
|
||||
¡No mucho! Si tienes algún navegador que cuente con WebGL (como por ejemplo Chrome, Firefox o Safari) y una conexión a internet, solo necesitas hacer click en "Siguiente" para poder comenzar.
|
||||
¡No mucho! Si tienes algún navegador que cuente con WebGL (como por ejemplo Chrome, Firefox o Safari) y una conexión a internet, solo necesitas hacer clic en "Siguiente" para poder comenzar.
|
||||
|
||||
Alternativamente, dependiendo cuales sean tus necesidades puedes:
|
||||
|
||||
|
@ -1,47 +1,47 @@
|
||||
# Introdução
|
||||
# Introduction
|
||||
|
||||
<canvas id="custom" class="canvas" data-fragment-url="cmyk-halftone.frag" data-textures="vangogh.jpg" width="700px" height="320px"></canvas>
|
||||
|
||||
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.
|
||||
|
1
00/TITLE-pt.md
Normal file
1
00/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
# Introdução
|
@ -1,11 +1,11 @@
|
||||
# Comenzando
|
||||
## Qué es un fragment shader?
|
||||
|
||||
En el capítulo anterior comparamos a los shaders con la invención de la imprenta de Gutenberg. ¿Por qué? Y mas importante: ¿Qué es un shader?
|
||||
En el capítulo anterior comparamos a los shaders con la invención de la imprenta de Gutenberg. ¿Por qué? Y más importante: ¿Qué es un shader?
|
||||
|
||||
![From Letter-by-Letter, Right: William Blades (1891). To Page-by-page, Left: Rolt-Wheeler (1920).](print.png)
|
||||
|
||||
Si ya tienes experiencia dibujando con computadoras, sabrás que en ese proceso dibujas un círculo, luego un rectángulo, una línea, algunos triángulos, hasta que por fin compones la imágen que querías. Ese proceso es muy similar a escribir una carta o un libro a mano, es un conjunto de instrucciones, una tarea después de la otra.
|
||||
Si ya tienes experiencia dibujando con computadoras, sabrás que en ese proceso dibujas un círculo, luego un rectángulo, una línea, algunos triángulos, hasta que por fin compones la imagen que querías. Ese proceso es muy similar a escribir una carta o un libro a mano, es un conjunto de instrucciones, una tarea después de la otra.
|
||||
|
||||
Los shaders son también un conjunto de instrucciones, pero estas son ejecutadas todas al mismo tiempo por cada pixel de la pantalla. Eso significa que el código que escribes tiene que comportarse de manera diferente dependiendo de su posición en la pantalla. Como una prensa tipográfica, tu programa trabajará como una función que recibe posición y devuelve color, y que al ser compilada se ejecutará a una velocidad extraordinaria.
|
||||
|
||||
@ -15,23 +15,23 @@ Los shaders son también un conjunto de instrucciones, pero estas son ejecutadas
|
||||
|
||||
Para responder esto hay que hablar de las maravillas del *parallel processing*.
|
||||
|
||||
Imagina que tu CPU es un gran tubo industrial y que cada tarea pasa por ahi como si fuese una linea de producción. Algunas tareas son mas grandes que otras, esto quiere decir que algunas consumen mas tiempo y energía que el resto. Solemos decir que estas tareas requieren mas tiempo de proceso. Debido a la arquitectura de las computadoras estas tareas son forzadas a correr en serie; cada trabajo debe ser terminado, uno después del otro. Las computadoras modernas usualmente cuentan con un grupo de procesadores que trabajan como estos tubos, completando tareas, una después de la otra. Cada uno de estos tubos es también conocido como *thread*.
|
||||
Imagina que tu CPU es un gran tubo industrial y que cada tarea pasa por ahí como si fuese una linea de producción. Algunas tareas son más grandes que otras, esto quiere decir que algunas consumen más tiempo y energía que el resto. Solemos decir que estas tareas requieren más tiempo de proceso. Debido a la arquitectura de las computadoras estas tareas son forzadas a correr en serie; cada trabajo debe ser terminado, uno después del otro. Las computadoras modernas usualmente cuentan con un grupo de procesadores que trabajan como estos tubos, completando tareas, una después de la otra. Cada uno de estos tubos es también conocido como *thread*.
|
||||
|
||||
![CPU](00.jpeg)
|
||||
|
||||
Los videojuegos y otras aplicaciones gráficas requieren mucho mas tiempo de proceso que otros programas. Debido a su contenido gráfico es necesario hacer muchas operaciones numéricas por pixel. Cada pixel de la pantalla necesita ser computado, y en el caso de los videojuegos en 3D también hay que calcular las geometrías y las perspectivas.
|
||||
Los videojuegos y otras aplicaciones gráficas requieren mucho más tiempo de proceso que otros programas. Debido a su contenido gráfico es necesario hacer muchas operaciones numéricas por pixel. Cada pixel de la pantalla necesita ser computado, y en el caso de los videojuegos en 3D también hay que calcular las geometrías y las perspectivas.
|
||||
|
||||
Volvamos a pensar en la metáfora de los tubos y las tareas. Cada pixel de la pantalla representa una pequeña tarea a realizar. Individualmente cada tarea no es un gran problema para el CPU, pero (y aquí esta el problema) ¡Esta pequeña tarea deberá ser ejecutada por cada pixel! Eso significa que en una antigua pantalla de 800x600 pixeles ¡Tendremos que procesar 480000 pixeles por frame, es decir 14400000 cálculos por segundo! ¡Si! Ese es un problema lo suficientemente grande como para sobrecargar al microprocesador. En una pantalla retina display moderna de 2880x1800 pixeles, corriendo a 60 frames por segundo, los cálculos aumentarían a 311040000 por segundo. ¿Cómo hicieron los ingenieros gráficos para solucionar este problema?
|
||||
Volvamos a pensar en la metáfora de los tubos y las tareas. Cada pixel de la pantalla representa una pequeña tarea a realizar. Individualmente cada tarea no es un gran problema para el CPU, pero (y aquí está el problema) ¡Esta pequeña tarea deberá ser ejecutada por cada pixel! Eso significa que en una antigua pantalla de 800x600 pixeles ¡Tendremos que procesar 480000 pixeles por frame, es decir 14400000 cálculos por segundo! ¡Sí! Ese es un problema lo suficientemente grande como para sobrecargar al microprocesador. En una pantalla retina display moderna de 2880x1800 pixeles, corriendo a 60 frames por segundo, los cálculos aumentarían a 311040000 por segundo. ¿Cómo hicieron los ingenieros gráficos para solucionar este problema?
|
||||
|
||||
![](03.jpeg)
|
||||
|
||||
Aquí es donde procesar en paralelo se vuelve una buena solución. En vez de tener un par de procesadores grandes y poderosos, o *tubos*, es mucho mas inteligente tener muchos pequeños procesadores funcionando en paralelo al mismo tiempo. Eso es la GPU (Graphic Processor Unit).
|
||||
Aquí es donde procesar en paralelo se vuelve una buena solución. En vez de tener un par de procesadores grandes y poderosos, o *tubos*, es mucho más inteligente tener muchos pequeños procesadores funcionando en paralelo al mismo tiempo. Eso es la GPU (Graphic Processor Unit).
|
||||
|
||||
![GPU](04.jpeg)
|
||||
|
||||
Imagina que los pequeños procesadores conforman una mesa de tuberías, y que la información de cada pixel es una pelota de ping pong. 14400000 pelotas de ping pong en un segundo pueden obstruir a cualquier tubería, pero si en cambio es una mesa de 800x600 tuberías y recibe 30 olas de 480000 pixeles por segundo, se puede manejar de una manera fluída sin problemas. Esto funciona de la misma manera con resoluciones mas grandes, cuanto mas hardware en paralelo tengas, es mayor el flujo de pixeles que se puede manejar.
|
||||
Imagina que los pequeños procesadores conforman una mesa de tuberías, y que la información de cada pixel es una pelota de ping pong. 14400000 pelotas de ping pong en un segundo pueden obstruir a cualquier tubería, pero si en cambio es una mesa de 800x600 tuberías y recibe 30 olas de 480000 pixeles por segundo, se puede manejar de una manera fluída sin problemas. Esto funciona de la misma manera con resoluciones más grandes, cuanto más hardware en paralelo tengas, es mayor el flujo de pixeles que se puede manejar.
|
||||
|
||||
Otro "superpoder" de la GPU es que algunas funciones matemáticas especiales son aceleradas via hardware, la matemática mas compleja es solucionada directamente en el microchip en vez resolverlo en el software. Eso signfica que tendremos una velocidad extra en cálculos trigonométricos u operaciones de matrices que iran tan rápido como la electricidad.
|
||||
Otro "superpoder" de la GPU es que algunas funciones matemáticas especiales son aceleradas vía hardware, la matemática más compleja es solucionada directamente en el microchip en vez resolverlo en el software. Eso signfica que tendremos una velocidad extra en cálculos trigonométricos u operaciones de matrices que irán tan rápido como la electricidad.
|
||||
|
||||
## ¿Qué es GLSL?
|
||||
|
||||
@ -43,6 +43,6 @@ Como dijo el tio Ben "un gran poder conlleva una gran responsabilidad", y la com
|
||||
|
||||
Para que cada tubo, o thread, pueda correr en paralelo es necesario que cada uno sea independiente del otro. Es decir que los threads son *ciegos* y no saben lo que los demás threads están haciendo. Esta restricción implica que toda la información debe fluir en la misma dirección, por lo tanto es imposible conocer el resultado de otro thread. Permitir la comunicación entre threads pondría en riesgo la integridad de los datos.
|
||||
|
||||
Además la GPU deja constantemente ocupados a los micro-procesadores (los tubos); tan pronto como terminan una tarea reciben nueva información para procesar. Es imposible para cada thread saber lo que estaba haciendo en el momento previo. Se podría dibujar un botón de una UI de un sistema operativo, luego renderizar una porción del cielo de un videojuego, y a continuación mostrar el texto de un mail. Cada thread no solamente es **ciego** sino que **tampoco tiene memoria**. Mas alla de la abstracción necesaria para poder crear una función que cambie de resultado pixel a pixel, dependiendo de su posición, la incapacidad de ver a los demás threads y la falta de memoria, hacen que los shaders no sean muy populares entre los programadores principiantes.
|
||||
Además la GPU deja constantemente ocupados a los micro-procesadores (los tubos); tan pronto como terminan una tarea reciben nueva información para procesar. Es imposible para cada thread saber lo que estaba haciendo en el momento previo. Se podría dibujar un botón de una UI de un sistema operativo, luego renderizar una porción del cielo de un videojuego, y a continuación mostrar el texto de un mail. Cada thread no solamente es **ciego** sino que **tampoco tiene memoria**. Más allá de la abstracción necesaria para poder crear una función que cambie de resultado pixel a pixel, dependiendo de su posición, la incapacidad de ver a los demás threads y la falta de memoria, hacen que los shaders no sean muy populares entre los programadores principiantes.
|
||||
|
||||
¡No te preocupues! En los próximos capítulos aprenderemos paso a paso, desde los shaders mas sencillos a los casos mas avanzados. Si estás leyendo esto desde un navegador moderno, vas a poder jugar con los ejemplos interactivos. No esperes mas y presiona *Siguiente >>* para ir al próximo capítulo.
|
||||
¡No te preocupues! En los próximos capítulos aprenderemos paso a paso, desde los shaders más sencillos a los casos más avanzados. Si estás leyendo esto desde un navegador moderno, vas a poder jugar con los ejemplos interactivos. No esperes más y presiona *Siguiente >>* para ir al próximo capítulo.
|
||||
|
@ -25,7 +25,7 @@ Imaginez le CPU de votre ordinateur comme un *tuyau* et chacune des opérations
|
||||
![CPU](00.jpeg)
|
||||
|
||||
Les jeux vidéos et autres applications graphiques demandent beaucoup plus de puissance de calcul que les autres programmes.
|
||||
Par nature, ils demandent de grandes quantités d'opérations au pixel, chaque changement d'image demande de recalculer l'ensemble des pixels de l'écran. Dans les applications 3D, on doit également mettre à jour les modèles, les textures, les transformations etc... ce qui rajoute encore plus de charge au CPU.
|
||||
Par nature, ils demandent de grandes quantités d'opérations au pixel, chaque changement d'image demande de recalculer l'ensemble des pixels de l'écran. Dans les applications 3D, on doit également mettre à jour les modèles, les textures, les transformations etc. ce qui rajoute encore plus de charge au CPU.
|
||||
|
||||
Revenons à notre métaphore des tuyaux et des opérations. Chaque pixel à l'écran représente une simple petite opération. En soi, chaque le traitement d'une opération n'est pas un problème pour le CPU, mais (et c'est ici que se trouve le problème) il faut appliquer cette petite opération sur chaque pixel à l'écran ! Par exemple, sur un vieux moniteur ayant une résolution de 800x600, 480 000 pixels ont besoin d'être traités par *frame* ce qui équivaut à 14 600 000 calculs par seconde ! C’est une opération assez importante pour surcharger un microprocesseur. Sur un écran rétina moderne ayant une résolution de 2880x1800 cadencé à 60 *frames* par seconde, cela représente un total de 311 040 000 calculs par seconde. Comment les ingénieurs graphiques résolvent-ils ce problème?
|
||||
|
||||
|
@ -15,7 +15,7 @@ Shaders are also a set of instructions, but the instructions are executed all at
|
||||
|
||||
To answer this, I present the wonders of *parallel processing*.
|
||||
|
||||
Imagine the CPU of your computer as a big industrial pipe, and every task as something that passes through it - like a factory line. Some tasks are bigger than others, which means they require more time and energy to deal with. We say they require more processing power. Because of the architecture of computers the jobs are forced to run in a series; each job has to be finished one at a time. Modern computers usually have groups of four processors that work like these pipes, completing tasks one after another to keeping things running smoothly. Each pipe is also known as a *thread*.
|
||||
Imagine the CPU of your computer as a big industrial pipe, and every task as something that passes through it - like a factory line. Some tasks are bigger than others, which means they require more time and energy to deal with. We say they require more processing power. Because of the architecture of computers the jobs are forced to run in a series; each job has to be finished one at a time. Modern computers usually have groups of four processors that work like these pipes, completing tasks one after another to keep things running smoothly. Each pipe is also known as a *thread*.
|
||||
|
||||
![CPU](00.jpeg)
|
||||
|
||||
|
2
01/TITLE-pt.md
Normal file
2
01/TITLE-pt.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Começando
|
||||
## O que é um shader?
|
@ -6,7 +6,7 @@ En el mundo de las GPU renderizar texto es una tarea complicada para ser el prim
|
||||
|
||||
<div class="codeAndCanvas" data="hello_world.frag"></div>
|
||||
|
||||
Si estás leyendo este libro en un navegador, el código anterior es interactivo, eso significa que puedes hacer click y cambiar cualquier línea de código para explorar cómo funciona. Los cambios se reflejaran automáticamente gracias a que la arquitectura de la GPU se encarga de compilar y reemplazar los shaders al instante. Intenta modificar el contenido de la línea 6.
|
||||
Si estás leyendo este libro en un navegador, el código anterior es interactivo, eso significa que puedes hacer clic y cambiar cualquier línea de código para explorar cómo funciona. Los cambios se reflejaran automáticamente gracias a que la arquitectura de la GPU se encarga de compilar y reemplazar los shaders al instante. Intenta modificar el contenido de la línea 6.
|
||||
|
||||
Aunque estas simples líneas de código no parezcan mucho, podemos inferir mucha información importante de ellas:
|
||||
|
||||
@ -14,15 +14,15 @@ Aunque estas simples líneas de código no parezcan mucho, podemos inferir mucha
|
||||
|
||||
2. El color final del pixel es guardado en la variable global reservada ```gl_FragColor```.
|
||||
|
||||
3. Este lenguaje similar a C tiene *variables* reservadas (como ```gl_FragColor```), *funciones* y *tipos de variables*. En este caso vemos que existe ```vec4``` que es un tipo de variable de 4 dimensiones de punto flotante. Mas adelante veremos otros tipos de variables como ```vec3``` y ```vec2``` junto con las populares: ```float```, ```int``` y ```bool```.
|
||||
3. Este lenguaje similar a C tiene *variables* reservadas (como ```gl_FragColor```), *funciones* y *tipos de variables*. En este caso vemos que existe ```vec4``` que es un tipo de variable de 4 dimensiones de punto flotante. Más adelante veremos otros tipos de variables como ```vec3``` y ```vec2``` junto con las populares: ```float```, ```int``` y ```bool```.
|
||||
|
||||
4. Si miramos detenidamente el ```vec4``` podemos inferir que los cuatro argumentos pasados son el canal RED (rojo), el canal GREEN (verde), el canal BLUE (azul) y el canal ALPHA (transparencia). Además podemos ver que los valores se encuentran *normalizados*, eso significa que van desde ```0.0``` a ```1.0```. Mas adelante aprenderemos que normalizar valores vuelve mucho mas fácil nuestro trabajo con las variables.
|
||||
4. Si miramos detenidamente el ```vec4``` podemos inferir que los cuatro argumentos pasados son el canal RED (rojo), el canal GREEN (verde), el canal BLUE (azul) y el canal ALPHA (transparencia). Además podemos ver que los valores se encuentran *normalizados*, eso significa que van desde ```0.0``` a ```1.0```. Más adelante aprenderemos que normalizar valores vuelve mucho más fácil nuestro trabajo con las variables.
|
||||
|
||||
5. Otra *función de C* que vemos en el ejemplo son los macros al preprocesador. Los macros son parte del proceso de precompilado. Con ellos es posible definir variables globales (con ```#define```) y hacer operaciones condicionales básicas ( con ```#ifdef``` y ```#endif```). Todos los comandos macro comienzan con un numeral (```#```). La pre-compilación sucede en el momento previo a la compilación y chequea todos los ```#defines```, y los condicionales ```#ifdef``` (esta definido) y ```#ifndef``` (no esta definido). En nuestro ejemplo, el "Hola mundo", solamente insertamos la segunda línea de código si ```GL_ES``` esta definida, que la mayoría de las veces se encuentra definida cuando el código es compilado en mobile o en navegadores.
|
||||
5. Otra *función de C* que vemos en el ejemplo son los macros al preprocesador. Los macros son parte del proceso de precompilado. Con ellos es posible definir variables globales (con ```#define```) y hacer operaciones condicionales básicas ( con ```#ifdef``` y ```#endif```). Todos los comandos macro comienzan con un numeral (```#```). La pre-compilación sucede en el momento previo a la compilación y chequea todos los ```#defines```, y los condicionales ```#ifdef``` (está definido) y ```#ifndef``` (no está definido). En nuestro ejemplo, el "Hola mundo", solamente insertamos la segunda línea de código si ```GL_ES``` está definida, que la mayoría de las veces se encuentra definida cuando el código es compilado en mobile o en navegadores.
|
||||
|
||||
6. Los valores flotantes son vitales en los shaders, ya que el nivel de *precisión* es crucial. A menor precisión mayor velocidad de render, pero peor calidad. Podemos ser meticulosos y especificar la precisión de cada variable que use punto flotante. En la primera línea (```precision mediump float;```) estamos ajustando todos los valores flotantes a una precisión media. Pero podríamos configurarlos en low (```precision lowp float;```) o high (```precision highp float;```).
|
||||
|
||||
7. El último detalle, y quizá el mas importante, es que las especificaciones de GLSL no garantizan que las variables sean automáticamente convertidas. ¿Qué significa eso? Los manufacturadores de GPU tienen diferentes estrategias para acelerar los gráficos pero están forzados a entregar especificaciones mínimas, por lo que la conversión automática de variables no es algo importante. Si queremos que nuestro código sea consistente y no pasar horas depurando pantallas blancas, tenemos que acostumbrarnos a usar el punto ( ```.``` ) en los flotantes. Este código no siempre funcionará:
|
||||
7. El último detalle, y quizá el más importante, es que las especificaciones de GLSL no garantizan que las variables sean automáticamente convertidas. ¿Qué significa eso? Los manufacturadores de GPU tienen diferentes estrategias para acelerar los gráficos pero están forzados a entregar especificaciones mínimas, por lo que la conversión automática de variables no es algo importante. Si queremos que nuestro código sea consistente y no pasar horas depurando pantallas blancas, tenemos que acostumbrarnos a usar el punto ( ```.``` ) en los flotantes. Este código no siempre funcionará:
|
||||
|
||||
```glsl
|
||||
void main() {
|
||||
@ -30,13 +30,13 @@ void main() {
|
||||
}
|
||||
```
|
||||
|
||||
Ahora que ya describimos los elementos mas importantes de nuestro "Hola mundo", es hora de hacer click en el código y poner en práctica nuestros conocimientos aprendidos. Notarás que cuando hay errores, el programa no compilará, y mostrará una pantalla blanca. Aqui hay algunas cosas interesantes que puedes probar, por ejemplo:
|
||||
Ahora que ya describimos los elementos más importantes de nuestro "Hola mundo", es hora de hacer clic en el código y poner en práctica nuestros conocimientos aprendidos. Notarás que cuando hay errores, el programa no compilará, y mostrará una pantalla blanca. Aqui hay algunas cosas interesantes que puedes probar, por ejemplo:
|
||||
|
||||
* Intenta modificar los flotantes y poner enteros, es posible que tu placa de video no tolere esto.
|
||||
|
||||
* Prueba comentar la línea 6 y no asignar ningún valor a la función.
|
||||
|
||||
* Intenta crear una función separada que devuelva un color específico y usalo dentro del ```main()```. Una pista, aqui esta el código que usaríamos para devolver el color rojo:
|
||||
* Intenta crear una función separada que devuelva un color específico y usalo dentro del ```main()```. Una pista, aqui está el código que usaríamos para devolver el color rojo:
|
||||
|
||||
```glsl
|
||||
vec4 red(){
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<div class="codeAndCanvas" data="hello_world.frag"></div>
|
||||
|
||||
С кодом выше можно взаимодействовать, если вы читаете книгу в браузере. Это означает, что вы можете изменить любую часть кода по вашему желанию. Благодаря архитектуре GPU, которая компилирует и запускает шейдеры *на лету*, вы увидите изменения незамедлительно. Попробуйте изменить значения в строке 6.
|
||||
С кодом выше можно взаимодействовать, если вы читаете книгу в браузере. Это означает, что вы можете изменить любую часть кода по вашему желанию. Благодаря архитектуре GPU, которая компилирует и запускает шейдеры *на лету*, вы увидите изменения незамедлительно. Попробуйте изменить значения в строке 8.
|
||||
|
||||
Эти несколько строчек кода не похожи на нормальную, зрелую программу, но мы можем извлечь из них кое-какие знания:
|
||||
|
||||
|
@ -18,7 +18,7 @@ Although these simple lines of code don't look like a lot, we can infer substant
|
||||
|
||||
4. If we look closely to the `vec4` type we can infer that the four arguments respond to the RED, GREEN, BLUE and ALPHA channels. Also we can see that these values are *normalized*, which means they go from `0.0` to `1.0`. Later, we will learn how normalizing values makes it easier to *map* values between variables.
|
||||
|
||||
5. Another important *C feature* we can see in this example is the presence of preprocessor macros. Macros are part of a pre-compilation step. With them it is possible to `#define` global variables and do some basic conditional operation (with `#ifdef` and `#endif`). All the macro comands begin with a hashtag (`#`). Pre-compilation happens right before compiling and copies all the calls to `#defines` and check `#ifdef` (is defined) and `#ifndef` (is not defined) conditionals. In our "hello world!" example above, we only insert the line 2 if `GL_ES` is defined, which mostly happens when the code is compiled on mobile devices and browsers.
|
||||
5. Another important *C feature* we can see in this example is the presence of preprocessor macros. Macros are part of a pre-compilation step. With them it is possible to `#define` global variables and do some basic conditional operation (with `#ifdef` and `#endif`). All the macro comands begin with a hashtag (`#`). Pre-compilation happens right before compiling and copies all the calls to `#define` and checks `#ifdef` (is defined) and `#ifndef` (is not defined) conditionals. In our "hello world!" example above, we only insert the line 2 if `GL_ES` is defined, which mostly happens when the code is compiled on mobile devices and browsers.
|
||||
|
||||
6. Float types are vital in shaders, so the level of *precision* is crucial. Lower precision means faster rendering, but at the cost of quality. You can be picky and specify the precision of each variable that uses floating point. In the first line (`precision mediump float;`) we are setting all floats to medium precision. But we can choose to set them to low (`precision lowp float;`) or high (`precision highp float;`).
|
||||
|
||||
|
@ -14,7 +14,7 @@ uniform vec2 u_mouse; // mouse position in screen pixels
|
||||
uniform float u_time; // Time in seconds since load
|
||||
```
|
||||
|
||||
Podemos imaginar que los uniforms son como pequeños puentes entre la CPU y la GPU. Los nombres varían dependiendo de cada implementación, en esta serie de ejemplos estoy usando ```u_time``` (tiempo en segundos desde que shaders comenzó a correr), ```u_resolution``` (el tamaño de la ventana donde se esta dibujando el shader) y ```u_mouse``` (la posición del mouse dentro de la ventana en pixeles). Estoy siguiendo la convención de utilizar ```u_``` antes del nombre del uniform, para ser explícito respecto a la naturaleza de la variable, pero encontrarás diferentes nombre de uniforms. Por ejemplo [ShaderToy.com](https://www.shadertoy.com/) utiliza las mismas uniforms pero con los siguientes nombres:
|
||||
Podemos imaginar que los uniforms son como pequeños puentes entre la CPU y la GPU. Los nombres varían dependiendo de cada implementación, en esta serie de ejemplos estoy usando ```u_time``` (tiempo en segundos desde que shaders comenzó a correr), ```u_resolution``` (el tamaño de la ventana donde se está dibujando el shader) y ```u_mouse``` (la posición del mouse dentro de la ventana en pixeles). Estoy siguiendo la convención de utilizar ```u_``` antes del nombre del uniform, para ser explícito respecto a la naturaleza de la variable, pero encontrarás diferentes nombre de uniforms. Por ejemplo [ShaderToy.com](https://www.shadertoy.com/) utiliza las mismas uniforms pero con los siguientes nombres:
|
||||
|
||||
```glsl
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
@ -26,7 +26,7 @@ Ya hemos hablado mucho, vamos a ver los uniforms en acción. En el código sigui
|
||||
|
||||
<div class="codeAndCanvas" data="time.frag"></div>
|
||||
|
||||
Como puedes ver, GLSL tiene mas sorpresas. La GPU tiene funciones de ángulo, de trigonometría y exponenciales, que son aceleradas por hardware: [```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) y [```clamp()```](../glossary/?search=clamp).
|
||||
Como puedes ver, GLSL tiene más sorpresas. La GPU tiene funciones de ángulo, de trigonometría y exponenciales, que son aceleradas por hardware: [```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) y [```clamp()```](../glossary/?search=clamp).
|
||||
|
||||
Es hora de jugar con el código de arriba:
|
||||
|
||||
@ -38,13 +38,14 @@ Es hora de jugar con el código de arriba:
|
||||
|
||||
## gl_FragCoord
|
||||
|
||||
De la misma forma que GLSL nos da por default la variable reservada ```vec4 gl_FragColor```, también nos da ```vec4 gl_FragCoord``` que guarda la coordenada del *pixel* o *screen fragment* del thread actual. Con ```vec4 gl_FragCoord``` podemos saber el lugar en la pantalla en el que el thread esta actualmente trabajando. En este caso esta variable no es un ```uniform``` porque será diferente en cada uno de los threads, las variables que cambian en cada thread, como ```gl_FragCoord```, son *varying*.
|
||||
|
||||
De la misma forma que GLSL nos da por default la variable reservada ```vec4 gl_FragColor```, también nos da ```vec4 gl_FragCoord``` que guarda la coordenada del *pixel* o *screen fragment* del thread actual. Con ```vec4 gl_FragCoord``` podemos saber el lugar en la pantalla en el que el thread está actualmente trabajando. En este caso, esta variable no es un ```uniform``` porque será diferente en cada uno de los threads, las variables que cambian en cada thread, como ```gl_FragCoord```, son *varying*.
|
||||
```
|
||||
<div class="codeAndCanvas" data="space.frag"></div>
|
||||
```
|
||||
|
||||
En el código de arriba *normalizamos* la coordenada del fragment, dividiéndolo por la resolución total de la ventana. Una vez que hicimos este proceso, la posición va de 0.0 a 1.0, lo que vuelve mucho más fácil de usar estos valores en los canales RED (rojo) y GREEN (verde).
|
||||
|
||||
En el mundo de los shaders no tenemos muchas herramientas para hacer debug mas allá de asignar colores e intentar encontrarles el sentido. Muchas veces verás que programar en GLSL es como poner barcos dentro de botellas, cuanto más complicado, mas hermoso y gratificante es.
|
||||
En el mundo de los shaders no tenemos muchas herramientas para hacer debug más allá de asignar colores e intentar encontrarles el sentido. Muchas veces verás que programar en GLSL es como poner barcos dentro de botellas, cuanto más complicado, más hermoso y gratificante es.
|
||||
|
||||
![](08.png)
|
||||
|
||||
@ -58,4 +59,4 @@ Es hora de poner en práctica los conocimientos aprendidos.
|
||||
|
||||
* ¿Te imaginas alguna forma interesante de combinar ```u_time``` y ```u_mouse``` para generar patrones ?
|
||||
|
||||
Luego de hacer estos ejercicios seguramente te preguntarás que mas puedes hacer con los superpoderes que los shaders te dan. En el próximo capítulo veremos como crear tus propios shaders en three.js, Processing y openFrameworks.
|
||||
Luego de hacer estos ejercicios seguramente te preguntarás que más puedes hacer con los superpoderes que los shaders te dan. En el próximo capítulo veremos como crear tus propios shaders en three.js, Processing y openFrameworks.
|
||||
|
@ -67,7 +67,7 @@ Cette variable n'est pas une *uniform* puisqu'elle ne conserve pas la même vale
|
||||
La variable `gl_FragCoord` s'appelle *varying* puisqu'elle va *varier* d'un thread sur l'autre, c'est la seconde _famille_ de variables qu'on peut utiliser dans un shader.
|
||||
Cette variable est déclarée *implicitement* dans les _vertex-shader_ et passée systématiquement à notre *fragment-shader*, autrement dit, elle est toujours là mais inutile de la chercher dans le code ci dessous.
|
||||
|
||||
Deuxième chose importante, `gl_FragColor`, `gl_FragCoord` et tous les noms de fonctions (`sin()`, `abs()`, etc...) sont des noms réservés ; on ne peut pas s'en servir pour créer nos variables.
|
||||
Deuxième chose importante, `gl_FragColor`, `gl_FragCoord` et tous les noms de fonctions (`sin()`, `abs()`, etc.) sont des noms réservés ; on ne peut pas s'en servir pour créer nos variables.
|
||||
|
||||
<div class="codeAndCanvas" data="space.frag"></div>
|
||||
|
||||
|
7
03/SUMMARY-pt.md
Normal file
7
03/SUMMARY-pt.md
Normal file
@ -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
|
||||
```
|
@ -1,6 +1,6 @@
|
||||
## Ejecutando tu shader
|
||||
|
||||
En este punto seguro estás entusiasmado con poder probar shaders en las plataformas en las que te sientes cómodo. En los siguientes ejemplos veremos como agregarlos el algunos frameworks populares con las mismas uniforms con las que estamos trabajando en este libro. (En el [repositorio de GitHub de este capítulo](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04) encontrarás el código completo de estos ejemplos.)
|
||||
En este punto seguro estás entusiasmado con poder probar shaders en las plataformas en las que te sientes cómodo. En los siguientes ejemplos veremos como agregarlos en algunos frameworks populares con las mismas uniforms con las que estamos trabajando en este libro. (En el [repositorio de GitHub de este capítulo](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04) encontrarás el código completo de estos ejemplos.)
|
||||
|
||||
**Nota 1**: En caso de que no quieras utilizar los shaders en los siguientes frameworks pero quieras hacerlo fuera del navegador, puedes descargar y compilar [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Este programa corre en MacOS y en Raspberry Pi, permite ejecutar directamente los ejemplos desde la terminal.
|
||||
|
||||
@ -10,7 +10,7 @@ En este punto seguro estás entusiasmado con poder probar shaders en las platafo
|
||||
|
||||
El brillante y humilde Ricardo Cabello (también conocido como [MrDoob](https://twitter.com/mrdoob)) ha estado desarrollando junto con otros [contribuidores](https://github.com/mrdoob/three.js/graphs/contributors) probablemente el framework más conocido de WebGL, llamado [Three.js](http://threejs.org/). Encontrarás muchos ejemplos, libros y tutoriales para aprender a hacer cosas geniales en 3D con JavaScript.
|
||||
|
||||
Aqui abajo hay un ejemplo del HTML y JS necesario para poder empezar a utilizar shaders con three.js. Presta atención al script```id="fragmentShader"```, aqui es donde puedes copiar los ejemplos de este libro.
|
||||
Aqui abajo hay un ejemplo del HTML y JS necesario para poder empezar a utilizar shaders con three.js. Presta atención al script```id="fragmentShader"```, aquí es donde puedes copiar los ejemplos de este libro.
|
||||
|
||||
```html
|
||||
<body>
|
||||
@ -98,7 +98,7 @@ Aqui abajo hay un ejemplo del HTML y JS necesario para poder empezar a utilizar
|
||||
|
||||
### En **Processing**
|
||||
|
||||
Iniciado por [Ben Fry](http://benfry.com/) y [Casey Reas](http://reas.com/) en 2001, [Processing](https://processing.org/) es un extraordinario y poderoso entorno en el que se puede aprender los primeros pasos con el código (al menos así fue para mí). [Andres Colubri](https://codeanticode.wordpress.com/) ha hecho importantes cambios a la parte de OpenGL y video, logrando que sea más fácil y amigable utilizar shaders GLSL. Processing buscará el archivo ```"shader.frag"``` en la carpeta ```data``` del sketch. En ese archivo debes poner los ejemplos que encuentres en este libro.
|
||||
Iniciado por [Ben Fry](http://benfry.com/) y [Casey Reas](http://reas.com/) en 2001, [Processing](https://processing.org/) es un extraordinario y poderoso entorno en el que se puede aprender los primeros pasos con el código (al menos así fue para mí). [Andrés Colubri](https://codeanticode.wordpress.com/) ha hecho importantes cambios a la parte de OpenGL y video, logrando que sea más fácil y amigable utilizar shaders GLSL. Processing buscará el archivo ```"shader.frag"``` en la carpeta ```data``` del sketch. En ese archivo debes poner los ejemplos que encuentres en este libro.
|
||||
|
||||
```processing
|
||||
PShader shader;
|
||||
@ -141,7 +141,7 @@ Para más información sobre shaders en processing puedes chequear este [tutoria
|
||||
|
||||
### En **openFrameworks**
|
||||
|
||||
Todos tienen un lugar en el que se sienten mas cómodos, en mi caso, todavía sigue siendo [openFrameworks](http://openframeworks.cc/). Este framework en C++ engloba openGL y otras librerías open source. En muchos puntos es muy parecido a Processing, pero con las complicaciones obvias de trabajar con los compiladores de C++. De la misma forma que Processing, openFrameworks buscará tus shaders en archivos de la carpeta data, no te olvides de copiar los archivos ```.frag``` que quieres usar y cambiar el nombre cuando los cargas.
|
||||
Todos tienen un lugar en el que se sienten más cómodos, en mi caso, todavía sigue siendo [openFrameworks](http://openframeworks.cc/). Este framework en C++ engloba openGL y otras librerías open source. En muchos puntos es muy parecido a Processing, pero con las complicaciones obvias de trabajar con los compiladores de C++. De la misma forma que Processing, openFrameworks buscará tus shaders en archivos de la carpeta data, no te olvides de copiar los archivos ```.frag``` que quieres usar y cambiar el nombre cuando los cargas.
|
||||
|
||||
```cpp
|
||||
void ofApp::draw(){
|
||||
@ -156,4 +156,4 @@ void ofApp::draw(){
|
||||
}
|
||||
```
|
||||
|
||||
Para mas información sobre shaders en openFrameworks ve a este [excelente tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) creado por [Joshua Noble](http://thefactoryfactory.com/).
|
||||
Para más información sobre shaders en openFrameworks ve a este [excelente tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) creado por [Joshua Noble](http://thefactoryfactory.com/).
|
||||
|
190
04/README-pt.md
Normal file
190
04/README-pt.md
Normal file
@ -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
|
||||
<canvas class="glslCanvas" data-fragment-url=“yourShader.frag" data-textures=“yourInputImage.png” width="500" height="500"></canvas>
|
||||
```
|
||||
|
||||
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
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="js/three.min.js"></script>
|
||||
<script id="vertexShader" type="x-shader/x-vertex">
|
||||
void main() {
|
||||
gl_Position = vec4( position, 1.0 );
|
||||
}
|
||||
</script>
|
||||
<script id="fragmentShader" type="x-shader/x-fragment">
|
||||
uniform vec2 u_resolution;
|
||||
uniform float u_time;
|
||||
|
||||
void main() {
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
gl_FragColor=vec4(st.x,st.y,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
var container;
|
||||
var camera, scene, renderer;
|
||||
var uniforms;
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
container = document.getElementById( 'container' );
|
||||
|
||||
camera = new THREE.Camera();
|
||||
camera.position.z = 1;
|
||||
|
||||
scene = new THREE.Scene();
|
||||
|
||||
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
|
||||
|
||||
uniforms = {
|
||||
u_time: { type: "f", value: 1.0 },
|
||||
u_resolution: { type: "v2", value: new THREE.Vector2() },
|
||||
u_mouse: { type: "v2", value: new THREE.Vector2() }
|
||||
};
|
||||
|
||||
var material = new THREE.ShaderMaterial( {
|
||||
uniforms: uniforms,
|
||||
vertexShader: document.getElementById( 'vertexShader' ).textContent,
|
||||
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
|
||||
} );
|
||||
|
||||
var mesh = new THREE.Mesh( geometry, material );
|
||||
scene.add( mesh );
|
||||
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
|
||||
container.appendChild( renderer.domElement );
|
||||
|
||||
onWindowResize();
|
||||
window.addEventListener( 'resize', onWindowResize, false );
|
||||
|
||||
document.onmousemove = function(e){
|
||||
uniforms.u_mouse.value.x = e.pageX
|
||||
uniforms.u_mouse.value.y = e.pageY
|
||||
}
|
||||
}
|
||||
|
||||
function onWindowResize( event ) {
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
uniforms.u_resolution.value.x = renderer.domElement.width;
|
||||
uniforms.u_resolution.value.y = renderer.domElement.height;
|
||||
}
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame( animate );
|
||||
render();
|
||||
}
|
||||
|
||||
function render() {
|
||||
uniforms.u_time.value += 0.05;
|
||||
renderer.render( scene, camera );
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
|
||||
### 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/).
|
53
04/README.md
53
04/README.md
@ -1,6 +1,8 @@
|
||||
## Running your shader
|
||||
|
||||
As part of the construction of this book and my art practice I made an ecosystem of tools to create, display, share and curate shaders. These tools work consistently across Linux Desktops, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) and browsers without the need of changing your code.
|
||||
As part of the construction of this book and my art practice I made an ecosystem of tools to create, display, share and curate shaders. These tools work consistently across Linux, MacOS, Windows and [Raspberry Pi](https://www.raspberrypi.org/) and browsers without the need of changing your code.
|
||||
|
||||
## Running your shaders on the browser
|
||||
|
||||
**Display**: all live examples in this book are displayed using [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) which makes the process of running standalone shader incredible easy.
|
||||
|
||||
@ -10,7 +12,7 @@ As part of the construction of this book and my art practice I made an ecosystem
|
||||
|
||||
As you can see, it just needs a `canvas` element with `class="glslCanvas"` and the url to your shader in the `data-fragment-url`. Learn more about it [here](https://github.com/patriciogonzalezvivo/glslCanvas).
|
||||
|
||||
If you are like me, you will probably want to run shaders directly from the console, in that case you should check out [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). This application allows you to incorporate shaders into your `bash` scripts or unix pipelines and use it in a similar way that [ImageMagick](http://www.imagemagick.org/script/index.php). Also [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) is a great way to compile shaders on your [Raspberry Pi](https://www.raspberrypi.org/), reason why [openFrame.io](http://openframe.io/) use it to display shader artwork. Learn more about this application [here](https://github.com/patriciogonzalezvivo/glslViewer).
|
||||
If you are like me, you will probably want to run shaders directly from the console, in that case you should check out [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). This application allows you to incorporate shaders into your `bash` scripts or unix pipelines and use it in a similar way to [ImageMagick](http://www.imagemagick.org/script/index.php). Also [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) is a great way to compile shaders on your [Raspberry Pi](https://www.raspberrypi.org/), reason why [openFrame.io](http://openframe.io/) uses it to display shader artwork. Learn more about this application [here](https://github.com/patriciogonzalezvivo/glslViewer).
|
||||
|
||||
```bash
|
||||
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png
|
||||
@ -24,17 +26,17 @@ If you prefer to work offline using [SublimeText](https://www.sublimetext.com/)
|
||||
|
||||
![](glslViewer.gif)
|
||||
|
||||
**Share**: the online editor ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) can share your shaders! Both the embedded and standalone version have an export button where you can get an unique URL's to your shader. Also have the ability to export directly to an [openFrame.io](http://openframe.io/).
|
||||
**Share**: the online editor ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) can share your shaders! Both the embedded and standalone version have an export button where you can get an unique URL's to your shader. Also it has the ability to export directly to an [openFrame.io](http://openframe.io/).
|
||||
|
||||
![](glslEditor-00.gif)
|
||||
|
||||
**Curate**: Sharing your code is the beginning of you sharing your shader as artwork! Beside the option to export to [openFrame.io](http://openframe.io/) I made a tool to curate your shaders into a gallery that can be embebed on any site, it’s name is [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Learn more [here](https://github.com/patriciogonzalezvivo/glslGallery).
|
||||
**Curate**: Sharing your code is the beginning of you sharing your shader as artwork! Beside the option to export to [openFrame.io](http://openframe.io/) I made a tool to curate your shaders into a gallery that can be embedded on any site, it’s name is [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Learn more [here](https://github.com/patriciogonzalezvivo/glslGallery).
|
||||
|
||||
![](glslGallery.gif)
|
||||
|
||||
## Running your shaders on your favorite framework
|
||||
|
||||
In case you already have experience programming in a framework like: [Processing](https://processing.org/), [Three.js](http://threejs.org/) or [OpenFrameworks](http://openframeworks.cc/), you're probably excited to try shaders on this platforms you feel comfortable with. The following are examples of how to set shaders in some popular frameworks with the same uniforms that we are going to use throughout this book. (In the [GitHub repository for this chapter](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), you'll find the full source code for these three frameworks.)
|
||||
In case you already have experience programming in a framework like: [Processing](https://processing.org/), [Three.js](http://threejs.org/) or [OpenFrameworks](http://openframeworks.cc/), you're probably excited to try shaders on these platforms you feel comfortable with. The following are examples of how to set shaders in some popular frameworks with the same uniforms that we are going to use throughout this book. (In the [GitHub repository for this chapter](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), you'll find the full source code for these three frameworks.)
|
||||
|
||||
### In **Three.js**
|
||||
|
||||
@ -187,4 +189,45 @@ void ofApp::draw(){
|
||||
}
|
||||
```
|
||||
|
||||
If you want to use the full set of uniforms contain on the specs of GlslViewer and GlslCanvas in a more simple way on OpenFrameworks I recomend using the [ofxShader](https://github.com/patriciogonzalezvivo/ofxshader) addon which will also have support for multiple buffers, material shaders, hotreload and automatic conversion for OpenGL ES in the Raspberry Pi. And your code will be as simple as doing
|
||||
|
||||
```cpp
|
||||
//--------------------------------------------------------------
|
||||
void ofApp::setup(){
|
||||
ofDisableArbTex();
|
||||
|
||||
sandbox.allocate(ofGetWidth(), ofGetHeight());
|
||||
sandbox.load("grayscott.frag");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
void ofApp::draw(){
|
||||
sandbox.render();
|
||||
sandbox.draw(0, 0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
For more information about shaders in openFrameworks go to this [excellent tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) made by [Joshua Noble](http://thefactoryfactory.com/).
|
||||
|
||||
|
||||
### In **Blender**
|
||||
|
||||
[GlslTexture](https://github.com/patriciogonzalezvivo/glslTexture) it's an addon that allows you to programatically generate textures using GLSL Shaders and is fully compatible with the rest of the sandboxes on this chapter. How it works:
|
||||
|
||||
|
||||
1. Operator Search: `F3` (or `SpaceBar` depending on your setup). Type `GlslTexture`
|
||||
|
||||
![](blender/00.png)
|
||||
|
||||
2. Change `width` and `height` size and `Source` file (which can be a path to an external file).
|
||||
|
||||
![](blender/01.png)
|
||||
|
||||
3. Use the Image on your materials. The Image name will be based on the name of the source file.
|
||||
|
||||
![](blender/02.png)
|
||||
|
||||
4. Go to the Text Editor (or an external editor if your source file is external) and edit the shader. It will hot reload.
|
||||
|
||||
![](blender/03.png)
|
||||
|
1
04/TITLE-pt.md
Normal file
1
04/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
## Rodando o seu shader
|
BIN
04/blender/00.png
Normal file
BIN
04/blender/00.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
04/blender/01.png
Normal file
BIN
04/blender/01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
BIN
04/blender/02.png
Normal file
BIN
04/blender/02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
04/blender/03.png
Normal file
BIN
04/blender/03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 436 KiB |
@ -1,7 +1,7 @@
|
||||
# Dibujando con algoritmos
|
||||
## Funciones de forma
|
||||
|
||||
Este capítulo se podría llamar "La lección de la cerca del Sr Miyagi". Anteriormente normalizamos la posición de x e y al canal de rojo y verde. Esencialmente creamos una función que tomaba dos vectores dimensionales (x e y) y devolvía un vector de cuatro dimensiones (rojo, verde, azul y transparencia). Pero antes de ir mas lejos, transformando valores entre dimensiones, necesitamos comenzar con algo sencillo... mucho mas sencillo. Eso significa comprender las funciones unidimensionales. A mayor tiempo y energía que pongas en aprender esto, mejor será tu karate.
|
||||
Este capítulo se podría llamar "La lección de la cerca del Sr Miyagi". Anteriormente normalizamos la posición de x e y al canal de rojo y verde. Esencialmente creamos una función que tomaba dos vectores dimensionales (x e y) y devolvía un vector de cuatro dimensiones (rojo, verde, azul y transparencia). Pero antes de ir más lejos, transformando valores entre dimensiones, necesitamos comenzar con algo sencillo... mucho más sencillo. Eso significa comprender las funciones unidimensionales. A mayor tiempo y energía que pongas en aprender esto, mejor será tu karate.
|
||||
|
||||
![The Karate Kid (1984)](mr_miyagi.jpg)
|
||||
|
||||
@ -19,9 +19,9 @@ Esta relación par entre *x* e *y* (o el brillo) es conocida como *interpolació
|
||||
|
||||
Interesante ¿No? En la línea 19 puedes probar diferentes exponentes: 20.0, 2.0, 1.0, 0.0, 0.2 o 0.02 por ejemplo. Entender esta relación entre el valor y el exponente nos será muy útil. Usar este tipo de funciones matemáticas aquí y allá nos dará un control expresivo sobre nuestro código, como si fuese un tipo de acupuntura con el que manejas el flujo de los valores.
|
||||
|
||||
[```pow()```](../glossary/?search=pow) es una función nativa en GLSL y hay muchas mas. La mayoría de ellas son aceleradas por hardware, lo que significa que, usadas de la forma correcta, harán tu código mucho mas rápido.
|
||||
[```pow()```](../glossary/?search=pow) es una función nativa en GLSL y hay muchas más. La mayoría de ellas son aceleradas por hardware, lo que significa que, usadas de la forma correcta, harán tu código mucho más rápido.
|
||||
|
||||
Reemplaza la función de la línea 19. Prueba otras como: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) y [```sqrt()```](../glossary/?search=sqrt). Algunas de estas funciones son mucho mas interesantes cuando las usamos con PI. En la línea 8 definí un macro que reemplaza cualquier llamado a ```PI``` por el valor ```3.14159265359```.
|
||||
Reemplaza la función de la línea 19. Prueba otras como: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) y [```sqrt()```](../glossary/?search=sqrt). Algunas de estas funciones son mucho más interesantes cuando las usamos con PI. En la línea 8 definí un macro que reemplaza cualquier llamado a ```PI``` por el valor ```3.14159265359```.
|
||||
|
||||
### Step y Smoothstep
|
||||
|
||||
@ -47,7 +47,7 @@ En el anterior ejemplo, en la línea 12, hemos usado smoothstep para dibujar una
|
||||
|
||||
Cuando queremos usar un poco de matemática para animar, dar forma o mezclar valores, no hay nada mejor que ser amigos del seno y del coseno.
|
||||
|
||||
Estas dos funciones básicas trigonométricas trabajan juntas creando círculos y son mas útiles que la navaja suiza de MacGyver. Es importante saber como se comportan y de que forma pueden ser combinadas. En pocas palabras, dado un ángulo (en radianes) devolverán la posición de *x* ([coseno](../glossary/?search=cos)) e y ([seno](../glossary/?search=sin)) de un punto en el borde de un círculo con un radio igual a 1. Como estas funciones devuelven un valor normalizado (entre -1 y 1) y suavizado, terminan siendo una herramienta increíble.
|
||||
Estas dos funciones básicas trigonométricas trabajan juntas creando círculos y son más útiles que la navaja suiza de MacGyver. Es importante saber como se comportan y de que forma pueden ser combinadas. En pocas palabras, dado un ángulo (en radianes) devolverán la posición de *x* ([coseno](../glossary/?search=cos)) e y ([seno](../glossary/?search=sin)) de un punto en el borde de un círculo con un radio igual a 1. Como estas funciones devuelven un valor normalizado (entre -1 y 1) y suavizado, terminan siendo una herramienta increíble.
|
||||
|
||||
![](sincos.gif)
|
||||
|
||||
@ -63,7 +63,7 @@ Completa los siguientes ejercicios y presta atención a lo que sucede:
|
||||
|
||||
* Multiplica *x* por ```PI``` antes de computar el ```sin```. Nota como las dos fases se **encogen** y cada ciclo se repite dos veces.
|
||||
|
||||
* Multiplica el tiempo (```u_time```) por *x* antes de computar el ```sin```. Observa como la **frecuencia** entre las fases se comprime mas y mas. Nota que u_time en un momento pasa a ser un número muy alto y se hace difícil ver el gráfico.
|
||||
* Multiplica el tiempo (```u_time```) por *x* antes de computar el ```sin```. Observa como la **frecuencia** entre las fases se comprime más y más. Nota que u_time en un momento pasa a ser un número muy alto y se hace difícil ver el gráfico.
|
||||
|
||||
* Suma 1.0 a [```sin(x)```](../glossary/?search=sin). Observa como toda la onda es **desplazada** hacia arriba y ahora todos los valores van de 0.0 a 2.0.
|
||||
|
||||
@ -73,11 +73,11 @@ Completa los siguientes ejercicios y presta atención a lo que sucede:
|
||||
|
||||
* Extrae sólo la parte fraccionaria ([```fract()```](../glossary/?search=fract)) del resultado de [```sin(x)```](../glossary/?search=sin).
|
||||
|
||||
* Suma el mayor entero mas cercano ([```ceil()```](../glossary/?search=ceil)) y el menor entero mas cercano ([```floor()```](../glossary/?search=floor)) del resultado de [```sin(x)```](../glossary/?search=sin) para obtener la onda digital de 1.0 y -1.0.
|
||||
* Suma el mayor entero más cercano ([```ceil()```](../glossary/?search=ceil)) y el menor entero más cercano ([```floor()```](../glossary/?search=floor)) del resultado de [```sin(x)```](../glossary/?search=sin) para obtener la onda digital de 1.0 y -1.0.
|
||||
|
||||
### Otras funciones útiles
|
||||
|
||||
Al final del último ejercicio hemos introducido algunas funciones nuevas. Ahora es el momento de experimentar con cada una descomentenando las siguientes lineas, de a una. Es importante entender estas funciones y estudiar como se comportan. Ya lo sé ¿Para qué? Si buscas rápidamente en Google "Arte Generativo" vas a entender el por qué. Ten en cuenta que estas funciones son nuestra cerca. Estamos dominando el movimiento en una sola dimensión, arriba y abajo. ¡Pronto, será el momento de agregar la segunda, la tercera y la cuarta dimensión!
|
||||
Al final del último ejercicio hemos introducido algunas funciones nuevas. Ahora es el momento de experimentar con cada una descomenteando las siguientes lineas, de a una. Es importante entender estas funciones y estudiar como se comportan. Ya lo sé ¿Para qué? Si buscas rápidamente en Google "Arte Generativo" vas a entender el por qué. Ten en cuenta que estas funciones son nuestra cerca. Estamos dominando el movimiento en una sola dimensión, arriba y abajo. ¡Pronto, será el momento de agregar la segunda, la tercera y la cuarta dimensión!
|
||||
|
||||
![Anthony Mattox (2009)](anthony-mattox-ribbon.jpg)
|
||||
|
||||
@ -128,16 +128,16 @@ Presta atención a la siguiente tabla de ecuaciones hecha por [Kynd](http://www.
|
||||
|
||||
#### Para tu caja de herramientas
|
||||
|
||||
Estas son algunas herramientas que te ayudaran a visualizar este tipo de funciones.
|
||||
Estas son algunas herramientas que te ayudarán a visualizar este tipo de funciones.
|
||||
|
||||
* Grapher: si tienes una computadora con Mac OS, escribe ```grapher``` en tu spotlight y podrás usar esta herramienta super útil.
|
||||
|
||||
![OS X Grapher (2004)](grapher.png)
|
||||
|
||||
* [GraphToy](http://www.iquilezles.org/apps/graphtoy/): una vez mas [Iñigo Quilez](http://www.iquilezles.org) ha creado una herramienta para visualizar funciones GLSL en WebGL.
|
||||
* [GraphToy](http://www.iquilezles.org/apps/graphtoy/): una vez más [Iñigo Quilez](http://www.iquilezles.org) ha creado una herramienta para visualizar funciones GLSL en WebGL.
|
||||
|
||||
![Iñigo Quilez - GraphToy (2010)](graphtoy.png)
|
||||
|
||||
* [Shadershop](http://tobyschachman.com/Shadershop/): esta herramienta increíble creada por [Toby Schachman](http://tobyschachman.com/) te enseñará a consturir funciones complejas de una manera intuitiva y visual.
|
||||
* [Shadershop](http://tobyschachman.com/Shadershop/): esta herramienta increíble creada por [Toby Schachman](http://tobyschachman.com/) te enseñará a construir funciones complejas de una manera intuitiva y visual.
|
||||
|
||||
![Toby Schachman - Shadershop (2014)](shadershop.png)
|
||||
|
@ -19,7 +19,7 @@
|
||||
このサンプルのx座標とy座標(または明るさ)の1対1の対応は線形補間と呼ばれています。
|
||||
ここから私たちは数学的な関数を使って線を形作っていくことになります。例えばxを5乗すれば曲線を作ることができます。
|
||||
|
||||
(訳注:ここでは x=0.0 から x=1.0 の間のグラフが一次方程式で書ける、つまりグラフが直線になることを指して線形補完 * Liniear Interpolation*という言葉が使われています。参考:[Wikipedia: 線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)。このの章の原文ではInterpolateという単語が複数回登場しますが、厳密な使い方ではない箇所もあるため以下では「補完」という訳語はあてませんでした。興味がある方はコンピュータグラフィックスやアニメーションの世界で補完関数 *Interpolator* がどのように使われているか調べてみましょう。)
|
||||
(訳注:ここでは x=0.0 から x=1.0 の間のグラフが一次方程式で書ける、つまりグラフが直線になることを指して線形補完 * Liniear Interpolation*という言葉が使われています。参考:[Wikipedia: 線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)。この章の原文ではInterpolateという単語が複数回登場しますが、厳密な使い方ではない箇所もあるため以下では「補完」という訳語はあてませんでした。興味がある方はコンピュータグラフィックスやアニメーションの世界で補完関数 *Interpolator* がどのように使われているか調べてみましょう。)
|
||||
|
||||
<div class="codeAndCanvas" data="expo.frag"></div>
|
||||
|
||||
|
@ -93,7 +93,7 @@ At the end of the last exercise we introduced some new functions. Now it’s tim
|
||||
|
||||
### Advance shaping functions
|
||||
|
||||
[Golan Levin](http://www.flong.com/) has great documentation of more complex shaping functions that are extraordinarily helpful. Porting them to GLSL is a really smart move, to start builidng your own resource of snippets of code.
|
||||
[Golan Levin](http://www.flong.com/) has great documentation of more complex shaping functions that are extraordinarily helpful. Porting them to GLSL is a really smart move, to start building your own resource of snippets of code.
|
||||
|
||||
* Polynomial Shaping Functions: [www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
![Paul Klee - Color Chart (1931)](klee.jpg)
|
||||
|
||||
No hemos tenido oportunidad todavía de hablar sobre los tipos de vectores en GLSL. Antes de ir mas lejos, es importante entender cómo funcionan estas variables, hablar de colores es una buena forma de entenderlos.
|
||||
No hemos tenido oportunidad todavía de hablar sobre los tipos de vectores en GLSL. Antes de ir más lejos, es importante entender cómo funcionan estas variables, hablar de colores es una buena forma de entenderlos.
|
||||
|
||||
Si te encuentras familiarizado con la programación orientada a objetos, probablemente te habrás dado cuenta que estamos accediendo a los valores de los vectores, como si fuese un ```struct``` de C.
|
||||
|
||||
@ -25,7 +25,7 @@ vector[2] = vector.b = vector.z = vector.p;
|
||||
vector[3] = vector.a = vector.w = vector.q;
|
||||
```
|
||||
|
||||
Las diferentes formas de acceder a las variables son sólo nomenclaturas diseñadas para que el código sea mas claro. Esta flexibilidad de los shaders, es una puerta de entrada para poder relacionar el color con las coordenadas en el espacio.
|
||||
Las diferentes formas de acceder a las variables son sólo nomenclaturas diseñadas para que el código sea más claro. Esta flexibilidad de los shaders, es una puerta de entrada para poder relacionar el color con las coordenadas en el espacio.
|
||||
|
||||
Otra estupenda funcionalidad de los vectores en GLSL, es que las propiedades se pueden combinar en el orden que quieras, lo que hace muy sencillo manipular y mezclar valores. Esta habilidad es conocida como *swizzle*.
|
||||
|
||||
@ -45,7 +45,7 @@ green.rgb = yellow.bgb; // Assign the blue channel of Yellow (0) to red and blue
|
||||
|
||||
#### Para tu caja de herramientas
|
||||
|
||||
Quizás no estás acostumbrado a seleccionar colores usando números - puede ser un poco confuso. Por suerte, hay muchísimos programas que nos hacen este trabajo mucho mas sencillo. Encuentra el que mas se adapte a tus necesidades y úsalo para trabajar con colores en formato vec3 o vec4. Por ejemplo, estos son los templates que uso en [Spectrum](http://www.eigenlogik.com/spectrum/mac):
|
||||
Quizás no estás acostumbrado a seleccionar colores usando números - puede ser un poco confuso. Por suerte, hay muchísimos programas que nos hacen este trabajo mucho más sencillo. Encuentra el que más se adapte a tus necesidades y úsalo para trabajar con colores en formato vec3 o vec4. Por ejemplo, estos son los templates que uso en [Spectrum](http://www.eigenlogik.com/spectrum/mac):
|
||||
|
||||
```
|
||||
vec3({{rn}},{{gn}},{{bn}})
|
||||
@ -75,15 +75,15 @@ La función [```mix()```](../glossary/?search=mix) tiene mucho para ofrecer. En
|
||||
|
||||
Mira el siguiente ejemplo, como en los del capítulo anterior, estamos conectando la transición normalizada de la coordenada *x* y visualizándola con una línea. Ahora todos los canales van por la misma línea.
|
||||
|
||||
Ahora descomenta la línea 25 y mira lo que sucede. Luego descomenta las lineas 26 y 27. Recuerda que con las lineas visualizamos la cantidad de ```colorA``` y ```colorB``` a mezclar por cada canal.
|
||||
Ahora descomenta la línea 25 y mira lo que sucede. Luego descomenta las líneas 26 y 27. Recuerda que con las líneas visualizamos la cantidad de ```colorA``` y ```colorB``` a mezclar por cada canal.
|
||||
|
||||
<div class="codeAndCanvas" data="gradient.frag"></div>
|
||||
|
||||
Probablemente reconoces las tres funciones de forma que usamos en las lineas 25 y 27. ¡Juega con ellas! Es hora de mezclar y explorar lo aprendido en el capítulo previo para crear gradientes interesantes. Prueba hacer los próximos ejercicios:
|
||||
Probablemente reconoces las tres funciones de forma que usamos en las líneas 25 y 27. ¡Juega con ellas! Es hora de mezclar y explorar lo aprendido en el capítulo previo para crear gradientes interesantes. Prueba hacer los próximos ejercicios:
|
||||
|
||||
![William Turner - The Fighting Temeraire (1838)](turner.jpg)
|
||||
|
||||
* Crea un gradiente que se parezca a atardecer de William Turner.
|
||||
* Crea un gradiente que se parezca a un atardecer de William Turner.
|
||||
|
||||
* Crea una transición entre el atardecer y el amanecer usando ```u_time```.
|
||||
|
||||
@ -93,21 +93,21 @@ Probablemente reconoces las tres funciones de forma que usamos en las lineas 25
|
||||
|
||||
### HSB
|
||||
|
||||
No podemos hablar de color sin mencionar el espacio de color. Probablemente sabes que hay diferentes formas de organizar un color mas allá de usar los canales de rojo, verde y azul.
|
||||
No podemos hablar de color sin mencionar el espacio de color. Probablemente sabes que hay diferentes formas de organizar un color más allá de usar los canales de rojo, verde y azul.
|
||||
|
||||
[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) significa Hue (tono), Saturation (saturación) y Brightness (brillo o valor), es una forma útil y mas intuitiva de organizar el color. Tomate un momento para leer las funciones ```rgb2hsv()``` y ```hsv2rgb()``` del código siguiente.
|
||||
[HSB](http://en.wikipedia.org/wiki/HSL_and_HSV) significa Hue (tono), Saturation (saturación) y Brightness (brillo o valor), es una forma útil y más intuitiva de organizar el color. Tomate un momento para leer las funciones ```rgb2hsv()``` y ```hsv2rgb()``` del código siguiente.
|
||||
|
||||
Conectando la posición del eje x al tono y la posición del eje y al brillo podemos obtener este bonito espectro del color visible. La distribución espacial del color puede sernos muy útil; es mas intuitivo seleccionar un color usando HSB que con RGB.
|
||||
Conectando la posición del eje x al tono y la posición del eje y al brillo podemos obtener este bonito espectro del color visible. La distribución espacial del color puede sernos muy útil; es más intuitivo seleccionar un color usando HSB que con RGB.
|
||||
|
||||
<div class="codeAndCanvas" data="hsb.frag"></div>
|
||||
|
||||
### HSB en coordenadas polares
|
||||
|
||||
HSB fue originalmente diseñado para ser representado en coordenadas polares (basadas en el ángulo y el radio) en vez de coordenadas cartesianas (basadas en x e y). Para asociar nuestra función HSB a coordenadas polares necesitamos obtener el ángulo y la distancia del centro de la ventana. para hacer eso usaremos la función [```length()```](../glossary/?search=length) y [```atan(y,x)```](../glossary/?search=atan) (que es la versión en GLSL del comunmente usado ```atan2(y,x)```).
|
||||
HSB fue originalmente diseñado para ser representado en coordenadas polares (basadas en el ángulo y el radio) en vez de coordenadas cartesianas (basadas en x e y). Para asociar nuestra función HSB a coordenadas polares necesitamos obtener el ángulo y la distancia del centro de la ventana. Para hacer eso usaremos la función [```length()```](../glossary/?search=length) y [```atan(y,x)```](../glossary/?search=atan) (que es la versión en GLSL del comunmente usado ```atan2(y,x)```).
|
||||
|
||||
Cuando usamos vectores y funciones trigonométricas, ```vec2```, ```vec3``` y ```vec4``` son tratados como vectores, incluso cuando representan colores. Comenzaremos a tratar a los colores y a los vectores de una manera similar, de hecho te darás cuenta que es un concepto muy poderoso y flexible.
|
||||
|
||||
**Nota:** Si te preguntabas si había mas funciones geométricas además de [```length```](../glossary/?search=length): [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=faceforward), [```reflect()```](../glossary/?search=reflect) y [```refract()```](../glossary/?search=refract). También GLSL tiene funciones relacionadas a los vectores como: [```lessThan()```](../glossary/?search=lessThan), [```lessThanEqual()```](../glossary/?search=lessThanEqual), [```greaterThan()```](../glossary/?search=greaterThan), [```greaterThanEqual()```](../glossary/?search=greaterThanEqual), [```equal()```](../glossary/?search=equal) y [```notEqual()```](../glossary/?search=notEqual).
|
||||
**Nota:** Si te preguntabas si había más funciones geométricas además de [```length```](../glossary/?search=length): [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=faceforward), [```reflect()```](../glossary/?search=reflect) y [```refract()```](../glossary/?search=refract). También GLSL tiene funciones relacionadas a los vectores como: [```lessThan()```](../glossary/?search=lessThan), [```lessThanEqual()```](../glossary/?search=lessThanEqual), [```greaterThan()```](../glossary/?search=greaterThan), [```greaterThanEqual()```](../glossary/?search=greaterThanEqual), [```equal()```](../glossary/?search=equal) y [```notEqual()```](../glossary/?search=notEqual).
|
||||
|
||||
Una vez que obtenemos el ángulo y la longitud, necesitamos "normalizar" sus valores al rango de 0.0 a 1.0. En la línea 27, [```atan(y,x)```](../glossary/?search=atan) devolverá el angulo en radianes entre -PI y PI (-3.14 a 3.14), por lo que necesitamos dividir este número por ```TWO_PI``` (declarado arriba en nuestro código) para obtener valores de -0.5 a 0.5, que con una simple suma podemos transformar al rango deseado de 0.0 a 1.0. El radio devolverá un máximo de 0.5 (porque estamos calculando la distancia desde el centro del viewport) por lo tanto necesitamos duplicar este rango (multiplicándolo por dos) para obtener un máximo de 1.0.
|
||||
|
||||
@ -123,7 +123,7 @@ Intenta resolver los próximos ejercicios:
|
||||
|
||||
![William Home Lizars - Red, blue and yellow spectra, with the solar spectrum (1834)](spectrums.jpg)
|
||||
|
||||
* Si miras detenidamente el círculo cromático usado en los goteros de color (ver la imágen de abajo), usan un espectro diferente, se trata del RYB. Por ejemplo, el opuesto del color rojo, debería ser el verde, pero en nuestro ejemplo es el cyan. ¿Podrías encontras la forma de igualarlo para que luzca igual a la siguiente imágen? [Pista: este es un buen momento para usar funciones de forma.]
|
||||
* Si miras detenidamente el círculo cromático usado en los goteros de color (ver la imagen de abajo), usan un espectro diferente, se trata del RYB. Por ejemplo, el opuesto del color rojo, debería ser el verde, pero en nuestro ejemplo es el cyan. ¿Podrías encontrar la forma de igualarlo para que luzca igual a la siguiente imagen? [Pista: este es un buen momento para usar funciones de forma.]
|
||||
|
||||
![](colorwheel.png)
|
||||
|
||||
|
@ -132,7 +132,7 @@ Tente os seguintes exercícios:
|
||||
|
||||
#### Nota sobre funções e argumentos
|
||||
|
||||
Antes de irmos para o próximo capítulo, vamos parar e rebobinar. Volte e dê uma olhada nas funções nos exemplos anteriores. Você vai perceber um `in` antes dos tipos de argumentos. Isso é um *qualificador*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) e neste caso, especifica que a variável é somente leitura. Em exemplos futuros, veremos que também é possível definir argumentos como `out` ou `inout`. Este último, `inout`, é conceitualmente similar a passar um argumento pela referência na qual nos dará a possibilidade de modificar uma variável passada.
|
||||
Antes de irmos para o próximo capítulo, vamos parar e rebobinar. Volte e dê uma olhada nas funções nos exemplos anteriores. Você vai perceber um `in` antes dos tipos de argumentos. Isso é um [*qualificador*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) e neste caso, especifica que a variável é somente leitura. Em exemplos futuros, veremos que também é possível definir argumentos como `out` ou `inout`. Este último, `inout`, é conceitualmente similar a passar um argumento pela referência na qual nos dará a possibilidade de modificar uma variável passada.
|
||||
|
||||
```glsl
|
||||
int newFunction(in vec4 aVec4, // read-only
|
||||
|
1
06/SUMMARY-pt.md
Normal file
1
06/SUMMARY-pt.md
Normal file
@ -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.
|
1
06/TITLE-pt.md
Normal file
1
06/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
## Cores
|
@ -235,4 +235,6 @@ pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
|
||||
|
||||
恭喜!你完成了最艰难的部分!休息下让这些概念沉淀一下吧 —— 用Processing 来画简单的形状很容易,但却不到火候。在 shader 的世界里,画形状是很纠结,而且适应这种新的编程范式会有些累人。
|
||||
|
||||
在本章的最后,您将找到[PixelSpirit Deck](https://patriciogonzalezvivo.github.io/PixelSpiritDeck/)的链接,这组卡片将帮助您学习新的SDF功能,将其组合到您的设计和使用中 在您的着色器上。 卡片组具有预先的学习曲线,因此,每天拿一张卡片并进行练习将推动并挑战您几个月的技能。
|
||||
|
||||
既然现在你知道了如何画形状,我十分肯定你脑袋里已经充满了新的点子。在接下来的章节里你会学习到怎么移动,旋转以及缩放图形。这将使你的创作如虎添翼!
|
||||
|
@ -230,4 +230,6 @@ Unser Trick nutzt die gegebene Anzahl der Seiten eines Polygons, um das benötig
|
||||
|
||||
Herzlichen Glückwunsch! Du hast Dich durch schwieriges Fahrwasser gekämpft. Nimm eine kleine Pause, damit sich das Erlernte setzen kann. Das Zeichnen komplexer Formen im Land der Shader ist wahrlich nicht ganz trivial, das kann durchaus ein wenig erschöpfen.
|
||||
|
||||
Unten am Ende dieses Kapitels finden Sie einen Link zu [PixelSpirit Deck] (https://patriciogonzalezvivo.github.io/PixelSpiritDeck/). Mit diesem Kartenspiel können Sie neue SDF-Funktionen erlernen, in Ihre Designs einfügen und verwenden auf deine Shader. Das Deck hat eine prägresive Lernkurve. Wenn Sie also eine Karte pro Tag nehmen und daran arbeiten, können Sie Ihre Fähigkeiten monatelang verbessern und herausfordern.
|
||||
|
||||
Da Du nun weißt, wie man unterschiedliche Formen zeichnet, kommen Dir bestimmt viele interessante Ideen in den Sinn. In den folgenden Kapiteln lernen wir, wie man Formen verschieben, skalieren und rotieren kann. Das wird Dir ermöglichen, komplexe Kompositionen zu erstellen.
|
||||
|
@ -288,5 +288,7 @@ Faites une pause et laissez décanter ces nouveaux concepts.
|
||||
Dessiner des formes dans une API de dessin, c'est facile mais ici c'est une autre histoire.
|
||||
Au pays des shaders, dessiner des formes géométriques est un peu tordu et s'imposer la disciple nécessaire à la compréhension de ce paradigme est épuisant.
|
||||
|
||||
À la fin de ce chapitre, vous trouverez un lien vers [PixelSpirit Deck] (https://patriciogonzalezvivo.github.io/PixelSpiritDeck/). Ce jeu de cartes vous aidera à apprendre les nouvelles fonctions SDF, à les composer dans vos conceptions et à les utiliser. sur vos shaders. La plate-forme a une courbe d’apprentissage prégressive, aussi prendre une carte par jour et travailler dessus vous poussera et mettra au défi vos compétences pendant des mois.
|
||||
|
||||
Maintenant que vous savez comment dessiner des formes, je suis sûr que ça va vous donner des idées.
|
||||
Au prochain chapitre, nous apprendrons à déplacer, à appliquer des rotations et à changer d'échelle pour créer des compositions !
|
||||
|
@ -227,4 +227,6 @@ Il nostro trucco userà il numero di lati di un poligono per costruire il campo
|
||||
|
||||
Congratulazioni! Avete affrontato la parte più complicata! Fate una pausa per poter assimilare questi concetti: disegnare delle semplici forme con Processing è facile, ma qui no. Nella “terra degli Shader”, disegnare le forme è contorto e può essere faticoso adattarsi al nuovo paradigma di codificazione.
|
||||
|
||||
Alla fine di questo capitolo troverai un link a [PixelSpirit Deck] (https://patriciogonzalezvivo.github.io/PixelSpiritDeck/) questo mazzo di carte ti aiuterà ad apprendere nuove funzioni SDF, compilarle nei tuoi progetti e utilizzarle sui tuoi shader. Il mazzo ha una curva di apprendimento pregresiva, quindi prendere una carta al giorno e lavorarci su spingerà e metterà alla prova le tue abilità per mesi.
|
||||
|
||||
Ora che sapete come disegnare le forme, sono sicuro che vi verranno in mente nuove idee. Nel capitolo successivo imparerete a spostare, ruotare e ridimensionare le forme. Questo vi permetterà di fare delle composizioni!
|
||||
|
@ -237,4 +237,6 @@ pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
|
||||
|
||||
おめでとうございます。これで山を乗り越えました。[Processing](https://processing.org/)を使えばシンプルな形を描くのは簡単なことですが、ここで学んだ方法は違います。シェーダーの世界では形を描くのにもひねくれたやり方をしなくてはなりませんし、新しいコーディングの考え方に慣れるのは大変なことです。一息入れて、学んだ概念を頭に馴染ませましょう。
|
||||
|
||||
この章の終わりには、[PixelSpirit Deck](https://patriciogonzalezvivo.github.io/PixelSpiritDeck/)へのリンクがあります。このカードのデッキは、新しいSDF機能を学び、デザインに組み込んで使用するのに役立ちます シェーダーで。 このデッキには学習曲線がありますので、1日に1枚のカードを取り、それに取り組んでいくと、数か月間スキルが向上します。
|
||||
|
||||
図形の描きかたを学んだので、新しいアイデアが頭の中に浮かんでくることでしょう。次の章ではこれらを移動、回転、そして拡大・縮小させる方法を学びます。これで図形を様々に組み合わせることができるようになります。
|
||||
|
231
07/README-pt.md
Normal file
231
07/README-pt.md
Normal file
@ -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:
|
||||
|
||||
<div class="codeAndCanvas" data="rect-making.frag"></div>
|
||||
|
||||
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.
|
||||
|
||||
<div class="codeAndCanvas" data="circle-making.frag"></div>
|
||||
|
||||
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).
|
||||
|
||||
<div class="codeAndCanvas" data="circle.frag"></div>
|
||||
|
||||
### 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.
|
||||
|
||||
<div class="codeAndCanvas" data="rect-df.frag"></div>
|
||||
|
||||
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.
|
||||
|
||||
<div class="simpleFunction" data="y = cos(x*3.);
|
||||
//y = abs(cos(x*3.));
|
||||
//y = abs(cos(x*2.5))*0.5+0.3;
|
||||
//y = abs(cos(x*12.)*sin(x*3.))*.8+.1;
|
||||
//y = smoothstep(-.5,1., cos(x*10.))*0.2+0.5;"></div>
|
||||
|
||||
<div class="codeAndCanvas" data="polar.frag"></div>
|
||||
|
||||
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).
|
||||
|
||||
<div class="codeAndCanvas" data="shapes.frag"></div>
|
||||
|
||||
* 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!
|
@ -228,4 +228,6 @@ float a = atan(pos.y,pos.x);
|
||||
|
||||
Поздравляю! Мы прошли трудную тему! Вдохните и дайте изученным принципам устояться. Рисовать фигуры - это просто в Processing, но не здесь. В мире шейдеров алгоритмы рисования фигур очень заковыристы, и адаптация к такой парадигме программирования может стоить значительных усилий.
|
||||
|
||||
В конце этой главы вы найдете ссылку на [PixelSpirit Deck] (https://patriciogonzalezvivo.github.io/PixelSpiritDeck/), эта колода карт поможет вам изучить новые функции SDF, объединить их в свои проекты и использовать на ваших шейдерах. Колода имеет предварительную кривую обучения, поэтому, взяв одну карту в день и работая над ней, вы испытаете свои навыки на месяцы.
|
||||
|
||||
Теперь, когда вы умеете рисовать фигуры, новые идеи будут появляться в вашей голове с огромной скоростью. В следующей главе мы научимся двигать, вращать и масштабировать фигуры. Вы сможете делать композиции!
|
||||
|
1
07/SUMMARY-pt.md
Normal file
1
07/SUMMARY-pt.md
Normal file
@ -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.
|
1
07/TITLE-pt.md
Normal file
1
07/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
## Formas
|
@ -18,7 +18,7 @@ Un exemple sera sans doute plus explicite :
|
||||
Essayez l'exercice suivant :
|
||||
|
||||
* Servez vous d'```u_time``` et des fonctions de formes pour déplacer la croix de façon intéressante.
|
||||
Pensez à un type de mouvement et tentez de l'appliquer à la croix. Prenez des exemples de la "vraie vie", ça aide! Par exemple, un mouvement de vagues, un pendule, une balle qui rebondit, un vélo qui freine, etc...
|
||||
Pensez à un type de mouvement et tentez de l'appliquer à la croix. Prenez des exemples de la "vraie vie", ça aide! Par exemple, un mouvement de vagues, un pendule, une balle qui rebondit, un vélo qui freine, etc.
|
||||
|
||||
### Rotations
|
||||
|
||||
|
101
08/README-pt.md
Normal file
101
08/README-pt.md
Normal file
@ -0,0 +1,101 @@
|
||||
## Matrizes 2D
|
||||
|
||||
<canvas id="custom" class="canvas" data-fragment-url="matrix.frag" width="700px" height="200px"></canvas>
|
||||
|
||||
### 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.
|
||||
|
||||
<div class="codeAndCanvas" data="cross-translate.frag"></div>
|
||||
|
||||
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:
|
||||
|
||||
<div class="codeAndCanvas" data="cross-rotate.frag"></div>
|
||||
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
<div class="codeAndCanvas" data="cross-scale.frag"></div>
|
||||
|
||||
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.
|
||||
|
||||
<iframe width="800" height="450" frameborder="0" src="https://www.shadertoy.com/embed/4s2SRt?gui=true&t=10&paused=true" allowfullscreen></iframe>
|
||||
|
||||
### 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.
|
||||
|
||||
<div class="codeAndCanvas" data="yuv.frag"></div>
|
||||
|
||||
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.
|
2
08/SUMMARY-pt.md
Normal file
2
08/SUMMARY-pt.md
Normal file
@ -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.
|
||||
|
1
08/TITLE-pt.md
Normal file
1
08/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
## Matrizes 2D
|
122
09/README-pt.md
Normal file
122
09/README-pt.md
Normal file
@ -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.
|
||||
|
||||
<div class="codeAndCanvas" data="grid-making.frag"></div>
|
||||
|
||||
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.
|
||||
|
||||
<div class="codeAndCanvas" data="checks.frag"></div>
|
||||
|
||||
* 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.
|
||||
|
||||
<div class="simpleFunction" data="y = mod(x,2.0);
|
||||
// y = mod(x,2.0) < 1.0 ? 0. : 1. ;
|
||||
// y = step(1.0,mod(x,2.0));"></div>
|
||||
|
||||
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.
|
||||
|
||||
|
||||
<div class="codeAndCanvas" data="bricks.frag"></div>
|
||||
|
||||
* 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:
|
||||
|
||||
<a href="../edit.php#09/marching_dots.frag"><canvas id="custom" class="canvas" data-fragment-url="marching_dots.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
## 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.
|
||||
|
||||
<div class="codeAndCanvas" data="truchet.frag"></div>
|
||||
|
||||
* 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)
|
||||
|
||||
<a href="../edit.php#09/iching-01.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-01.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
## 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.
|
||||
|
1
09/SUMMARY-pt.md
Normal file
1
09/SUMMARY-pt.md
Normal file
@ -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.
|
1
09/TITLE-pt.md
Normal file
1
09/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
## Patterns (padrões)
|
92
10/README-pt.md
Normal file
92
10/README-pt.md
Normal file
@ -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:
|
||||
|
||||
<div class="simpleFunction" data="y = fract(sin(x)*1.0);"></div>
|
||||
|
||||
Acima, estamos extraindo o conteúdo fracionário de uma onda senoide. 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
|
||||
|
||||
Usar o random pode ser difícil; é ao mesmo tempo caótico demais, e às vezes pouco aleatório. Dê uma olhada no gráfico a seguir. Para fazê-lo, estamos usando a função ```rand()``` que é implementada exatamente como descrevemos acima.
|
||||
|
||||
Olhando mais de perto, você pode ver a crista da onda do [```sin()```](../glossary/?search=sin) em ```-1.5707``` e ```1.5707```. Eu aposto que agora você entende porque - é onde acontecem o máximo e o mínimo da onda de seno.
|
||||
|
||||
Se olhar bem de perto na distribuição aleatória, você vai notar que existe uma concentração em torno do meio, comparado com as bordas.
|
||||
|
||||
<div class="simpleFunction" data="y = rand(x);
|
||||
//y = rand(x)*rand(x);
|
||||
//y = sqrt(rand(x));
|
||||
//y = pow(rand(x),5.);"></div>
|
||||
|
||||
Há um certo tempo, o [Pixelero](https://pixelero.wordpress.com) publicou um [artigo interessante sobre distribuição aleatória](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/). Eu adicionei alguma das funções que ele usa no gráfico anterior, para você brincar com elas, e ver como a distribuição pode ser alterada. Descomente as funções e veja o que acontece.
|
||||
|
||||
Se você ser o [artigo do Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/), é importante ter em mente que nossa função ```rand()``` é um random determinístico, também conhecido como pseudo-random. Isso quer dizer que, por exemplo, ```rand(1.)``` vai sempre retornar o mesmo valor. [Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) faz referência à função ```Math.random()``` do ActionScriptm que é não-determinística; toda chamada vai retornar um valor diferente.
|
||||
|
||||
## 2D Random
|
||||
|
||||
Agora que temos um entendimento melhor da aleatoriedade, é hora de aplicar isso em duas dimensões, tanto para o eixo ```x``` quanto o ```y```. Para isso, precisamos de uma maneira de transformar um vetor bi-dimensional em um valor de ponto flutuante, de uma dimensão. Existem formas diferentes de se fazer isso, mas a função [```dot()```](../glossary/?search=dot) é bem útil nesse caso. Ela retorna um valor float entre ```0.0``` e ```1.0``` dependendo do alinhamento dos vetores.
|
||||
|
||||
<div class="codeAndCanvas" data="2d-random.frag"></div>
|
||||
|
||||
Veja as linhas 13 a 15 e note como estamos comparando o ```vec2 st``` com outro vetor bi-dimensional ( ```vec2(12.9898,78.233)```).
|
||||
|
||||
* Tente mudar os valores nas linhas 14 e 15. Veja como o padrão do random muda e pense no que podemos aprender com isso.
|
||||
|
||||
* Junte essa função random à interação com o mouse (```u_mouse```) e tempo (```u_time```) para entender melhor como ela funciona.
|
||||
|
||||
## Usando o chaos
|
||||
|
||||
A random em duas dimensões parece bastante com o ruído da TV, não é? É um material difícil para usar para compor imagens. Vamos aprender como fazer uso disso.
|
||||
|
||||
Nosso primeiro passo é aplicar um grid; usando a função [```floor()```](../glossary/?search=floor) vamos gerar uma tabela inteira de células. Dê uma olhada nesse código a seguir, em especial as linhas 22 e 23.
|
||||
|
||||
<div class="codeAndCanvas" data="2d-random-mosaic.frag"></div>
|
||||
|
||||
Depois de escalar o espaço por 10 (na linha 21), nós separamos os inteiros das coordernadas da parte fracionária. Estamos familiares com essa última operação porque já vínhamos usando para subdividir um espaço em células menores, que vão de ```0.0``` a ```1.0```. Obtendo a parte inteira da coordenada, isolamos um valor comum para uma região de pixels, que vai parecer com uma célula simples. Então, podemos usar esse inteiro comum para obter um valor aleatório para essa área. Como nossa random é determinística, o valor aleatório retornado vai ser constante para todos os pixels naquela célula.
|
||||
|
||||
Descomente a linha 29 e veja que nós preservamos a parte de ponto flutuante da coordenada, de modo que podemos ainda usar o sistema de coordenadas para desenhar coisas dentro de cada célula.
|
||||
|
||||
Combinar esses dois valores - a parte inteira e a fracionária da coordenada - vai te permitir misturar variação e ordem.
|
||||
|
||||
Dê uma olhada nessa versão portada para GLSL do famoso gerador de labirintos ```10 PRINT CHR$(205.5+RND(1)); : GOTO 10```.
|
||||
|
||||
<div class="codeAndCanvas" data="2d-random-truchet.frag"></div>
|
||||
|
||||
Aqui, estou usando os valores aleatórios de células para desenhar uma linha em uma direção ou outra, usando a função ```truchetPattern()``` do capítulo anterior (linhas 41 a 47).
|
||||
|
||||
Você pode conseguir outro padrão interessante ao descomentar o bloco de linhas entre 50 e 53, ou animar o padrão ao descomentar as linhas 35 e 36.
|
||||
|
||||
## Seja Master no Random
|
||||
|
||||
[Ryoji Ikeda](http://www.ryojiikeda.com/), um japonês que é compositor eletrônico e artista visual, fez uso de mestre do random; é difícil não ser tocado e hipnotizado por seu trabalho. Seu uso da aleatoriedade em mídia visua e áudio é trabalhada de forma que não é vira um caos irritante, mas um espelho da complexidade de nossa cultura tecnológica.
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/76813693?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
Veja o trabalho do [Ikeda](http://www.ryojiikeda.com/) e tente os seguintes exercícios:
|
||||
|
||||
* Faça linhas de células se movendo (em direções opostas) com valores aleatórios. Exiba apenas as células com valores mais claros. Faça a velocidade das células mudar ao longo do tempo.
|
||||
|
||||
<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>
|
||||
|
||||
* De modo similar, faça várias linhas, mas cada uma com velocidade e direção diferentes. Ligue a posição do mouse ao threshold de cada célula a exibir.
|
||||
|
||||
<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>
|
||||
|
||||
* Crie outros efeitos interessantes.
|
||||
|
||||
<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>
|
||||
|
||||
Usar uma estética aleatória pode ser problemática, especialmente se você quer fazer simulações que pareçam naturais. A random é simplesmente caótica demais, e bem poucas coisas parecem com ```random()``` na vida real. Se você olhar um padrão de chuva, ou gráfico de ações, que são bem aleatórios, eles não são nada como o padrão aleatório que fizemos no começo desse capítulo. A razão? Bem, valores aleatórios não têm correlação entre eles de qualquer modo, mas a maioria dos padrões naturais têm alguma memória do estado anterior.
|
||||
|
||||
No próximo capítulo vamos aprender sobre ruído, a forma suave e de *aparência natural* de criar caos computacional.
|
1
10/SUMMARY-pt.md
Normal file
1
10/SUMMARY-pt.md
Normal file
@ -0,0 +1 @@
|
||||
A vida é chata, se tudo é previsível. Embora nada seja realmente aleatório em computadores, podemos criar pseudo-aleatoriedade que pareça totalmente imprevisível usando truques simples para criar padrões e comportamentos mais interessantes.
|
1
10/TITLE-pt.md
Normal file
1
10/TITLE-pt.md
Normal file
@ -0,0 +1 @@
|
||||
# Designs Generativos
|
@ -241,7 +241,7 @@ Bon... assez parlé technique, il est temps d'utiliser cette ressource de façon
|
||||
Que pouvez-vous dire de l'impression que chacun "dégage" ? Plissez les yeux pour vous aider, comme quand vous regardez les nuages.
|
||||
Que voyez vous ? Qu'est ce que ça vous rappelle ? Quelles utilisations potentielles voyez vous pour chaque type de bruit ? Essayez de concrétiser ces idées.
|
||||
|
||||
* Créez un shader qui donne l'illusion d'un flux ; une lava-lamp, des goutes d'encre, de l'eau, etc...
|
||||
* Créez un shader qui donne l'illusion d'un flux ; une lava-lamp, des goutes d'encre, de l'eau, etc.
|
||||
|
||||
<a href="../edit.php#11/lava-lamp.frag"><canvas id="custom" class="canvas" data-fragment-url="lava-lamp.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
|
@ -16,7 +16,7 @@ Ce qui signifie qu'il va nous falloir itérer sur tous les points et conserver l
|
||||
![](cell-00.png)
|
||||
|
||||
```glsl
|
||||
float m_dist = 1.; // distance minimun
|
||||
float m_dist = 1.; // distance minimum
|
||||
for (int i = 0; i < TOTAL_POINTS; i++) {
|
||||
float dist = distance(st, points[i]);
|
||||
m_dist = min(m_dist, dist);
|
||||
|
@ -23,7 +23,7 @@ void main() {
|
||||
point[3] = vec2(0.31,0.26);
|
||||
point[4] = u_mouse/u_resolution;
|
||||
|
||||
float m_dist = 1.; // minimun distance
|
||||
float m_dist = 1.; // minimum distance
|
||||
|
||||
// Iterate through the points positions
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
@ -25,7 +25,7 @@ void main() {
|
||||
vec2 i_st = floor(st);
|
||||
vec2 f_st = fract(st);
|
||||
|
||||
float m_dist = 1.; // minimun distance
|
||||
float m_dist = 1.; // minimum distance
|
||||
|
||||
for (int y= -1; y <= 1; y++) {
|
||||
for (int x= -1; x <= 1; x++) {
|
||||
|
@ -25,7 +25,7 @@ void main() {
|
||||
vec2 i_st = floor(st);
|
||||
vec2 f_st = fract(st);
|
||||
|
||||
float m_dist = 1.; // minimun distance
|
||||
float m_dist = 1.; // minimum distance
|
||||
for (int j= -1; j <= 1; j++ ) {
|
||||
for (int i= -1; i <= 1; i++ ) {
|
||||
// Neighbor place in the grid
|
||||
|
@ -23,7 +23,7 @@ void main() {
|
||||
point[3] = vec2(0.31,0.26);
|
||||
point[4] = u_mouse/u_resolution;
|
||||
|
||||
float m_dist = 1.; // minimun distance
|
||||
float m_dist = 1.; // minimum distance
|
||||
vec2 m_point; // minimum position
|
||||
|
||||
// Iterate through the points positions
|
||||
|
@ -25,7 +25,7 @@ void main() {
|
||||
vec2 i_st = floor(st);
|
||||
vec2 f_st = fract(st);
|
||||
|
||||
float m_dist = 10.; // minimun distance
|
||||
float m_dist = 10.; // minimum distance
|
||||
vec2 m_point; // minimum point
|
||||
|
||||
for (int j=-1; j<=1; j++ ) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
Le bruit peut avoir plusieurs significations selon les personnes. Les musiciens le trouveront dérangeant, les communicants le considèrent comme une interférence et les astrophysiciens comme un rayonnement cosmique.
|
||||
|
||||
Toutes ces qualifications, nous ramènent à l'ancrage *physique* du bruit dans notre environnement. Commençons toutefois par quelque chose de plus simple et de plus fondamental ; les ondes et leurs propriétés.
|
||||
Une onde peut être considérée comme la variation d'une propriété dans le temps ; le son est une variation de la pression de l'air au fil du temps, une onde électro-magnétique est la fluctuation dans le temps d'un champs électrique et magnétique, etc...
|
||||
Une onde peut être considérée comme la variation d'une propriété dans le temps ; le son est une variation de la pression de l'air au fil du temps, une onde électro-magnétique est la fluctuation dans le temps d'un champs électrique et magnétique, etc.
|
||||
Les deux caractéristiques importantes d'une onde sont sa *fréquence* et son *amplitude*.
|
||||
|
||||
L'équation d'une onde à une dimension peut s'écrire comme suit :
|
||||
|
38
15/README.md
38
15/README.md
@ -4,11 +4,11 @@
|
||||
|
||||
![](01.jpg)
|
||||
|
||||
Graphic cards (GPUs) have special memory types for images. Usually on CPUs images are stores as arrays of bites but on GPUs store images as ```sampler2D``` which is more like a table (or matrix) of floating point vectors. More interestingly is that the values of this *table* of vectors are continously. That means that value between pixels are interpolated in a low level.
|
||||
Graphic cards (GPUs) have special memory types for images. Usually on CPUs images are stored as arrays of bytes but GPUs store images as ```sampler2D``` which is more like a table (or matrix) of floating point vectors. More interestingly, the values of this *table* of vectors are continuous. That means that values between pixels are interpolated in a low level.
|
||||
|
||||
In order to use this feature we first need to *upload* the image from the CPU to the GPU, to then pass the ```id``` of the texture to the right [```uniform```](../05). All that happens outside the shader.
|
||||
|
||||
Once the texture is loaded and linked to a valid ```uniform sampler2D``` you can ask for specific color value at specific coordinates (formated on a [```vec2```](index.html#vec2.md) variable) usin the [```texture2D()```](index.html#texture2D.md) function which will return a color formated on a [```vec4```](index.html#vec4.md) variable.
|
||||
Once the texture is loaded and linked to a valid ```uniform sampler2D``` you can ask for specific color value at specific coordinates (formated on a [```vec2```](index.html#vec2.md) variable) using the [```texture2D()```](index.html#texture2D.md) function which will return a color formatted on a [```vec4```](index.html#vec4.md) variable.
|
||||
|
||||
```glsl
|
||||
vec4 texture2D(sampler2D texture, vec2 coordinates)
|
||||
@ -18,31 +18,31 @@ Check the following code where we load Hokusai's Wave (1830) as ```uniform sampl
|
||||
|
||||
<div class="codeAndCanvas" data="texture.frag" data-textures="hokusai.jpg"></div>
|
||||
|
||||
If you pay attention you will note that the coordinates for the texture are normalized! What a surprise right? Textures coordenates are consisten with the rest of the things we had saw and their coordenates are between 0.0 and 1.0 whitch match perfectly with the normalized space coordinates we have been using.
|
||||
If you pay attention you will note that the coordinates for the texture are normalized! What a surprise right? Textures coordinates are consistent with the rest of the things we had seen and their coordinates are between 0.0 and 1.0 which match perfectly with the normalized space coordinates we have been using.
|
||||
|
||||
Now that you have seen how we load correctly a texture is time to experiment to discover what we can do with it, by trying:
|
||||
Now that you have seen how we correctly load a texture, it is time to experiment to discover what we can do with it, by trying:
|
||||
|
||||
* Scaling the previus texture by half.
|
||||
* Rotating the previus texture 90 degrees.
|
||||
* Hooking the mouse position to the coordenates to move it.
|
||||
* Scaling the previous texture by half.
|
||||
* Rotating the previous texture 90 degrees.
|
||||
* Hooking the mouse position to the coordinates to move it.
|
||||
|
||||
Why you should be excited about textures? Well first of all forget about the sad 255 values for channel, once your image is trasformed into a ```uniform sampler2D``` you have all the values between 0.0 and 1.0 (depending on what you set the ```precision``` to ). That's why shaders can make really beatiful post-processing effects.
|
||||
Why you should be excited about textures? Well first of all forget about the sad 255 values for channel; once your image is transformed into a ```uniform sampler2D``` you have all the values between 0.0 and 1.0 (depending on what you set the ```precision``` to ). That's why shaders can make really beautiful post-processing effects.
|
||||
|
||||
Second, the [```vec2()```](index.html#vec2.md) means you can get values even between pixels. As we said before the textures are a continum. This means that if you set up your texture correctly you can ask for values all arround the surface of your image and the values will smoothly vary from pixel to pixel with no jumps!
|
||||
Second, the [```vec2()```](index.html#vec2.md) means you can get values even between pixels. As we said before the textures are a continuum. This means that if you set up your texture correctly you can ask for values all around the surface of your image and the values will smoothly vary from pixel to pixel with no jumps!
|
||||
|
||||
Finnally, you can setup your image to repeat in the edges, so if you give values over or lower of the normalized 0.0 and 1.0, the values will wrap around starting over.
|
||||
Finally, you can set up your image to repeat in the edges, so if you give values over or lower of the normalized 0.0 and 1.0, the values will wrap around starting over.
|
||||
|
||||
All this features makes your images more like an infinit spandex fabric. You can streach and shrinks your texture without noticing the grid of bites they originally where compose of or the ends of it. To experience this take a look to the following code where we distort a texture using [the noise function we already made](../11/).
|
||||
All these features make your images more like an infinite spandex fabric. You can stretch and shrink your texture without noticing the grid of bytes they are originally composed of or the ends of it. To experience this take a look at the following code where we distort a texture using [the noise function we already made](../11/).
|
||||
|
||||
<div class="codeAndCanvas" data="texture-noise.frag" data-textures="hokusai.jpg"></div>
|
||||
|
||||
## Texture resolution
|
||||
|
||||
Aboves examples play well with squared images, where both sides are equal and match our squared billboard. But for non-squared images things can be a little more tricky, and unfortunatly centuries of picturical art and photography found more pleasent to the eye non-squared proportions for images.
|
||||
Above examples play well with squared images, where both sides are equal and match our squared billboard. But for non-squared images things can be a little more tricky, and unfortunately centuries of pictorial art and photography found more pleasant to the eye non-squared proportions for images.
|
||||
|
||||
![Joseph Nicéphore Niépce (1826)](nicephore.jpg)
|
||||
|
||||
How we can solve this problem? Well we need to know the original proportions of the image to know how to streatch the texture correctly in order to have the original [*aspect ratio*](http://en.wikipedia.org/wiki/Aspect_ratio). For that the texture width and height is pass to the shader as an ```uniform```. Which in our example framework are pass as an ```uniform vec2``` with the same name of the texture followed with proposition ```Resolution```. Once we have this information on the shader he can get the aspect ration by dividing the ```width``` for the ```height``` of the texture resolution. Finally by multiplying this ratio to the coordinates on ```y``` we will shrink these axis to match the original proportions.
|
||||
How we can solve this problem? Well we need to know the original proportions of the image to know how to stretch the texture correctly in order to have the original [*aspect ratio*](http://en.wikipedia.org/wiki/Aspect_ratio). For that the texture width and height are passed to the shader as an ```uniform```, which in our example framework are passed as an ```uniform vec2``` with the same name of the texture followed with proposition ```Resolution```. Once we have this information on the shader we can get the aspect ratio by dividing the ```width``` for the ```height``` of the texture resolution. Finally by multiplying this ratio to the coordinates on ```y``` we will shrink this axis to match the original proportions.
|
||||
|
||||
Uncomment line 21 of the following code to see this in action.
|
||||
|
||||
@ -54,25 +54,25 @@ Uncomment line 21 of the following code to see this in action.
|
||||
|
||||
![](03.jpg)
|
||||
|
||||
You may be thinking that this is unnesesary complicated... and you are probably right. Also this way of working with images leave a enought room to different hacks and creative tricks. Try to imagine that you are an upholster and by streaching and folding a fabric over a structure you can create better and new patterns and techniques.
|
||||
You may be thinking that this is unnecessarily complicated... and you are probably right. Also this way of working with images leaves enough room to different hacks and creative tricks. Try to imagine that you are an upholster and by stretching and folding a fabric over a structure you can create better and new patterns and techniques.
|
||||
|
||||
![Eadweard's Muybridge study of motion](muybridge.jpg)
|
||||
|
||||
This level of craftsmanship links back to some of the first optical experiments ever made. For example on games *sprite animations* are very common, and is inevitably to see on it reminicence to phenakistoscope, zoetrope and praxinoscope.
|
||||
This level of craftsmanship links back to some of the first optical experiments ever made. For example on games *sprite animations* are very common, and is inevitably to see on it reminiscence to phenakistoscope, zoetrope and praxinoscope.
|
||||
|
||||
This could seam simple but the posibilities of modifing textures coordinates is enormus. For example: .
|
||||
This could seem simple but the possibilities of modifying textures coordinates are enormous. For example:
|
||||
|
||||
<div class="codeAndCanvas" data="texture-sprite.frag" data-textures="muybridge.jpg"></div>
|
||||
|
||||
Now is your turn:
|
||||
|
||||
* Can you make a kaleidoscope using what we have learn?
|
||||
* Can you make a kaleidoscope using what we have learned?
|
||||
|
||||
* Way before Oculus or google cardboard, stereoscopic photography was a big thing. Could code a simple shader to re-use this beautiful images?
|
||||
* Way before Oculus or google cardboard, stereoscopic photography was a big thing. Could you code a simple shader to re-use these beautiful images?
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
* What other optical toys can you re-create using textures?
|
||||
|
||||
In the next chapters we will learn how to do some image processing using shaders. You will note that finnaly the complexity of shader makes sense, because was in a big sense designed to do this type of process. We will start doing some image operations!
|
||||
In the next chapters we will learn how to do some image processing using shaders. You will note that finally the complexity of shader makes sense, because it was in a big sense designed to do this type of process. We will start doing some image operations!
|
||||
|
@ -28,7 +28,7 @@ void main () {
|
||||
float r = length(st);
|
||||
float a = atan(st.y, st.x);
|
||||
|
||||
// Repeat side acoriding to angle
|
||||
// Repeat side according to angle
|
||||
float sides = 10.;
|
||||
float ma = mod(a, TWO_PI/sides);
|
||||
ma = abs(ma - PI/sides);
|
||||
|
@ -16,7 +16,7 @@ void main () {
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
// Fix the proportions by finding the aspect ration
|
||||
// Fix the proportions by finding the aspect ratio
|
||||
float aspect = u_tex0Resolution.x/u_tex0Resolution.y;
|
||||
// st.y *= aspect; // and then applying to it
|
||||
|
||||
|
@ -25,7 +25,7 @@ void main () {
|
||||
// Normalize value of the frame resolution
|
||||
vec2 nRes = u_tex0Resolution/fRes;
|
||||
|
||||
// Scale the coordenates to a single frame
|
||||
// Scale the coordinates to a single frame
|
||||
st = st/nRes;
|
||||
|
||||
// Calculate the offset in cols and rows
|
||||
|
22
README-pt.md
22
README-pt.md
@ -11,23 +11,23 @@ Este é um guia passo-a-passo pelo universo abstrato e complexo de Fragment Shad
|
||||
|
||||
## Conteúdo
|
||||
|
||||
* [Sobre este livro](00/)
|
||||
* [Sobre este livro](00/?lan=pt)
|
||||
|
||||
* Início
|
||||
* [O que é um shader?](01/)
|
||||
* [“Olá mundo!”](02/)
|
||||
* [Uniforms](03/)
|
||||
* [Executando seu shader](04/)
|
||||
* [O que é um shader?](01/?lan=pt)
|
||||
* [“Olá mundo!”](02/?lan=pt)
|
||||
* [Uniforms](03/?lan=pt)
|
||||
* [Executando seu shader](04/?lan=pt)
|
||||
|
||||
* Desenho algorítmico
|
||||
* [Funções de forma](05/)
|
||||
* [Cores](06/)
|
||||
* [Formas](07/)
|
||||
* [Matrizes](08/)
|
||||
* [Padrões](09/)
|
||||
* [Funções de forma](05/?lan=pt)
|
||||
* [Cores](06/?lan=pt)
|
||||
* [Formas](07/?lan=pt)
|
||||
* [Matrizes](08/?lan=pt)
|
||||
* [Padrões](09/?lan=pt)
|
||||
|
||||
* Design generativo
|
||||
* [Aleatório](10/)
|
||||
* [Aleatório](10/?lan=pt)
|
||||
* [Noise](11/)
|
||||
* [Cellular noise](12/)
|
||||
* [Movimento browniano fracionário](13/)
|
||||
|
@ -1,4 +1,4 @@
|
||||
## Wie kann ich die Beispielprogramme auf einem RaspberryPi ausführen?
|
||||
## Wie kann ich die Beispiele auf einem RaspberryPi ausführen?
|
||||
|
||||
Vor wenigen Jahren konnte man noch nicht davon ausgehen, dass jedermann über einen Computer mit einer GPU verfügt. Heutzutage gilt das nicht mehr. Doch im Bereich von Schulen, Universitäten und anderen Weiterbildungseichrichtungen ist dies immer noch eine hohe Anforderung.
|
||||
|
||||
|
@ -8,7 +8,7 @@ Exercises:
|
||||
|
||||
* Animate two circles. Can you express difference between different materials through motion? How a metal ball and a plastic ball behave differently?
|
||||
|
||||
* Design your character(an animal, monster, spaceship, etc.) by combining shapes and animate it.
|
||||
* Design your character (an animal, monster, spaceship, etc.) by combining shapes and animate it.
|
||||
|
||||
* Speed up or down your character animation. Can you make it five times faster or slower than the original?
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
*[kynd](http://www.kynd.info) Nov 20, 2016*
|
||||
|
||||
Shaders are often used to create realistic surfaces of natural or artificial material such as wood, marble, granite, metal, stone, etc. without using photographs or pre-rendered images. Here are demonstrations of some basic techniques. All the examples are based on anumber of random and noise functions from [Random](http://thebookofshaders.com/10/), [Noise](http://thebookofshaders.com/11/), [Cellular Noise](http://thebookofshaders.com/12/) and [Fractal Brownian Motion](http://thebookofshaders.com/13/) chapters. Once you get the basic ideas, try tweaking and adding more details to make them more realistic, coming up with new textures and optimizing the performance.
|
||||
Shaders are often used to create realistic surfaces of natural or artificial material such as wood, marble, granite, metal, stone, etc. without using photographs or pre-rendered images. Here are demonstrations of some basic techniques. All the examples are based on a number of random and noise functions from [Random](http://thebookofshaders.com/10/), [Noise](http://thebookofshaders.com/11/), [Cellular Noise](http://thebookofshaders.com/12/) and [Fractal Brownian Motion](http://thebookofshaders.com/13/) chapters. Once you get the basic ideas, try tweaking and adding more details to make them more realistic, coming up with new textures and optimizing the performance.
|
||||
|
||||
Note that the terrain examples at the bottom use normal map and lighting which are techniques not yet introduced in this book. In short, what they do is to generate a map of the directions of the surface and shade the pixels accordingly. We will cover these ideas in future chapters. Stay tuned.
|
||||
|
Loading…
Reference in New Issue
Block a user