Skip to content

Commit

Permalink
adding images to noise chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
patriciogonzalezvivo committed Sep 15, 2015
1 parent 3c76a6f commit 6d61f94
Show file tree
Hide file tree
Showing 15 changed files with 314 additions and 74 deletions.
68 changes: 68 additions & 0 deletions 09/dots-zoom-00.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Author @patriciogv ( patricio.io ) - 2015
// Inspired by the Patterns of Nina Warmerdam ( www.behance.net/ninawarmerdam )
#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float aastep(float threshold, float value) {
#ifdef GL_OES_standard_derivatives
float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
return smoothstep(threshold-afwidth, threshold+afwidth, value);
#else
return step(threshold, value);
#endif
}
vec2 brickTile(vec2 st, float zoom){
st *= zoom;
if (fract(st.y * 0.5) > 0.5){
st.x += 0.5;
}
return fract(st);
}
float circleDF(vec2 st){
vec2 pos = vec2(0.5)-st;
return dot(pos,pos)*3.14;
}
float circle(vec2 st, float radius){
radius *= 0.75;
return 1.-aastep(radius,circleDF(st));
}

float dots(vec2 st, float size){
st = brickTile(st, 2.);
return circle(st, size);
}

float dotsDF(vec2 st){
st = brickTile(st, 2.);
return circleDF(st);
}

void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color = vec3(0.0);

vec2 IN = st;
vec2 OUT = st*2.;

float pct = 1.0-fract(u_mouse.y/u_resolution.y);
pct = pow(pct,6.);

float d = 0.0;
// d = mix(dots(fract(IN),(1.-pct)), dots(fract(OUT),pct), pct);
// d = mix(dotsDF(fract(IN)), dotsDF(fract(OUT)), pct);
d = dotsDF(fract(IN))*(1.-pct) + dotsDF(fract(OUT))*pct;
d = aastep(.21,d);
color = vec3(d);

gl_FragColor = vec4(color,1.0);
}
59 changes: 59 additions & 0 deletions 09/dots-zoom-01.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Author @patriciogv ( patricio.io ) - 2015
// Inspired by the Patterns of Nina Warmerdam ( www.behance.net/ninawarmerdam )
#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float aastep(float threshold, float value) {
#ifdef GL_OES_standard_derivatives
float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
return smoothstep(threshold-afwidth, threshold+afwidth, value);
#else
return step(threshold, value);
#endif
}
vec2 brickTile(vec2 st, float zoom){
st *= zoom;
if (fract(st.y * 0.5) > 0.5){
st.x += 0.5;
}
return fract(st);
}

float circleDF(vec2 st){
vec2 pos = vec2(0.5)-st;
return dot(pos,pos)*3.14;
}

float dotsDF(vec2 st){
st = brickTile(st, 2.);
return circleDF(st);
}

void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
vec3 color = vec3(0.0);

vec2 IN = st;
vec2 OUT = st*2.;

float pct = 1.0-fract(u_mouse.y/u_resolution.y);

float d = 0.0;
d = dotsDF(fract(IN))*(1.0-pct);
d += dotsDF(fract(OUT))*pct;
// d = max(dotsDF(fract(IN))*(1.0-pct),dotsDF(fract(OUT))*pct);
// d = aastep(.21,d);
color = vec3(d);

gl_FragColor = vec4(color,1.0);
}
39 changes: 26 additions & 13 deletions 11/2d-snoise.frag
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,53 @@ vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); }

float snoise(vec2 v) {
const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
-0.577350269189626, // -1.0 + 2.0 * C.x
0.024390243902439); // 1.0 / 41.0
const vec4 C = vec4(0.211324865405187,
// (3.0-sqrt(3.0))/6.0
0.366025403784439,
// 0.5*(sqrt(3.0)-1.0)
-0.577350269189626,
// -1.0 + 2.0 * C.x
0.024390243902439);
// 1.0 / 41.0
// First corner
vec2 i = floor(v + dot(v, C.yy) );
vec2 x0 = v - i + dot(i, C.xx);

// Other corners
vec2 i1;
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0);
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;

// Permutations
i = mod289(i); // Avoid truncation effects in permutation
vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
+ i.x + vec3(0.0, i1.x, 1.0 ));

vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
// Avoid truncation effects in permutation
i = mod289(i);
vec3 p = permute(
permute( i.y + vec3(0.0, i1.y, 1.0))
+ i.x + vec3(0.0, i1.x, 1.0 ));

vec3 m = max(0.5 - vec3(
dot(x0,x0),
dot(x12.xy,x12.xy),
dot(x12.zw,x12.zw)
), 0.0);
m = m*m ;
m = m*m ;

// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
// Gradients:
// 41 pts uniformly over a line, mapped onto a diamond
// The ring size 17*17 = 289 is close to a multiple
// of 41 (41*7 = 287)

vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;

// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
// Approximation of: m *= inversesqrt(a0*a0 + h*h);
m *= 1.79284291400159 - 0.85373472095314 * (a0*a0+h*h);

// Compute final noise value at P
vec3 g;
Expand Down
40 changes: 26 additions & 14 deletions 11/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,34 @@

Break time! We have been playing with all this random functions that looks like TV white noise, our head is still spinning around thinking on shaders, and our eyes are tired. Time to get out for a walk!

We feel the air in our face, the sun in our nose and chicks. The world is such a vivid and rich place. Colors, textures, sounds. While we walk we can't avoid noticing the surface of the roads, rocks, trees and clouds. We note the stochasticity of textures, there is random on nature. But definitely not the type of random we were making in the previus chapter. The “real world” is such a rich place. How we can approximate to this level of variety computationally?
We feel the air in our skin, the sun in our face. The world is such a vivid and rich place. Colors, textures, sounds. While we walk we can't avoid noticing the surface of the roads, rocks, trees and clouds.

We are on the same path of thoughts that [Ken Perlin](https://mrl.nyu.edu/~perlin/)'s walk through on 1982 when he was commissioned with the job of generating "more realistic" textures for a new disney movie call "Tron". In response to that he came up with an elegant *oscar winner* noise algorithm.
![](texture-00.jpg)
![](texture-01.jpg)
![](texture-02.jpg)
![](texture-03.jpg)
![](texture-04.jpg)
![](texture-05.jpg)
![](texture-06.jpg)

The stochasticity of this textures could be call "random", but definitely not the type of random we were playing before in the previus chapter. The “real world” is such a rich place! It's rando is way complex. How we can approximate to this level of variety computationally?

This was the question [Ken Perlin](https://mrl.nyu.edu/~perlin/) was trying to solve arround 1982 when he was commissioned with the job of generating "more realistic" textures for a new disney movie call "Tron". In response to that he came up with an elegant *oscar winner* noise algorithm.

![Disney - Tron (1982)](tron.jpg)

The following is not the clasic Perlin noise algorithm, but is a good starting point to understand how to generate *smooth random* aka *noise*.

In the following graph you will see what we were doing on the previus chapter, obtaining ```rand()``` numbers of the integers of the `x` position (assigning it to `i` variable), while we keep the [```fract()```](.../glossary/?search=fract) part of it (and storing it on the `f` variable).

You will also see, two commented lines. The first one interpolates linearly between the random value of the integer position and it next one.

```glsl
y = mix(rand(i), rand(i + 1.0), f);
```

Uncomment it an see how that looks. See how we use the [```fract()```](.../glossary/?search=fract) value store in `f` to [```mix()```](.../glossary/?search=mix) the two random values.

<div class="simpleFunction" data="
float i = floor(x); // integer
float f = fract(x); // fraction
Expand All @@ -21,14 +41,6 @@ y = rand(i);
//y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
"></div>

You will see also, two commented lines. The first one interpolates linearly between the random value of the integer position and it next one.

```glsl
y = mix(rand(i), rand(i + 1.0), f);
```

Uncomment it an see how that looks. See how we use the [```fract()```](.../glossary/?search=fract) value store in `f` to [```mix()```](.../glossary/?search=mix) the two random values.

At this point on the book, we learned that we can do better than a linear interpolation. Right?
The following commented line, will transfor the linear interpolation of `f` with a [```smoothstep()```](.../glossary/?search=smoothstep) interpolation.

Expand Down Expand Up @@ -152,13 +164,13 @@ That means that the simplex shape for N dimensions is a shape with N + 1 corners

In 2D the interpolation happens between those three corners in a similar way we where seen before.

![](simplex-grid-01.png)

It worths taking a look to [this paper where Stefan Gustavson](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf) explains all the beauty and elegance of Ken Perlin's Simplex Noise. Couting from it:

"A point P inside a simplex gets contributions to its value only from the three kernels centered on the surrounding corners (shaded, red circles). Kernels at corners farther away (green circles) decay to zero before they cross the boundary to the simplex containing P. Thus, the noise value at each point can always be calculated as a sum of three terms."
_"A point P inside a simplex gets contributions to its value only from the three kernels centered on the surrounding corners (shaded, red circles). Kernels at corners farther away (green circles) decay to zero before they cross the boundary to the simplex containing P. Thus, the noise value at each point can always be calculated as a sum of three terms."_

![](simplex-grid-01.png)

Here is an actual GLSL implementation of this algorithm
Following is an actual GLSL implementation of this algorithm:

<div class="codeAndCanvas" data="2d-snoise.frag"></div>

Expand Down
Loading

0 comments on commit 6d61f94

Please sign in to comment.