relative paths as variables, glossary querry, code style

This commit is contained in:
Patricio Gonzalez Vivo 2015-07-17 16:24:23 -04:00
parent 050053e621
commit 1c190ea336
33 changed files with 365 additions and 326 deletions

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -19,5 +21,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -26,7 +26,7 @@ Enough talking, let's see the uniforms in action. In the following code we use `
<div class="codeAndCanvas" data="time.frag"></div>
As you can see GLSL has more surprises. The GPU has hardware accelerated angle, trigonometric and exponential functions. Some of those functions are: [```sin()```](http://www.shaderific.com/glsl-functions/#sine), [```cos()```](http://www.shaderific.com/glsl-functions/#cosine), [```tan()```](http://www.shaderific.com/glsl-functions/#tangent), [```asin()```](http://www.shaderific.com/glsl-functions/#arcsine), [```acos()```](http://www.shaderific.com/glsl-functions/#arccosine), [```atan()```](http://www.shaderific.com/glsl-functions/#arctangent), [```pow()```](http://www.shaderific.com/glsl-functions/#exponentiation), [```exp()```](http://www.shaderific.com/glsl-functions/#exponentiation), [```log()```](http://www.shaderific.com/glsl-functions/#naturallogarithm), [```sqrt()```](http://www.shaderific.com/glsl-functions/#squareroot), [```abs()```](http://www.shaderific.com/glsl-functions/#absolutevalue), [```sign()```](http://www.shaderific.com/glsl-functions/#sign), [```floor()```](http://www.shaderific.com/glsl-functions/#floor), [```ceil()```](http://www.shaderific.com/glsl-functions/#ceiling), [```fract()```](http://www.shaderific.com/glsl-functions/#fractionalpart), [```mod()```](http://www.shaderific.com/glsl-functions/#modulo), [```min()```](http://www.shaderific.com/glsl-functions/#minimum), [```max()```](http://www.shaderific.com/glsl-functions/#maximum) and [```clamp()```](http://www.shaderific.com/glsl-functions/#clamp).
As you can see GLSL has more surprises. The GPU has hardware accelerated angle, trigonometric and exponential functions. Some of those functions are: [```sin()```](../glossary/?search=sin), [```cos()```](../glossary/?search=cos), [```tan()```](../glossary/?search=tan), [```asin()```](../glossary/?search=asin), [```acos()```](../glossary/?search=acos), [```atan()```](../glossary/?search=atan), [```pow()```](../glossary/?search=pow), [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log), [```sqrt()```](../glossary/?search=sqrt), [```abs()```](../glossary/?search=abs), [```sign()```](../glossary/?search=sign), [```floor()```](../glossary/?search=floor), [```ceil()```](../glossary/?search=ceil), [```fract()```](../glossary/?search=fract), [```mod()```](../glossary/?search=mod), [```min()```](../glossary/?search=min), [```max()```](../glossary/?search=max) and [```clamp()```](../glossary/?search=clamp).
Now it is time again to play with the above code.

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -19,25 +19,25 @@ This one-to-one relationship between *x* and *y* (or the brightness) is know as
Interesting, right? On line 19 try different exponents: 20.0, 2.0, 1.0, 0.0, 0.2 and 0.02 for example. Understanding this relationship between the value and the exponent will be very helpful. Using these types of mathematical functions here and there will give you expressive control over your code, a sort of data acupuncture that let you control the flow of values.
[```pow()```](../glossary/index.html#pow.md) is a native function in GLSL and there are many others. Most of them are accelerated at the level of the hardware, which means if they are used in the right way and with discretion they will make your code faster.
[```pow()```](../glossary/?search=pow) is a native function in GLSL and there are many others. Most of them are accelerated at the level of the hardware, which means if they are used in the right way and with discretion they will make your code faster.
Replace the power function on line 19. Try other ones like: [```exp()```](../glossary/index.html#exp.md), [```log()```](../glossary/index.html#log.md) and [```sqrt()```](../glossary/index.html#sqrt.md). Some of these functions are more interesting when you play with them using PI. You can see on line 5 that I have defined a macro that will replace any call to ```PI``` with the value ```3.14159265359```.
Replace the power function on line 19. Try other ones like: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) and [```sqrt()```](../glossary/?search=sqrt). Some of these functions are more interesting when you play with them using PI. You can see on line 5 that I have defined a macro that will replace any call to ```PI``` with the value ```3.14159265359```.
### Step and Smoothstep
GLSL also has some unique native interpolation functions that are hardware accelerated.
The [```step()```](../glossary/index.html#step.md) interpolation receives two parameters. The first one is the limit or threshold, while the second one is the value we want to check or pass. Any value under the limit will return ```0.0``` while everything above the limit will return ```1.0```.
The [```step()```](../glossary/?search=step) interpolation receives two parameters. The first one is the limit or threshold, while the second one is the value we want to check or pass. Any value under the limit will return ```0.0``` while everything above the limit will return ```1.0```.
Try changing this threshold value on line 20 of the following code.
<div class="codeAndCanvas" data="step.frag"></div>
The other unique function is known as [```smoothstep()```](../glossary/index.html#smoothstep.md). Given a range of two numbers and a value, this function will interpolate the value between the defined range. The two first parameters are for the beginning and end of the transition, while the third is for the value to interpolate.
The other unique function is known as [```smoothstep()```](../glossary/?search=smoothstep). Given a range of two numbers and a value, this function will interpolate the value between the defined range. The two first parameters are for the beginning and end of the transition, while the third is for the value to interpolate.
<div class="codeAndCanvas" data="smoothstep.frag"></div>
In the previous example, on line 12, notice that weve been using smoothstep to draw the green line on the ```plot()``` function. For each position along the *x* axis this function makes a *bump* at a particular value of *y*. How? By connecting two [```smoothstep()```](../glossary/index.html#smoothstep.md) together. Take a look at the following function, replace it for line 20 above and think of it as a vertical cut. The background does look like a line, right?
In the previous example, on line 12, notice that weve been using smoothstep to draw the green line on the ```plot()``` function. For each position along the *x* axis this function makes a *bump* at a particular value of *y*. How? By connecting two [```smoothstep()```](../glossary/?search=smoothstep) together. Take a look at the following function, replace it for line 20 above and think of it as a vertical cut. The background does look like a line, right?
```glsl
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
@ -47,7 +47,7 @@ In the previous example, on line 12, notice that weve been using smoothstep t
When you want to use some math to animate, shape or blend values, there is nothing better than being friends with sine and cosine.
These two basic trigonometric functions work together to construct circles that are as handy as MacGyvers Swiss army knife. Its important to know how they behave and in what ways they can be combined. In a nutshell, given an angle (in radians) they will return the correct position of *x* ([cosine](../glossary/index.html#cos.md)) and *y* ([sine](../glossary/index.html#sin.md)) of a point on the edge of a circle with a radius equal to 1. But, the fact that they return normalized values (values between -1 and 1) in such a smooth way makes them an incredible tool.
These two basic trigonometric functions work together to construct circles that are as handy as MacGyvers Swiss army knife. Its important to know how they behave and in what ways they can be combined. In a nutshell, given an angle (in radians) they will return the correct position of *x* ([cosine](../glossary/?search=cos)) and *y* ([sine](../glossary/?search=sin)) of a point on the edge of a circle with a radius equal to 1. But, the fact that they return normalized values (values between -1 and 1) in such a smooth way makes them an incredible tool.
![](sincos.gif)
@ -55,7 +55,7 @@ While it's difficult to describe all the relationships between trigonometric fun
<div class="simpleFunction" data="y = sin(x);"></div>
Take a careful look at this sine wave. Note how the *y* values flow smoothly between +1 and -1. As we saw in the time example in the previous chapter, you can use this rhythmic behavior of [```sin()```](../glossary/index.html#sin.md) to animate properties. If you are reading this example in a browser you will see that the you can change the code in the formula above to watch how the wave changes. (Note: don't forget the semicolon at the end of the lines.)
Take a careful look at this sine wave. Note how the *y* values flow smoothly between +1 and -1. As we saw in the time example in the previous chapter, you can use this rhythmic behavior of [```sin()```](../glossary/?search=sin) to animate properties. If you are reading this example in a browser you will see that the you can change the code in the formula above to watch how the wave changes. (Note: don't forget the semicolon at the end of the lines.)
Try the following exercises and notice what happens:
@ -65,15 +65,15 @@ Try the following exercises and notice what happens:
* Multiply time (```u_time```) by *x* before computing the ```sin```. See how the **frequency** between phases becomes more and more compressed. Note that u_time may have already become very large, making the graph hard to read.
* Add 1.0 to [```sin(x)```](../glossary/index.html#sin.md). See how all the wave is **displaced** up and now all values are between 0.0 and 2.0.
* Add 1.0 to [```sin(x)```](../glossary/?search=sin). See how all the wave is **displaced** up and now all values are between 0.0 and 2.0.
* Multiply [```sin(x)```](../glossary/index.html#sin.md) by 2.0. See how the **amplitude** doubles in size.
* Multiply [```sin(x)```](../glossary/?search=sin) by 2.0. See how the **amplitude** doubles in size.
* Compute the absolute value ([```abs()```](../glossary/index.html#abs.md)) of ```sin(x)```. It looks like the trace of a **bouncing** ball.
* Compute the absolute value ([```abs()```](../glossary/?search=abs)) of ```sin(x)```. It looks like the trace of a **bouncing** ball.
* Extract just the fraction part ([```fract()```](../glossary/index.html#fract.md)) of the resultant of [```sin(x)```](../glossary/index.html#sin.md).
* Extract just the fraction part ([```fract()```](../glossary/?search=fract)) of the resultant of [```sin(x)```](../glossary/?search=sin).
* Add the higher integer ([```ceil()```](../glossary/index.html#ceil.md)) and the smaller integer ([```floor()```](../glossary/index.html#floor.md)) of the resultant of [```sin(x)```](../glossary/index.html#sin.md) to get a digital wave of 1 and -1 values.
* Add the higher integer ([```ceil()```](../glossary/?search=ceil)) and the smaller integer ([```floor()```](../glossary/?search=floor)) of the resultant of [```sin(x)```](../glossary/?search=sin) to get a digital wave of 1 and -1 values.
### Some extra useful functions

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -54,7 +54,7 @@ You might not be used to picking colors with numbers - it can be very counterint
### Mixing color
Now that you know how colors are defined, it's time to integrate this with our previous knowledge. In GLSL there is a very useful function, [```mix()```](../glossary/index.html#mix.md), that lets you mix two values in percentages. Can you guess what the percentage range is? Yes, values between 0.0 and 1.0! Which is perfect for you, after those long hours practicing your karate moves with the fence - it is time to use them!
Now that you know how colors are defined, it's time to integrate this with our previous knowledge. In GLSL there is a very useful function, [```mix()```](../glossary/?search=mix), that lets you mix two values in percentages. Can you guess what the percentage range is? Yes, values between 0.0 and 1.0! Which is perfect for you, after those long hours practicing your karate moves with the fence - it is time to use them!
![](mix-f.jpg)
@ -68,7 +68,7 @@ Show off your skills by:
### Playing with gradients
The [```mix()```](../glossary/index.html#mix.md) function has more to offer. Instead of a single ```float```, we can pass a variable type that matches the two first arguments, in our case a ```vec3```. By doing that we gain control over the mixing percentages of each individual color channel, ```r```, ```g``` and ```b```.
The [```mix()```](../glossary/?search=mix) function has more to offer. Instead of a single ```float```, we can pass a variable type that matches the two first arguments, in our case a ```vec3```. By doing that we gain control over the mixing percentages of each individual color channel, ```r```, ```g``` and ```b```.
![](mix-vec.jpg)
@ -102,13 +102,13 @@ By mapping the position on the x axis to the Hue and the position on the y axis
### HSB in polar coordinates
HSB was originally designed to be represented in polar coordinates (based on the angle and radius) instead of cartesian coordinates (based on x and y). To map our HSB function to polar coordinates we need to obtain the angle and distance from the center of the billboard to the pixel coordinate. For that we will use the [```length()```](../glossary/index.html#length.md) function and [```atan(y,x)```](../glossary/index.html#atan.md) (which is the GLSL version of the commonly used ```atan2(y,x)```).
HSB was originally designed to be represented in polar coordinates (based on the angle and radius) instead of cartesian coordinates (based on x and y). To map our HSB function to polar coordinates we need to obtain the angle and distance from the center of the billboard to the pixel coordinate. For that we will use the [```length()```](../glossary/?search=length) function and [```atan(y,x)```](../glossary/?search=atan) (which is the GLSL version of the commonly used ```atan2(y,x)```).
When using vector and trigonometric functions, ```vec2```, ```vec3``` and ```vec4``` are treated as vectors even when they represent colors. We will start treating colors and vectors similarly, in fact you will come to find this conceptual flexibility very empowering.
**Note:** If you were wondering, there are more geometric functions besides [```length```](../glossary/index.html#length.md) like: [```distance()```](../glossary/index.html#distance.md), [```dot()```](../glossary/index.html#dot.md), [```cross```](../glossary/index.html#cross.md), [```normalize()```](../glossary/index.html#normalize.md), [```faceforward()```](../glossary/index.html#fraceforward.md), [```reflect()```](../glossary/index.html#reflect.md) and [```refract()```](../glossary/index.html#refract.md). Also GLSL has special vector relational functions such as: [```lessThan()```](../glossary/index.html#lessThan.md), [```lessThanEqual()```](../glossary/index.html#lessThanEqual.md), [```greaterThan()```](../glossary/index.html#greaterThan.md), [```greaterThanEqual()```](../glossary/index.html#greaterThanEqual.md), [```equal()```](../glossary/index.html#equal.md) and [```notEqual()```](../glossary/index.html#notEqual.md).
**Note:** If you were wondering, there are more geometric functions besides [```length```](../glossary/?search=length) like: [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=fraceforward), [```reflect()```](../glossary/?search=reflect) and [```refract()```](../glossary/?search=refract). Also GLSL has special vector relational functions such as: [```lessThan()```](../glossary/?search=lessThan), [```lessThanEqual()```](../glossary/?search=lessThanEqual), [```greaterThan()```](../glossary/?search=greaterThan), [```greaterThanEqual()```](../glossary/?search=greaterThanEqual), [```equal()```](../glossary/?search=equal) and [```notEqual()```](../glossary/?search=notEqual).
Once we obtain the angle and length we need to “normalize” their values to the range between 0.0 to 1.0. On line 27, [```atan(y,x)```](../glossary/index.html#atan.md) will return an angle in radians between -PI and PI (-3.14 to 3.14), so we need to divide this number by ```TWO_PI``` (defined at the top of the code) to get values between -0.5 to 0.5, which by simple addition we change to the desired range of 0.0 to 1.0. The radius will return a maximum of 0.5 (because we are calculating the distance from the center of the viewport) so we need to double this range (by multiplying by two) to get a maximum of 1.0.
Once we obtain the angle and length we need to “normalize” their values to the range between 0.0 to 1.0. On line 27, [```atan(y,x)```](../glossary/?search=atan) will return an angle in radians between -PI and PI (-3.14 to 3.14), so we need to divide this number by ```TWO_PI``` (defined at the top of the code) to get values between -0.5 to 0.5, which by simple addition we change to the desired range of 0.0 to 1.0. The radius will return a maximum of 0.5 (because we are calculating the distance from the center of the viewport) so we need to double this range (by multiplying by two) to get a maximum of 1.0.
As you can see, our game here is all about transforming and mapping ranges to the 0.0 to 1.0 that we like.

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -23,7 +23,7 @@ Let's start by sketching pseudocode that uses ```if``` statements over the spati
paint black
```
Now that we have a better idea of how this will work, lets replace the ```if``` statement with [```step()```](../glossary/index.html#step.md), and instead of using 10x10 lets use normalized values between 0.0 and 1.0:
Now that we have a better idea of how this will work, lets replace the ```if``` statement with [```step()```](../glossary/?search=step), and instead of using 10x10 lets use normalized values between 0.0 and 1.0:
```glsl
uniform vec2 u_resolution;
@ -43,11 +43,11 @@ void main(){
}
```
The [```step()```](../glossary/index.html#step.md) 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.
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.
![](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/index.html#step.md) instead of one. That looks like this:
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:
```glsl
vec2 borders = step(vec2(0.1),st);
@ -58,7 +58,7 @@ So far, weve only drawn two borders (bottom-left) of our rectangle. Let's do
<div class="codeAndCanvas" data="rect-making.frag"></div>
Uncomment *lines 21-22* and see how we invert the ```st``` coordinates and repeat the same [```step()```](../glossary/index.html#step.md) 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.
Uncomment *lines 21-22* 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.
![](rect-02.jpg)
@ -70,15 +70,15 @@ Take note that in *lines 18 and 22* all of the sides are being multiplied togeth
color = vec3(bl.x * bl.y * tr.x * tr.y);
```
Interesting right? This technique is all about using [```step()```](../glossary/index.html#step.md) and multiplication for logical operations and flipping the coordinates.
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/index.html#smoothstep.md) instead of [```step()```](../glossary/index.html#step.md). Note that by changing values, you can go from blurred edges to elegant smooth borders.
* 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.
* Do another implementation that uses [```floor()```](../glossary/index.html#floor.md).
* Do another implementation that uses [```floor()```](../glossary/?search=floor).
* 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.
@ -90,7 +90,7 @@ Before going forward, try the following exercises:
### Circles
It's easy to draw squares on grid paper and rectangles on cartesian coordinates, but circles require another approach, especially since we need a "per-pixel" algorithm. One solution is to *re-map* the spatial coordinates so that we can use a [```step()```](../glossary/index.html#step.md) function to draw a circle.
It's easy to draw squares on grid paper and rectangles on cartesian coordinates, but circles require another approach, especially since we need a "per-pixel" algorithm. One solution is to *re-map* the spatial coordinates so that we can use a [```step()```](../glossary/?search=step) function to draw a circle.
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.
@ -100,11 +100,11 @@ Translating this to a shader where each square on the grid paper is a pixel impl
![](circle.jpg)
There are several ways to calculate that distance. The easiest one uses the [```distance()```](../glossary/index.html#distance.md) function, which internally computes the [```length()```](../glossary/index.html#length.md) 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/index.html#sqrt.md)) internally.
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.
![](hypotenuse.png)
You can use [```distance()```](../glossary/index.html#distance.md), [```length()```](../glossary/index.html#length.md) or [```sqrt()```](../glossary/index.html#sqrt.md) 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.
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.
@ -128,11 +128,11 @@ Basically we are using a re-interpretation of the space (based on the distance t
Try the following exercises:
* Use [```step()```](../glossary/index.html#step.md) to turn everything above 0.5 to white and everything below to 0.0.
* Use [```step()```](../glossary/?search=step) to turn everything above 0.5 to white and everything below to 0.0.
* Inverse the colors of the background and foreground.
* Using [```smoothstep()```](../glossary/index.html#smoothstep.md), experiment with different values to get nice smooth borders on your circle.
* Using [```smoothstep()```](../glossary/?search=smoothstep), experiment with different values to get nice smooth borders on your circle.
* Once you are happy with an implementation, make a function of it that you can reuse in the future.
@ -156,7 +156,7 @@ pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
#### For your tool box
In terms of computational power the [```sqrt()```](../glossary/index.html#sqrt.md) function - and all the functions that depend on it - can be expensive. Here is another way to create a circular distance field by using [```dot()```](../glossary/index.html#dot.md) product.
In terms of computational power the [```sqrt()```](../glossary/?search=sqrt) function - and all the functions that depend on it - can be expensive. Here is another way to create a circular distance field by using [```dot()```](../glossary/?search=dot) product.
<div class="codeAndCanvas" data="circle.frag"></div>
@ -170,13 +170,13 @@ Take a look at the following code.
<div class="codeAndCanvas" data="rect-df.frag"></div>
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/index.html#fract.md) function making it easy to see the pattern they create. The distance field pattern repeats over and over like rings in a Zen garden.
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.
Lets 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 (thats what [```abs()```](../glossary/index.html#abs.md) is doing there).
Lets 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 (thats 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/index.html#min.md) to zero. The result produces an interesting new pattern.
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/index.html#max.md) 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.
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.
@ -192,7 +192,7 @@ In the chapter about color we map the cartesian coordinates to polar coordinates
float a = atan(pos.y,pos.x);
```
We use part of this formula at the beginning of the chapter to draw a circle. We calculated the distance to the center using [```length()```](../glossary/index.html#length.md). Now that we know about distance fields we can learn another way of drawing shapes using polar coordinates.
We use part of this formula at the beginning of the chapter to draw a circle. We calculated the distance to the center using [```length()```](../glossary/?search=length). Now that we know about distance fields we can learn another way of drawing shapes using polar coordinates.
This technique is a little restrictive but very simple. It consists of changing the radius of a circle depending on the angle to achieve different shapes. How does the modulation work? Yes, using shaping functions!
@ -214,7 +214,7 @@ Try to:
### Combining powers
Now that we've learned how to modulate the radius of a circle according to the angle using the [```atan()```](../glossary/index.html#atan.md) to draw different shapes, we can learn how use ```atan()``` with distance fields and apply all the tricks and effects possible with distance fields.
Now that we've learned how to modulate the radius of a circle according to the angle using the [```atan()```](../glossary/?search=atan) to draw different shapes, we can learn how use ```atan()``` with distance fields and apply all the tricks and effects possible with distance fields.
The trick will use the number of edges of a polygon to construct the distance field using polar coordinates. Check out [the following code](http://thndl.com/square-shaped-shaders.html) from [Andrew Baldwin](https://twitter.com/baldand).
@ -222,7 +222,7 @@ The trick will use the number of edges of a polygon to construct the distance fi
* Using this example, make a function that inputs the position and number of corners of a desired shape and returns a distance field value.
* Mix distance fields together using [```min()```](../glossary/index.html#min.md) and [```max()```](../glossary/index.html#max.md).
* Mix distance fields together using [```min()```](../glossary/?search=min) and [```max()```](../glossary/?search=max).
* Choose a geometric logo to replicate using distance fields.

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -24,7 +24,7 @@ To rotate objects we also need to move the entire space system. For that we are
[![Wikipedia entry for Matrix (mathematics) ](matrixes.png)](https://en.wikipedia.org/wiki/Matrix)
GLSL has native support for two, three and four dimensional matrices: [```mat2```](../glossary/index.html#mat2.md) (2x2), [```mat3```](../glossary/index.html#mat3.md) (3x3) and [```mat4```](../glossary/index.html#mat4.md) (4x4). GLSL also supports matrix multiplication (```*```) and a matrix specific function ([```matrixCompMult()```](../glossary/index.html#matrixCompMult.md)).
GLSL has native support for two, three and four dimensional matrices: [```mat2```](../glossary/?search=mat2) (2x2), [```mat3```](../glossary/?search=mat3) (3x3) and [```mat4```](../glossary/?search=mat4) (4x4). GLSL also supports matrix multiplication (```*```) and a matrix specific function ([```matrixCompMult()```](../glossary/?search=matrixCompMult)).
Based on how matrices behave it's possible to construct matrices to produce specific behaviors. For example we can use a matrix to translate a vector:

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -8,7 +8,7 @@ In this chapter we are going to apply what we've learned so far and repeat it al
*"The grid provides a framework within which human intuition and invention can operate and that it can subvert. Within the chaos of nature patterns provide a constrast and promise of order. From early patterns on pottery to geometric mosaics in Roman baths, people have long used grids to enhance their lives with decoration."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/)
First let's remember the [```fract()```](../glossary/index.html#fract.md) function, which is in essence the modulo of one ([```mod(x,1.0)```](../glossary/index.html#mod.md)) because it returns the fractional part of a number. In other words, [```fract()```](../glossary/index.html#fract.md) returns the number after the floating point. Our normalized coordinate system variable (```st```) already goes from 0.0 to 1.0 so it doesn't make sense to do something like:
First let's remember the [```fract()```](../glossary/?search=fract) function, which is in essence the modulo of one ([```mod(x,1.0)```](../glossary/?search=mod)) because it returns the fractional part of a number. In other words, [```fract()```](../glossary/?search=fract) returns the number after the floating point. Our normalized coordinate system variable (```st```) already goes from 0.0 to 1.0 so it doesn't make sense to do something like:
```glsl
void main(){
@ -60,13 +60,13 @@ As a first step we need to know if the row of our thread is an even or odd numbe
____we have to fix these next two paragraphs together____
For that we are going to use [```mod()```](../glossary/index.html#mod.md) of ```2.0``` and then see if the result is under ```1.0``` or not. Take a look to the folowing formula and uncomment the two last lines.
For that we are going to use [```mod()```](../glossary/?search=mod) of ```2.0``` and then see if the result is under ```1.0``` or not. Take a look to the folowing formula and uncomment the two last lines.
<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>
As you can see we can use a [ternary operator](https://en.wikipedia.org/wiki/%3F:) to check if the [```mod()```](../glossary/index.html#mod.md) of ```2.0``` is under ```1.0``` (second line) or similarly we can use a [```step()```](../glossary/index.html#step.md) function which does that the same operation, but faster. Why? Althogh is hard to know how each graphic card optimize and compiles the code is safe to assume that built-ins functions are faster than non-built-in one. Everytime you can use one, use it!
As you can see we can use a [ternary operator](https://en.wikipedia.org/wiki/%3F:) to check if the [```mod()```](../glossary/?search=mod) of ```2.0``` is under ```1.0``` (second line) or similarly we can use a [```step()```](../glossary/?search=step) function which does that the same operation, but faster. Why? Althogh is hard to know how each graphic card optimize and compiles the code is safe to assume that built-ins functions are faster than non-built-in one. Everytime you can use one, use it!
So now we have our even number formula we can apply some offset to odd rows to give a *brick* effect to our tiles. Check lines 14 the following code, there we are using the function we just describe "detect odd" rows and give them an offset on ```x``` of half of unit. Note that by multipling by ```0.0``` even will make the offset similiar to ```0.0``` so we don't add any offset. But on odd rows we multipliy the result of our function (```1.0```) to the offset of ```0.5``` to the ```x``` axis of the coordinate system.

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -17,11 +19,8 @@
<ul class="navigationBar" >
<li class="navigationBar" onclick="previusPage()">&lt; &lt; Previous</li>
<li class="navigationBar" onclick="homePage()"> Home </li>
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>
<!--
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
-->

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -142,7 +142,7 @@ code {
border-radius: 4px;
}
.lang-bash {
.language-bash {
background-color: #ECECEC;
display: block;
@ -153,7 +153,7 @@ code {
border-radius: 6px;
}
.lang-glsl {
.language-glsl {
background-color: #ECECEC;
font-size: 14px;
@ -163,7 +163,7 @@ code {
border-radius: 6px;
}
.lang-cpp {
.language-cpp {
background-color: #ECECEC;
font-size: 14px;
@ -173,7 +173,7 @@ code {
border-radius: 6px;
}
.lang-html {
.language-html {
background-color: #ECECEC;
font-size: 14px;
@ -183,7 +183,7 @@ code {
border-radius: 6px;
}
.lang-processing {
.language-processing {
background-color: #ECECEC;
font-size: 14px;

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -20,5 +22,5 @@
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -4,7 +4,7 @@ echo '
<p> Copyright 2015 <a href="http://www.patriciogonzalezvivo.com" target="_blank">Patricio Gonzalez Vivo</a> </p>
</footer>
<script type="text/javascript" src="/src/main.js" defer></script>
<script type="text/javascript" src="'.$path.'/src/main.js" defer></script>
<script>
(function(i,s,o,g,r,a,m){i["GoogleAnalyticsObject"]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

View File

@ -4,274 +4,274 @@
* TYPES
[void](index.html#void.md)
[bool](index.html#bool.md)
[int](index.html#int.md)
[float](index.html#float.md)
[bvec2](index.html#bvec2.md)
[bvec3](index.html#bvec3.md)
[bvec4](index.html#bvec4.md)
[ivec2](index.html#ivec2.md)
[ivec3](index.html#ivec3.md)
[ivec4](index.html#ivec4.md)
[vec2](index.html#vec2.md)
[vec3](index.html#vec3.md)
[vec4](index.html#vec4.md)
[mat2](index.html#mat2.md)
[mat3](index.html#mat3.md)
[mat4](index.html#mat4.md)
[sampler2D](index.html#sampler2D.md)
[samplerCube](index.html#samplerCube.md)
[struct](index.html#struct.md)
[void](./?search=void)
[bool](./?search=bool)
[int](./?search=int)
[float](./?search=float)
[bvec2](./?search=bvec2)
[bvec3](./?search=bvec3)
[bvec4](./?search=bvec4)
[ivec2](./?search=ivec2)
[ivec3](./?search=ivec3)
[ivec4](./?search=ivec4)
[vec2](./?search=vec2)
[vec3](./?search=vec3)
[vec4](./?search=vec4)
[mat2](./?search=mat2)
[mat3](./?search=mat3)
[mat4](./?search=mat4)
[sampler2D](./?search=sampler2D)
[samplerCube](./?search=samplerCube)
[struct](./?search=struct)
* QUALIFIERS
[attribute](index.html#attribute.md)
[const](index.html#const.md)
[uniform](index.html#uniform.md)
[varying](index.html#varying.md)
[precision](index.html#precision.md)
[highp](index.html#highp.md)
[mediump](index.html#mediump.md)
[lowp](index.html#lowp.md)
[in](index.html#in.md)
[out](index.html#out.md)
[inout](index.html#inout.md)
[attribute](./?search=attribute)
[const](./?search=const)
[uniform](./?search=uniform)
[varying](./?search=varying)
[precision](./?search=precision)
[highp](./?search=highp)
[mediump](./?search=mediump)
[lowp](./?search=lowp)
[in](./?search=in)
[out](./?search=out)
[inout](./?search=inout)
* BUILT-IN VARIABLES
[gl_Position](index.html#gl_Position.md)
[gl_PointSize](index.html#gl_PointSize.md)
[gl_PointCoord](index.hmtl#gl_PointCoord.md)
[gl_FrontFacing](index.html#gl_FrontFacing.md)
[gl_FragCoord](index.html#gl_FragCoord.md)
[gl_FragColor](index.html#gl_FragColor.md)
[gl_Position](./?search=gl_Position)
[gl_PointSize](./?search=gl_PointSize)
[gl_PointCoord](index.hmtl#gl_PointCoord)
[gl_FrontFacing](./?search=gl_FrontFacing)
[gl_FragCoord](./?search=gl_FragCoord)
[gl_FragColor](./?search=gl_FragColor)
* BUILT-IN CONSTANTS
[gl_MaxVertexAttribs](index.html#gl_MaxVertexAttribs.md)
[gl_MaxVaryingVectors](index.html#gl_MaxVaryingVectors.md)
[gl_MaxVertexTextureImageUnits](index.html#gl_MaxVertexTextureImageUnits.md)
[gl_MaxCombinedTextureImageUnits](index.html#gl_MaxCombinedTextureImageUnits.md)
[gl_MaxTextureImageUnits](index.html#gl_MaxTextureImageUnits.md)
[gl_MaxFragmentUniformVectors](index.html#gl_MaxFragmentUniformVectors.md)
[gl_MaxDrawBuffers](index.html#gl_MaxDrawBuffers.md)
[gl_MaxVertexAttribs](./?search=gl_MaxVertexAttribs)
[gl_MaxVaryingVectors](./?search=gl_MaxVaryingVectors)
[gl_MaxVertexTextureImageUnits](./?search=gl_MaxVertexTextureImageUnits)
[gl_MaxCombinedTextureImageUnits](./?search=gl_MaxCombinedTextureImageUnits)
[gl_MaxTextureImageUnits](./?search=gl_MaxTextureImageUnits)
[gl_MaxFragmentUniformVectors](./?search=gl_MaxFragmentUniformVectors)
[gl_MaxDrawBuffers](./?search=gl_MaxDrawBuffers)
* ANGLE & TRIGONOMETRY FUNCTIONS
[radians()](index.html#radians.md)
[degrees()](index.html#degrees.md)
[sin()](index.html#sin.md)
[cos()](index.html#cos.md)
[tan()](index.html#tan.md)
[asin()](index.html#asin.md)
[acos()](index.html#acos.md)
[atan()](index.html#atan.md)
[radians()](./?search=radians)
[degrees()](./?search=degrees)
[sin()](./?search=sin)
[cos()](./?search=cos)
[tan()](./?search=tan)
[asin()](./?search=asin)
[acos()](./?search=acos)
[atan()](./?search=atan)
* EXPONENTIAL FUNCTIONS
[pow()](index.html#pow.md)
[exp()](index.html#exp.md)
[log()](index.html#log.md)
[exp2()](index.html#exp2.md)
[log2()](index.html#log2.md)
[sqrt()](index.html#sqrt.md)
[inversesqrt()](index.html#inversesqrt.md)
[pow()](./?search=pow)
[exp()](./?search=exp)
[log()](./?search=log)
[exp2()](./?search=exp2)
[log2()](./?search=log2)
[sqrt()](./?search=sqrt)
[inversesqrt()](./?search=inversesqrt)
* COMMON FUNCTIONS
[abs()](index.html#abs.md)
[sign()](index.html#sign.md)
[floor()](index.html#floor.md)
[ceil()](index.html#ceil.md)
[fract()](index.html#fract.md)
[mod()](index.html#mod.md)
[min()](index.html#min.md)
[max()](index.html#max.md)
[clamp()](index.html#clamp.md)
[mix()](index.html#mix.md)
[step()](index.html#step.md)
[smoothstep()](index.html#smoothstep.md)
[abs()](./?search=abs)
[sign()](./?search=sign)
[floor()](./?search=floor)
[ceil()](./?search=ceil)
[fract()](./?search=fract)
[mod()](./?search=mod)
[min()](./?search=min)
[max()](./?search=max)
[clamp()](./?search=clamp)
[mix()](./?search=mix)
[step()](./?search=step)
[smoothstep()](./?search=smoothstep)
* GEOMETRIC FUNCTIONS
[length()](index.html#length.md)
[distance()](index.html#distance.md)
[dot()](index.html#dot.md)
[cross()](index.html#cross.md)
[normalize()](index.html#normalize.md)
[facefoward()](index.html#facefoward.md)
[reflect()](index.html#reflect.md)
[refract()](index.html#refract.md)
[length()](./?search=length)
[distance()](./?search=distance)
[dot()](./?search=dot)
[cross()](./?search=cross)
[normalize()](./?search=normalize)
[facefoward()](./?search=facefoward)
[reflect()](./?search=reflect)
[refract()](./?search=refract)
* MATRIX FUNCTIONS
[matrixCompMult()](index.html#matrixCompMult.md)
[matrixCompMult()](./?search=matrixCompMult)
* VECTOR RELATIONAL FUNCTIONS
[lessThan()](index.html#lessThan.md)
[lessThanEqual()](index.html#lessThanEqual.md)
[greaterThan()](index.html#greaterThan.md)
[greaterThanEqual()](index.html#greaterThanEqual.md)
[equal()](index.html#equal.md)
[notEqual()](index.html#notEqual.md)
[any()](index.html#any.md)
[all()](index.html#all.md)
[not()](index.html#not.md)
[lessThan()](./?search=lessThan)
[lessThanEqual()](./?search=lessThanEqual)
[greaterThan()](./?search=greaterThan)
[greaterThanEqual()](./?search=greaterThanEqual)
[equal()](./?search=equal)
[notEqual()](./?search=notEqual)
[any()](./?search=any)
[all()](./?search=all)
[not()](./?search=not)
* TEXTURE LOOKUP FUNCTIONS
[texture2D()](index.html#texture2D.md)
[textureCube()](index.html#textureCube.md)
[texture2D()](./?search=texture2D)
[textureCube()](./?search=textureCube)
## Alphabetical
* A
[abs()](index.html#abs.md)
[acos()](index.html#acos.md)
[all()](index.html#all.md)
[any()](index.html#any.md)
[asin()](index.html#asin.md)
[atan()](index.html#atan.md)
[attribute](index.html#attribute.md)
[abs()](./?search=abs)
[acos()](./?search=acos)
[all()](./?search=all)
[any()](./?search=any)
[asin()](./?search=asin)
[atan()](./?search=atan)
[attribute](./?search=attribute)
* B
[bool](index.html#bool.md)
[bvec2](index.html#bvec2.md)
[bvec3](index.html#bvec3.md)
[bvec4](index.html#bvec4.md)
[bool](./?search=bool)
[bvec2](./?search=bvec2)
[bvec3](./?search=bvec3)
[bvec4](./?search=bvec4)
* C
[ceil()](index.html#ceil.md)
[clamp()](index.html#clamp.md)
[const](index.html#const.md)
[cos()](index.html#cos.md)
[cross()](index.html#cross.md)
[ceil()](./?search=ceil)
[clamp()](./?search=clamp)
[const](./?search=const)
[cos()](./?search=cos)
[cross()](./?search=cross)
* D
[degrees()](index.html#degrees.md)
[dFdx()](index.html#dFdx.md)
[dFdy()](index.html#dFdy.md)
[distance()](index.html#distance.md)
[dot()](index.html#dot.md)
[degrees()](./?search=degrees)
[dFdx()](./?search=dFdx)
[dFdy()](./?search=dFdy)
[distance()](./?search=distance)
[dot()](./?search=dot)
* E
[equal()](index.html#equal.md)
[exp()](index.html#exp.md)
[exp2()](index.html#exp2.md)
[equal()](./?search=equal)
[exp()](./?search=exp)
[exp2()](./?search=exp2)
* F
[faceforward()](index.html#faceforward.md)
[float](index.html#float.md)
[floor()](index.html#floor.md)
[fract()](index.html#fract.md)
[faceforward()](./?search=faceforward)
[float](./?search=float)
[floor()](./?search=floor)
[fract()](./?search=fract)
* G
[greaterThan()](index.html#greaterThan.md)
[greaterThanEqual()](index.html#greaterThanEqual.md)
[gl_FragColor](index.html#gl_FragColor.md)
[gl_FragCoord](index.html#gl_FragCoord.md)
[gl_FrontFacing](index.html#gl_FrontFacing.md)
[gl_PointCoord](index.hmtl#gl_PointCoord.md)
[gl_PointSize](index.html#gl_PointSize.md)
[gl_Position](index.html#gl_Position.md)
[gl_MaxCombinedTextureImageUnits](index.html#gl_MaxCombinedTextureImageUnits.md)
[gl_MaxDrawBuffers](index.html#gl_MaxDrawBuffers.md)
[gl_MaxFragmentUniformVectors](index.html#gl_MaxFragmentUniformVectors.md)
[gl_MaxVaryingVectors](index.html#gl_MaxVaryingVectors.md)
[gl_MaxVertexAttribs](index.html#gl_MaxVertexAttribs.md)
[gl_MaxVertexTextureImageUnits](index.html#gl_MaxVertexTextureImageUnits.md)
[gl_MaxTextureImageUnits](index.html#gl_MaxTextureImageUnits.md)
[greaterThan()](./?search=greaterThan)
[greaterThanEqual()](./?search=greaterThanEqual)
[gl_FragColor](./?search=gl_FragColor)
[gl_FragCoord](./?search=gl_FragCoord)
[gl_FrontFacing](./?search=gl_FrontFacing)
[gl_PointCoord](index.hmtl#gl_PointCoord)
[gl_PointSize](./?search=gl_PointSize)
[gl_Position](./?search=gl_Position)
[gl_MaxCombinedTextureImageUnits](./?search=gl_MaxCombinedTextureImageUnits)
[gl_MaxDrawBuffers](./?search=gl_MaxDrawBuffers)
[gl_MaxFragmentUniformVectors](./?search=gl_MaxFragmentUniformVectors)
[gl_MaxVaryingVectors](./?search=gl_MaxVaryingVectors)
[gl_MaxVertexAttribs](./?search=gl_MaxVertexAttribs)
[gl_MaxVertexTextureImageUnits](./?search=gl_MaxVertexTextureImageUnits)
[gl_MaxTextureImageUnits](./?search=gl_MaxTextureImageUnits)
* H
[highp](index.html#highp.md)
[highp](./?search=highp)
* I
[in](index.html#in.md)
[inout](index.html#inout.md)
[int](index.html#int.md)
[inversesqrt()](index.html#inversesqrt.md)
[ivec2](index.html#ivec2.md)
[ivec3](index.html#ivec3.md)
[ivec4](index.html#ivec4.md)
[in](./?search=in)
[inout](./?search=inout)
[int](./?search=int)
[inversesqrt()](./?search=inversesqrt)
[ivec2](./?search=ivec2)
[ivec3](./?search=ivec3)
[ivec4](./?search=ivec4)
* L
[length()](index.html#length.md)
[lessThan()](index.html#lessThan.md)
[lessThanEqual()](index.html#lessThanEqual.md)
[log()](index.html#log.md)
[log2()](index.html#log2.md)
[lowp](index.html#lowp.md)
[length()](./?search=length)
[lessThan()](./?search=lessThan)
[lessThanEqual()](./?search=lessThanEqual)
[log()](./?search=log)
[log2()](./?search=log2)
[lowp](./?search=lowp)
* M
[matrixCompMult()](index.html#matrixCompMult.md)
[mat2](index.html#mat2.md)
[mat3](index.html#mat3.md)
[mat4](index.html#mat4.md)
[max()](index.html#max.md)
[mediump](index.html#mediump.md)
[min()](index.html#min.md)
[mix()](index.html#mix.md)
[mod()](index.html#mod.md)
[matrixCompMult()](./?search=matrixCompMult)
[mat2](./?search=mat2)
[mat3](./?search=mat3)
[mat4](./?search=mat4)
[max()](./?search=max)
[mediump](./?search=mediump)
[min()](./?search=min)
[mix()](./?search=mix)
[mod()](./?search=mod)
* N
[normalize()](index.html#normalize.md)
[not()](index.html#not.md)
[notEqual()](index.html#notEqual.md)
[normalize()](./?search=normalize)
[not()](./?search=not)
[notEqual()](./?search=notEqual)
* O
[out](index.html#out.md)
[out](./?search=out)
* P
[precision](index.html#precision.md)
[pow()](index.html#pow.md)
[precision](./?search=precision)
[pow()](./?search=pow)
* R
[radians()](index.html#radians.md)
[reflect()](index.html#reflect.md)
[refract()](index.html#refract.md)
[radians()](./?search=radians)
[reflect()](./?search=reflect)
[refract()](./?search=refract)
* S
[sampler2D](index.html#sampler2D.md)
[samplerCube](index.html#samplerCube.md)
[sign()](index.html#sign.md)
[sin()](index.html#sin.md)
[smoothstep()](index.html#smoothstep.md)
[sqrt()](index.html#sqrt.md)
[step()](index.html#step.md)
[struct](index.html#struct.md)
[sampler2D](./?search=sampler2D)
[samplerCube](./?search=samplerCube)
[sign()](./?search=sign)
[sin()](./?search=sin)
[smoothstep()](./?search=smoothstep)
[sqrt()](./?search=sqrt)
[step()](./?search=step)
[struct](./?search=struct)
* T
[tan()](index.html#tan.md)
[texture2D()](index.html#texture2D.md)
[textureCube()](index.html#textureCube.md)
[tan()](./?search=tan)
[texture2D()](./?search=texture2D)
[textureCube()](./?search=textureCube)
* U
[uniform](index.html#uniform.md)
[uniform](./?search=uniform)
* V
[varying](index.html#varying.md)
[vec2](index.html#vec2.md)
[vec3](index.html#vec3.md)
[vec4](index.html#vec4.md)
[void](index.html#void.md)
[varying](./?search=varying)
[vec2](./?search=vec2)
[vec3](./?search=vec3)
[vec4](./?search=vec4)
[void](./?search=void)

View File

@ -1,6 +1,8 @@
<?php
include("../header.php");
include("../src/parsedown/Parsedown.php");
$path = "..";
include($path."/header.php");
include($path."/src/parsedown/Parsedown.php");
echo '
<div class="header"><p><a href="http://patriciogonzalezvivo.com/2015/thebookofshaders/">The Book of Shaders</a> by <a href="http://patriciogonzalezvivo.com">Patricio Gonzalez Vivo</a></p></div>
@ -12,11 +14,11 @@
if(empty($_GET))
echo $Parsedown->text(file_get_contents ('README.md'));
else
echo $Parsedown->text(file_get_contents ( $_GET['load'] ));
echo $Parsedown->text(file_get_contents ( $_GET['search'].'.md' ));
echo '
</div>
<hr>';
include("../footer.php");
include($path."/footer.php");
?>

View File

@ -11,33 +11,32 @@ echo '
<meta name="description" content="This is a gentle step-by-step guide through the abstract and complex universe of Fragment Shaders." />
<!-- CodeMirror -->
<link type="text/css" rel="stylesheet" href="/src/codemirror/css/codemirror.css">
<link type="text/css" rel="stylesheet" href="/src/codemirror/addon/fold/foldgutter.css">
<link type="text/css" rel="stylesheet" href="/src/codemirror/addon/dialog/dialog.css">
<link type="text/css" rel="stylesheet" href="/src/codemirror/addon/hint/show-hint.css">
<link type="text/css" rel="stylesheet" href="/src/codemirror/theme/neo.css">
<script type="text/javascript" src="/src/codemirror.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/search/searchcursor.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/search/search.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/dialog/dialog.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/edit/matchbrackets.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/edit/closebrackets.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/comment/comment.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/wrap/hardwrap.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/fold/foldcode.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/fold/brace-fold.js"></script>
<script type="text/javascript" src="/src/codemirror/keymap/sublime.js"></script>
<script type="text/javascript" src="/src/codemirror/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="/src/codemirror/mode/clike.js"></script>
<link type="text/css" rel="stylesheet" href="'.$path.'/src/codemirror/css/codemirror.css">
<link type="text/css" rel="stylesheet" href="'.$path.'/src/codemirror/addon/fold/foldgutter.css">
<link type="text/css" rel="stylesheet" href="'.$path.'/src/codemirror/addon/dialog/dialog.css">
<link type="text/css" rel="stylesheet" href="'.$path.'/src/codemirror/addon/hint/show-hint.css">
<link type="text/css" rel="stylesheet" href="'.$path.'/src/codemirror/theme/neo.css">
<script type="text/javascript" src="'.$path.'/src/codemirror.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/search/searchcursor.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/search/search.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/dialog/dialog.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/edit/matchbrackets.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/edit/closebrackets.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/comment/comment.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/wrap/hardwrap.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/fold/foldcode.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/fold/brace-fold.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/keymap/sublime.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="'.$path.'/src/codemirror/mode/clike.js"></script>
<!-- Highlight -->
<link type="text/css" rel="stylesheet" href="/css/github.css">
<script type="text/javascript" src="/src/highlight.min.js"></script>
<link type="text/css" rel="stylesheet" href="'.$path.'/css/github.css">
<script type="text/javascript" src="'.$path.'/src/highlight.min.js"></script>
<!-- My stuff -->
<link type="text/css" rel="stylesheet" href="/css/style.css">
<link type="text/css" rel="stylesheet" href="'.$path.'/css/style.css">
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</style>
</head>
<body>

View File

@ -1,4 +1,5 @@
<?php
$path = ".";
include("header.php");
echo '<div id="content">';
include("src/parsedown/Parsedown.php");

View File

@ -256,11 +256,11 @@ function loadMarkdown(){
// Load codes tags that have "src" attributes
var list = document.getElementsByTagName("code");
for(var i = 0; i < list.length; i++){
if (list[i].className == "lang-glsl" ||
list[i].className == "lang-bash" ||
list[i].className == "lang-cpp" ||
list[i].className == "lang-html" ||
list[i].className == "lang-processing" ){
if (list[i].className == "language-glsl" ||
list[i].className == "language-bash" ||
list[i].className == "language-cpp" ||
list[i].className == "language-html" ||
list[i].className == "language-processing" ){
hljs.highlightBlock(list[i]);
}
}
@ -354,7 +354,7 @@ function previusPage(){
if(n < 0){
url = "../";
} else {
url = "../" + FormatNumberLength(n,2);
url = "../" + FormatNumberLength(n,2) + "/";
}
window.location.href = url;
}