Finally! We have been building skills for this moment! You have learned most of the GLSL foundations, types and functions. You have practiced your shaping equations over and over. Now is the time to put it all together. You are up for this challenge! In this chapter you'll learn how to draw simple shapes in a parallel procedural way.
Imagine we have grid paper like we used in math classes and our homework is to draw a square. The paper size is 10x10 and the square is supposed to be 8x8. What will you do?
You'd paint everything except the first and last rows and the first and last column, right?
一番上と下の行、両端の列を除いてすべてを塗りつぶしませばよいですね。
一番上と下の行、左右両端の列を除いてすべてを塗りつぶせばよいですね。
How does this relate to shaders? Each little square of our grid paper is a thread (a pixel). Each little square knows its position, like the coordinates of a chess board. In previous chapters we mapped *x* and *y* to the *red* and *green* color channels, and we learned how to use the narrow two dimensional territory between 0.0 and 1.0. How can we use this to draw a centered square in the middle of our billboard?
これがシェーダーになんの関係があるのでしょう。方眼紙の小さな正方形一つ一つはスレッド(ピクセル)です。それぞれの小さな正方形は自分の位置をチェス盤の上の行と列のように把握しています。以前の章でに私たちは x と y を赤と緑の色のチャンネルに割り当てました。私たちはまた 0.0 から 1.0 の間の狭い二次元の領域を使う方法も学んできました。この知識を生かして描画領域の中央に正方形を描くにはどうすれば良いでしょうか。
これがシェーダーになんの関係があるのでしょう。方眼紙の小さな正方形1つ1つはスレッド(ピクセル)です。それぞれの小さな正方形は自分の位置を、チェス盤上の行と列のように把握しています。以前の章で私たちは x と y を赤と緑の色のチャンネルに割り当てました。また 0.0 から 1.0 の間の狭い二次元の領域を使う方法も学んできました。描画領域の中央に正方形を描くのに、これらの知識をどう活かせばよいでしょうか。
Let's start by sketching pseudocode that uses ```if``` statements over the spatial field. The principles to do this are remarkably similar to how we think of the grid paper scenario.
@ -38,7 +37,7 @@ Let's start by sketching pseudocode that uses ```if``` statements over the spati
Now that we have a better idea of how this will work, let’s replace the ```if``` statement with [```step()```](../glossary/?search=step), and instead of using 10x10 let’s use normalized values between 0.0 and 1.0:
The [```step()```](../glossary/?search=step) function will turn every pixel below 0.1 to black (```vec3(0.0)```) and the rest to white (```vec3(1.0)```) . The multiplication between ```left``` and ```bottom``` works as a logical ```AND``` operation, where both must be 1.0 to return 1.0 . This draws two black lines, one on the bottom and the other on the left side of the canvas.
[```step()```](../glossary/?search=step) 関数は、 x か y が 0.1 より小さくなるピクセルを黒(```vec3(0.0)```)に、他のすべてのピクセルを白(```vec3(1.0)```)に変えてくれます。```left``` と ```bottom``` の掛け算は ```AND``` 演算の役割をして、両方ともの値が1.0だった場合にのみ1.0を返します。結果として描画領域の下側と左側に2本の黒い線が引かれることになります。
![](rect-01.jpg)
In the previous code we repeat the structure for each axis (left and bottom). We can save some lines of code by passing two values directly to [```step()```](../glossary/?search=step) instead of one. That looks like this:
Uncomment and see how we invert the ```st``` coordinates and repeat the same [```step()```](../glossary/?search=step) function. That way the ```vec2(0.0,0.0)``` will be in the top right corner. This is the digital equivalent of flipping the page and repeating the previous procedure.
@ -97,14 +97,15 @@ Take note that in *lines 18 and 22* all of the sides are being multiplied togeth
Interesting right? This technique is all about using [```step()```](../glossary/?search=step) and multiplication for logical operations and flipping the coordinates.
Before going forward, try the following exercises:
さらに先に進む前に下記に挑戦しましょう。
さらに先に進む前に下記の課題に挑戦しましょう。
* Change the size and proportions of the rectangle.
* 長方形の大きさと縦横の比率を変えてみましょう。
* 長方形の大きさと縦横比を変えてみましょう。
* Experiment with the same code but using [```smoothstep()```](../glossary/?search=smoothstep) instead of [```step()```](../glossary/?search=step). Note that by changing values, you can go from blurred edges to elegant smooth borders.
@ -116,7 +117,7 @@ Before going forward, try the following exercises:
* Choose the implementation you like the most and make a function of it that you can reuse in the future. Make your function flexible and efficient.
* Make another function that just draws the outline of a rectangle.
@ -124,7 +125,7 @@ Before going forward, try the following exercises:
* How do you think you can move and place different rectangles in the same billboard? If you figure out how, show off your skills by making a composition of rectangles and colors that resembles a [Piet Mondrian](http://en.wikipedia.org/wiki/Piet_Mondrian) painting.
@ -138,7 +139,7 @@ It's easy to draw squares on grid paper and rectangles on cartesian coordinates,
How? Let's start by going back to math class and the grid paper, where we opened a compass to the radius of a circle, pressed one of the compass points at the center of the circle and then traced the edge of the circle with a simple spin.
@ -150,14 +151,14 @@ Translating this to a shader where each square on the grid paper is a pixel impl
There are several ways to calculate that distance. The easiest one uses the [```distance()```](../glossary/?search=distance) function, which internally computes the [```length()```](../glossary/?search=length) of the difference between two points (in our case the pixel coordinate and the center of the canvas). The ```length()``` function is nothing but a shortcut of the [hypotenuse equation](http://en.wikipedia.org/wiki/Hypotenuse) that uses square root ([```sqrt()```](../glossary/?search=sqrt)) internally.
You can use [```distance()```](../glossary/?search=distance), [```length()```](../glossary/?search=length) or [```sqrt()```](../glossary/?search=sqrt) to calculate the distance to the center of the billboard. The following code contains these three functions and the non-surprising fact that each one returns exactly same result.
* Comment and uncomment lines to try the different ways to get the same result.
* コメントを付け替えて、違う方法を使っても同じ結果が得られることを確かめましょう。
@ -165,40 +166,39 @@ You can use [```distance()```](../glossary/?search=distance), [```length()```](.
In the previous example we map the distance to the center of the billboard to the color brightness of the pixel. The closer a pixel is to the center, the lower (darker) value it has. Notice that the values don't get too high because from the center ( ```vec2(0.5, 0.5)``` ) the maximum distance barely goes over 0.5. Contemplate this map and think:
* Modify the above code in order to contain the entire circular gradient inside the canvas.
* コードを書き換えて円形のグラデーションの全体が病領域に収まるようにしてください。
* コードを書き換えて円形のグラデーションの全体が描画領域に収まるようにしてください。
### Distance field
### ディスタンスフィールド
We can also think of the above example as an altitude map, where darker implies taller. The gradient shows us something similar to the pattern made by a cone. Imagine yourself on the top of that cone. The horizontal distance to the edge of the cone is 0.5. This will be constant in all directions. By choosing where to “cut” the cone you will get a bigger or smaller circular surface.
Basically we are using a re-interpretation of the space (based on the distance to the center) to make shapes. This technique is known as a “distance field” and is used in different ways from font outlines to 3D graphics.
@ -243,7 +243,8 @@ In terms of computational power the [```sqrt()```](../glossary/?search=sqrt) fun
Distance fields can be used to draw almost everything. Obviously the more complex a shape is, the more complicated its equation will be, but once you have the formula to make distance fields of a particular shape it is very easy to combine and/or apply effects to it, like smooth edges and multiple outlines. Because of this, distance fields are popular in font rendering, like [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) and [as is describe on Chapter 7 of iPhone 3D Programming, O’Reilly](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921).
@ -257,20 +258,21 @@ Take a look at the following code.
We start by moving the coordinate system to the center and shrinking it in half in order to remap the position values between -1 and 1. Also on *line 24* we are visualizing the distance field values using a [```fract()```](../glossary/?search=fract) function making it easy to see the pattern they create. The distance field pattern repeats over and over like rings in a Zen garden.
Let’s take a look at the distance field formula on *line 19*. There we are calculating the distance to the position on ```(.3,.3)``` or ```vec3(.3)``` in all four quadrants (that’s what [```abs()```](../glossary/?search=abs) is doing there).
If you uncomment *line 20*, you will note that we are combining the distances to these four points using the [```min()```](../glossary/?search=min) to zero. The result produces an interesting new pattern.
Now try uncommenting *line 21*; we are doing the same but using the [```max()```](../glossary/?search=max) function. The result is a rectangle with rounded corners. Note how the rings of the distance field get smoother the further away they get from the center.
Finish uncommenting *lines 27 to 29* one by one to understand the different uses of a distance field pattern.
@ -284,7 +286,7 @@ Finish uncommenting *lines 27 to 29* one by one to understand the different uses
In the chapter about color we map the cartesian coordinates to polar coordinates by calculating the *radius* and *angles* of each pixel with the following formula: