Add a portuguese translation for chapter 4, 7 and 8.
parent
5334b5eb18
commit
1c0f3ae1ed
@ -0,0 +1,188 @@
|
|||||||
|
## Rodando seu shader
|
||||||
|
|
||||||
|
Como parte da construção deste livro e minha prática artística, eu criei um ecossistema de ferramentas para criar, visualizar, compartilhar e curar shaders. Estas ferramentas funcionam de forma consistente nas plataformas Linux, Desktop, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) e navegadores sem a necessidade de alterar o código.
|
||||||
|
|
||||||
|
**Visualize**: Todos os exemplos deste livro são exibidos usando [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) que facilita o processo de rodar o shader independentemente.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<canvas class="glslCanvas" data-fragment-url=“yourShader.frag" data-textures=“yourInputImage.png” width="500" height="500"></canvas>
|
||||||
|
```
|
||||||
|
Como você pode ver, só é preciso um elemento `canvas` com a classe `class="glslCanvas"` e a url do seu shader em `data-fragment-url`. Saiba mais [aqui](https://github.com/patriciogonzalezvivo/glslCanvas).
|
||||||
|
|
||||||
|
Se você é como eu, você provavelmente quer rodar shaders diretamente do console, neste caso, você deve dar uma olhada no [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Esta aplicação permite que voc6e incorpore shaders em seus scripts `bash` ou nas pipelines de unix e os-use de uma forma similar a [ImageMagick](http://www.imagemagick.org/script/index.php). [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) também é uma ótima forma de compilar seus shaders para [Raspberry Pi](https://www.raspberrypi.org/), razão na qual [openFrame.io](http://openframe.io/) o usa para exibir suas artes. Veja mais sobre a aplicação [aqui](https://github.com/patriciogonzalezvivo/glslViewer).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png
|
||||||
|
```
|
||||||
|
|
||||||
|
**Crie**: Para iluminar a experiência de programar shaders, eu fiz um editor online chamado [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). Este editor é embedado nos exemplos ao vivo do livro, ele trás uma série de widgets úteis tornando mais tangóvei a experiência abstrata de trabalhar com códigos em glsl. Você pode também rodá-los numa aplicação web independente em [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Aprenda mais sobre isso [aqui
|
||||||
|
](https://github.com/patriciogonzalezvivo/glslEditor).
|
||||||
|
|
||||||
|
![](glslEditor-01.gif)
|
||||||
|
|
||||||
|
Se você prefere trabalhar offline usando [SublimeText](https://www.sublimetext.com/), você pode instalar este [pacote do glslViewer](https://packagecontrol.io/packages/glslViewer). Veja mais sobre [aqui](https://github.com/patriciogonzalezvivo/sublime-glslViewer).
|
||||||
|
|
||||||
|
![](glslViewer.gif)
|
||||||
|
|
||||||
|
**Compartilhe**: o editor online ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) pode compartilhar seus shaders! Ambos, a versão incorporada e a independente, têm um botão de export onde você receberá uma URL única para seu shader. Também existe a opção de exportar diretamente para um [openFrame.io](http://openframe.io/).
|
||||||
|
|
||||||
|
![](glslEditor-00.gif)
|
||||||
|
|
||||||
|
**Cure**: Compartilhar seu código é só o começo para compartilhar seu shader como arte! Ao lado da opção para o [openFrame.io](http://openframe.io/), eu fiz uma ferramenta para curar shaders em uma galeria que pode ser incoporada em qualquer site, seu nome é [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Veja mais [aqui](https://github.com/patriciogonzalezvivo/glslGallery).
|
||||||
|
|
||||||
|
## Rodando seus shaders no seu framework favorito
|
||||||
|
|
||||||
|
No caso de você já ter experiência em um framework como: [Processing](https://processing.org/), [Three.js](http://threejs.org/) ou [OpenFrameworks](http://openframeworks.cc/), você está provavelmente empolgado para testar shaders com plataformas que você se sente confortável. A seguir, vemos exemplos de como configurar shaders em algumas frameworks populares com as mesmas uniforms que vamos estar usando durante este livro. (No [repositório do Github deste para este capítulo](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), você encontrará o código fonte completo para estas três frameworks.)
|
||||||
|
|
||||||
|
### Em ***Three.js***
|
||||||
|
|
||||||
|
O brilhante e muito humilde Ricardo Cabello (também conhecido como [MrDoob](https://twitter.com/mrdoob) ) tem desenvolvido junto com outros [contribuidores](https://github.com/mrdoob/three.js/graphs/contributors) provavelmente uma das mais famosas frameworks de WebGL, chamada [Three.js](http://threejs.org/). Você encontrará muitos exemplos, tutoriais e livros que te ensinarão como usar esta biblioteca em Javascript para criar bons gráficos 3D.
|
||||||
|
|
||||||
|
Abaixo, temos um exemplo de HTML e JS que você precisa para começar usando shaders em three.js. Preste atenção no script `id="fragmentShader"`, lá é onde você pode copiar os shaders que você 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**
|
||||||
|
|
||||||
|
Criado por [Ben Fry](http://benfry.com/) e [Casey Reas](http://reas.com/) em 2001, [Processing](https://processing.org/) é um ambiente extremamente simples e poderoso para dar seus primeiros passos em programação (ao menos, foi para mim). [Andres Colubri](https://codeanticode.wordpress.com/)fez as atualizações mais importantes ao openGL e vídeo em Processing, facilitando o uso de GLSL shaders neste ambiente amigável. Processing buscará pelo shader `"shader.frag"` na pasta `data` do seu sketch. Tenha certeza de ter copiar os shaders que você encontrar aqui para a pasta e renomear os arquivos.
|
||||||
|
|
||||||
|
```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);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Para que o shader funcione nas versões anteriores a 2.1, você precisa adicionar as seguintes linhas de código no começo do seu shader: `#define PROCESSING_COLOR_SHADER`. Algo parecido 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ção sobre shaders em Processing, dê uma olhada neste [tutorial](https://processing.org/tutorials/pshader/).
|
||||||
|
|
||||||
|
### Em **openFrameworks**
|
||||||
|
|
||||||
|
Todos tem um lugar no qual se sentem confortáveis, no meu caso, ainda é na [comunidade de openFrameworks](http://openframeworks.cc/). Esta framework C++ engloba OpenGL e outras bibliotecas C++ open source. É muito parecida com Processing, mas com as complicações óbvias de lidar com compiladores C++. Do mesmo jeito que Processing, openFrameworks procura pelos seus arquivos de shader na pasta data, então não se esqueça de copiar os arquivos `.frag` que você quer usar e os renomear quando carregá-los.
|
||||||
|
|
||||||
|
```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ção sobre shaders em openFrameworks, vá para este [excelente tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) feito por [Joshua Noble](http://thefactoryfactory.com/).
|
@ -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, nós aprendemos como criar algumas formas - o truque para mover estas formas é mover o próprio sistema de coordenadas. Nós fazemos isso simplesmente adicionando um vetor às variáveis ```st``` que contem a localização de cada fragmento. Isso fará com que todo o espaço de coordenadas se mova.
|
||||||
|
|
||||||
|
![](translate.jpg)
|
||||||
|
|
||||||
|
Isso é mais fácil de enxergar do que explicar, veja você mesmo:
|
||||||
|
|
||||||
|
* Descomente as linhas 35 do código abaixo e veja como o próprio espaço se move.
|
||||||
|
|
||||||
|
<div class="codeAndCanvas" data="cross-translate.frag"></div>
|
||||||
|
|
||||||
|
Agora implemente os seguintes exercícios:
|
||||||
|
|
||||||
|
* Usando ```u_time``` junto com a modelagem de função, mova a pequena cruz de uma forma interessante. Procure por uma específica qualidade de movimento que você se interessa e tente fazer com que a cruz se mova da mesma forma. Se lembrando de algo suave do "mundo real" primeiramente pode ser útil - Pode ser as ondas que vem e vão de um pêndulo, uma bola quicando, um carro acelerando uma bicicleta parando.
|
||||||
|
|
||||||
|
### Rotações
|
||||||
|
|
||||||
|
Para rotacionarmos objetos, também precisamos mexer todo o sistema espacial. Para isso, nós iremos usar uma [matriz](http://en.wikipedia.org/wiki/Matrix_%28mathematics%29). Uma matriz é um conjunto organizado de números em linhas e colunas. Vetores são multiplicados por matrizes seguindo um preciso conjunto de ordens para modificar os valores do vetor em uma forma particular.
|
||||||
|
|
||||||
|
[![Artigo da wikipedia sobre matrizes (matemática) ](matrixes.png)](https://en.wikipedia.org/wiki/Matrix)
|
||||||
|
|
||||||
|
GLSL tem um suporte nativo para matrizes de duas, três e quatro dimensões: [```mat2```](../glossary/?search=mat2) (2x2), [```mat3```](../glossary/?search=mat3) (3x3) e [```mat4```](../glossary/?search=mat4) (4x4). GLSL também suporta multiplicação de matrizes (```*```) e uma função específica para matriz ([```matrixCompMult()```](../glossary/?search=matrixCompMult)).
|
||||||
|
|
||||||
|
Baseado em como matrizes se comportam, é possível construir matrizes para produzir comportamentos específicos. Por exemplo, nós podemos usar matriz para transladar um vetor:
|
||||||
|
|
||||||
|
![](3dtransmat.png)
|
||||||
|
|
||||||
|
E mais interessante ainda, podemos usar uma matriz para rotacionar um sistema de coordenadas:
|
||||||
|
|
||||||
|
![](rotmat.png)
|
||||||
|
|
||||||
|
Dê uma olhada no seguinte código para uma função que constrói uma matriz de rotação bidimensional. Esta função segue a [formula](http://en.wikipedia.org/wiki/Rotation_matrix) acima para vetores de duas dimensões rotacionarem 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 o jeito que estamos desenhando formas, isto não é exatamente o que queremos. Nossa forma de cruz está desenhada no centro do canvas, que corresponde a posição ```vec2(0.5)```. Então, antes de rotacionarmos o espaço, nós precisamos mover a forma, do `centro` para a coordenada ```vec2(0.0)```, rotacionar o espaço, e então, finalmente, move-la de volta ao seu lugar original.
|
||||||
|
|
||||||
|
![](rotate.jpg)
|
||||||
|
|
||||||
|
Isso se parece com o seguinte código:
|
||||||
|
|
||||||
|
<div class="codeAndCanvas" data="cross-rotate.frag"></div>
|
||||||
|
|
||||||
|
Tente os seguintes exercícios:
|
||||||
|
|
||||||
|
* 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 consequencias.
|
||||||
|
|
||||||
|
* Use rotações para melhorar a animação que você simulou no exercício de translação.
|
||||||
|
|
||||||
|
### Escala
|
||||||
|
|
||||||
|
Nós vimos como matrizes são usadas para mover e rotacionar objetos no espaço. (Ou mais precisamente, transformar o sistema de coordenadas para rotacionar e mover os objetos.) Se você já usou um software de modelagem 3D ou o as funções de matrizes push e pop em Processing, você verá que matrizes também podem ser usadas para escalonar o tamanho de um objeto.
|
||||||
|
|
||||||
|
![](scale.png)
|
||||||
|
|
||||||
|
Se baseando na fórmula anterior, podemos descobrir como fazer uma matriz 2D de escala:
|
||||||
|
|
||||||
|
```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 exercícios para entender mais profundamente como isso funciona.
|
||||||
|
|
||||||
|
* Descomente a linha 42 do código acima para ver coordenadas espaciais serem escalonadas.
|
||||||
|
|
||||||
|
* Veja o que acontece quando você comenta as translações antes e depois de escalonar nas linhas 37 and 39.
|
||||||
|
|
||||||
|
* Tente combinar a matriz de rotação junto com a matriz de escala. Note que a ordem das matrizes importa. Multiplique primeiramente pela matriz e então, multiplique os vetores.
|
||||||
|
|
||||||
|
* Agora que você sabe como desenhar diferentes formas, e mover rotacionar e escalona-las, stá na hora de fazer uma ótima composição. Projete e construa uma fake UI or HUD (heads up display)](https://www.pinterest.com/patriciogonzv/huds/). Use os seguintes exemplos do Shadertoy [Ndel](https://www.shadertoy.com/user/ndel) como referência e inspiração.
|
||||||
|
|
||||||
|
<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 sistema de codificação de cores usado para transmissão analógica de fotos e vídeos que leva em consideração a percepção humana para reduzir a largura de banda dos componentes de crominância.
|
||||||
|
|
||||||
|
O código a seguir é uma interessante oportunidade de usar operações de matrizes em GLSL e transformar as cores de um modo para outro.
|
||||||
|
|
||||||
|
<div class="codeAndCanvas" data="yuv.frag"></div>
|
||||||
|
|
||||||
|
Como você pode ver, nós estamos tratando cores como vetores quando multiplicamos elas pelas matrizes. Desta forma podemos "mover" os valores.
|
||||||
|
|
||||||
|
Neste capítulo, nós aprendemos como usar transformações de matrizes para mover, rotacionar e escalonar vetores. Estas transformações serão essenciais para criar as composições além das formas que aprendemos no capítulo anterior. No próximo capítulo, nós vamos aplicat tudo que aprendemos para criar lindos padrões procedurais. Você irá descobrir que programar repetições e variações podem ser uma empolgante prática.
|
Loading…
Reference in New Issue