noise and examples
This commit is contained in:
parent
cf7ff5655b
commit
d567dcd8f2
|
|
@ -0,0 +1,39 @@
|
|||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec2 u_mouse;
|
||||
uniform float u_time;
|
||||
|
||||
vec2 random2(vec2 st){
|
||||
st = vec2( dot(st,vec2(127.1,311.7)),
|
||||
dot(st,vec2(269.5,183.3)) );
|
||||
return -1.0 + 2.0*fract(sin(st)*43758.5453123);
|
||||
}
|
||||
|
||||
// Value Noise by Inigo Quilez - iq/2013
|
||||
// https://www.shadertoy.com/view/lsf3WH
|
||||
float noise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
st.x *= u_resolution.x/u_resolution.y;
|
||||
vec3 color = vec3(0.0);
|
||||
|
||||
vec2 pos = vec2(st*10.0);
|
||||
|
||||
color = vec3( noise(pos)*.5+.5 );
|
||||
|
||||
gl_FragColor = vec4(color,1.0);
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ void main() {
|
|||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
vec3 color = vec3(0.0);
|
||||
|
||||
vec2 pos = vec2(st*5.0+u_time);
|
||||
vec2 pos = vec2(st*5.0);
|
||||
|
||||
color = vec3( noise(pos) );
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec2 u_mouse;
|
||||
uniform float u_time;
|
||||
|
||||
float hash(vec2 st) {
|
||||
float h = dot(st,vec2(127.1,311.7));
|
||||
return -1.0 + 2.0*fract(sin(h)*43758.5453123);
|
||||
}
|
||||
|
||||
// Gradient Noise by Inigo Quilez - iq/2013
|
||||
// https://www.shadertoy.com/view/XdXGW8
|
||||
float noise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( hash( i + vec2(0.0,0.0) ),
|
||||
hash( i + vec2(1.0,0.0) ), u.x),
|
||||
mix( hash( i + vec2(0.0,1.0) ),
|
||||
hash( i + vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
st.x *= u_resolution.x/u_resolution.y;
|
||||
vec3 color = vec3(0.0);
|
||||
|
||||
vec2 pos = vec2(st*10.0);
|
||||
|
||||
color = vec3(noise(pos)*.5+.5);
|
||||
|
||||
gl_FragColor = vec4(color,1.0);
|
||||
}
|
||||
56
11/README.md
56
11/README.md
|
|
@ -7,7 +7,7 @@ Break time! We have been playing with all this random functions that looks like
|
|||
|
||||
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 are on the same path of thoughts that Ken 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.
|
||||
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.
|
||||
|
||||
The following is not the clasic Perlin noise algorithm, but is a good starting point to understand how to generate *smooth random* aka *noise*.
|
||||
|
||||
|
|
@ -57,13 +57,25 @@ Now is your turn:
|
|||
|
||||
## 2D Noise
|
||||
|
||||

|
||||
|
||||
Now that we know how to do noise in one dimension, is time to port it to two. For that instead of interpolating between two points (```fract(x)``` and ```fract(x)+1.0```) we are going to interpolate between the four coorners of square (```fract(st)```, ```fract(st)+vec2(1.,0.)```, ```fract(st)+vec2(0.,1.)``` and ```fract(st)+vec2(1.,1.)```).
|
||||
|
||||

|
||||
|
||||
Take a look to the following 2D noise function, see how on line 32 we interpolate random values (lines 25-28) acording to the the position of ```st``` the four corners of the squared area.
|
||||
|
||||

|
||||
|
||||
If you pay atention is not just a linear interpolation but a cubic one which smoothly interpolates any points inside a squared grid
|
||||
|
||||

|
||||
|
||||
In the following implementation of 2D noise we scale the size of the grid by 5 (line 41).
|
||||
|
||||
<div class="codeAndCanvas" data="2d-noise.frag"></div>
|
||||
|
||||
To this 2D noise at line 41 we scale the space by 5 and "move" it acording to time. No try:
|
||||
Now is your turn, try the following excersices:
|
||||
|
||||
* Change the multiplier. Try to animate it.
|
||||
|
||||
|
|
@ -79,40 +91,44 @@ To this 2D noise at line 41 we scale the space by 5 and "move" it acording to ti
|
|||
|
||||

|
||||
|
||||
## Using 2D Noise to rotate the space
|
||||
## Using Noise on generative designs
|
||||
|
||||
As we saw, noise was designed to give a natural *je ne sais quoi* to digital textures, and could be use to make convincing generative textures. Lets refresh some of the previous knowledge and then jump forward learning how to mix all the knowledge we have learn so far.
|
||||
As we saw, noise algorithms was original designed to give a natural *je ne sais quoi* to digital textures. Our first step to use it will be to differenciate different types of noise algorithms. So far all the implementations in 1D and 2D we saw, were interpolation between values and so they are usually call **Value Noise**.
|
||||
|
||||
In the following code you will find:
|
||||
<a href="../edit.html#11/2d-vnoise.frag"><canvas id="custom" class="canvas" data-fragment-url="2d-vnoise.frag" width="520px" height="200px"></canvas> <p style="text-align: center;font-style: italic;">Value Noise by IQ</p></a>
|
||||
|
||||
* Shaping functions to create: random (line 13), noise (line 32) and a line pattern (line 46).
|
||||
* A color gradient (line 68).
|
||||
* A matrix to rotate the line pattern (line 37-40 and 45)
|
||||
* A 2d random function (line 12-16)
|
||||
* A 2d noise function (line 20-35)
|
||||
As you discovery on the previus excercises this type of noise tends to look "block", as a solution to this effect in 1985 again [Ken Perlin](https://mrl.nyu.edu/~perlin/) develop another implementation of the algorithm call **Gradient Noise**. In it what is interpolated per coorner is not a value but a direction (represented by a ```vec2```).
|
||||
|
||||
<div class="codeAndCanvas" data="wood.frag"></div>
|
||||
<a href="../edit.html#11/2d-gnoise.frag"><canvas id="custom" class="canvas" data-fragment-url="2d-gnoise.frag" width="520px" height="200px"></canvas> <p style="text-align: center;font-style: italic;">Gradient Noise by IQ</p></a>
|
||||
|
||||
By uncommenting line 60 you will see the line pattern we are talking about.
|
||||
Revealing line 63 you can see how we can alternate this pattern in a "natural-like" way, to then finally, uncommenting line 66 we can stretch the noise pattern in *y* axis.
|
||||
Take a minute to look to these two examples by [Inigo Quilez](http://www.iquilezles.org/) and pay attention on the differences between [value noise](https://www.shadertoy.com/view/lsf3WH) and [gradient noise](https://www.shadertoy.com/view/XdXGW8).
|
||||
|
||||
Wow! You really should be proud of your self. He have went from nothing to generating our own wood procedural texture!
|
||||
As a painter that understand how the pigments of their paint works, the more we know about noise implementations the better we will learn how to use it. The following step is to find interesting way of combining and using it.
|
||||
|
||||
Now is time for you to play with it:
|
||||
For example, if we use a two dimensional noise implementation to rotate the "grid" we can produce the following effect that looks a lot like wood
|
||||
|
||||
* What do you thing it will happen if the patter looks like this:
|
||||
<a href="../edit.html#11/wood.frag"><canvas id="custom" class="canvas" data-fragment-url="wood.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
```glsl
|
||||
pattern = sin(lines(pos, noise(pos*vec2(2.,0.5)),0.5)*3.14);
|
||||
pos = rotate2d( noise(pos) ) * pos; // rotate the space
|
||||
pattern = lines(pos,.5); // draw lines
|
||||
```
|
||||
|
||||
Or like this
|
||||
Another way to get interesting patterns from noise is to treat it like a distance field and apply some of the tricks described on the [Shapes chapter](../07)
|
||||
|
||||
<a href="../edit.html#11/splatter.frag"><canvas id="custom" class="canvas" data-fragment-url="splatter.frag" width="520px" height="200px"></canvas></a>
|
||||
|
||||
```glsl
|
||||
pattern = fract(lines(pos, noise(pos*vec2(2.,0.5)),0.5)*2.0);
|
||||
color += smoothstep(.15,.2,noise(st*10.)); // Black splatter
|
||||
color -= smoothstep(.35,.4,noise(st*10.)); // Holes on splatter
|
||||
```
|
||||
|
||||
* What other generative pattern can you make? What about granite? marble? magma? water?
|
||||
The third way of using the noise function is using it to modulate a shapes, this probably require reviewing the [Shapes Chapter](../07)
|
||||
|
||||
<a href="../edit.html#11/circleWave-noise.frag"><canvas id="custom" class="canvas" data-fragment-url="circleWave-noise.frag" width="520px" height="520"></canvas></a>
|
||||
|
||||
* What other generative pattern can you make? What about granite? marble? magma? water? Find a picture of three textures you are interested and implement it algorithmically using noise.
|
||||
* Use noise to modulate three shapes.
|
||||
* What about noise apply to motion? Go back to the Matrix chapter and use the translation example that move a the "+" around to apply some *random* and *noise* movements to it.
|
||||
|
||||
Nothing like having some control over the chaos and chances. Right?
|
||||
|
|
|
|||
|
|
@ -12,51 +12,24 @@ uniform vec2 u_resolution;
|
|||
uniform vec2 u_mouse;
|
||||
uniform float u_time;
|
||||
|
||||
vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
|
||||
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); }
|
||||
vec2 random2(vec2 st){
|
||||
st = vec2( dot(st,vec2(127.1,311.7)),
|
||||
dot(st,vec2(269.5,183.3)) );
|
||||
return -1.0 + 2.0*fract(sin(st)*43758.5453123);
|
||||
}
|
||||
|
||||
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
|
||||
// First corner
|
||||
vec2 i = floor(v + dot(v, C.yy) );
|
||||
vec2 x0 = v - i + dot(i, C.xx);
|
||||
// Value Noise by Inigo Quilez - iq/2013
|
||||
// https://www.shadertoy.com/view/lsf3WH
|
||||
float noise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
// Other corners
|
||||
vec2 i1;
|
||||
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
||||
vec4 x12 = x0.xyxy + C.xxzz;
|
||||
x12.xy -= i1;
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
// 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);
|
||||
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)
|
||||
|
||||
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 );
|
||||
|
||||
// Compute final noise value at P
|
||||
vec3 g;
|
||||
g.x = a0.x * x0.x + h.x * x0.y;
|
||||
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
||||
return 130.0 * dot(m, g);
|
||||
return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
mat2 rotate2d(float _angle){
|
||||
|
|
@ -69,13 +42,12 @@ float shape(vec2 st, float radius) {
|
|||
float r = length(st)*2.0;
|
||||
float a = atan(st.y,st.x);
|
||||
float m = abs(mod(a+u_time*2.,3.14*2.)-3.14)/3.6;
|
||||
m += snoise(st+u_time*0.1)*.8;
|
||||
a *= 1.+abs(atan(u_time*0.2))*.1;
|
||||
// a *= 1.+snoise(st+u_time*0.1)*0.1;
|
||||
// a *= 1.+snoise(vec2(a,r)+u_time*0.1)*.1;
|
||||
float f = radius;
|
||||
// f += sin(a*10.)*snoise(st+u_time*.2)*.1;
|
||||
f += (cos(a*50.)*.1*pow(m,2.));
|
||||
m += noise(st+u_time*0.1)*.5;
|
||||
// a *= 1.+abs(atan(u_time*0.2))*.1;
|
||||
// a *= 1.+noise(st+u_time*0.1)*0.1;
|
||||
f += sin(a*50.)*noise(st+u_time*.2)*.1;
|
||||
f += (sin(a*20.)*.1*pow(m,2.));
|
||||
return 1.-smoothstep(f,f+0.007,r);
|
||||
}
|
||||
|
||||
|
|
@ -87,5 +59,5 @@ void main() {
|
|||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
vec3 color = vec3(1.0) * shapeBorder(st,0.8,0.02);
|
||||
|
||||
gl_FragColor = vec4( color, 1.0 );
|
||||
gl_FragColor = vec4( 1.-color, 1.0 );
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ float snoise(vec2 v) {
|
|||
|
||||
void main() {
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
st.x *= u_resolution.x/u_resolution.y;
|
||||
vec3 color = vec3(0.0);
|
||||
vec2 pos = vec2(st*3.);
|
||||
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@ vec3 nNoise(vec2 st) {
|
|||
|
||||
void main(){
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
|
||||
st.x *= u_resolution.x/u_resolution.y;
|
||||
float scale = 10.0;
|
||||
st *= scale;
|
||||
|
||||
st += nNoise(st).xy*.1*sin(u_time);
|
||||
float df = sin(fract(st.y)*10.);
|
||||
|
||||
gl_FragColor= vec4(vec3(smoothstep(.9,.99,df)),1.);
|
||||
gl_FragColor= vec4(vec3(1.0-smoothstep(.9,.99,df)),1.);
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec2 u_mouse;
|
||||
uniform float u_time;
|
||||
|
||||
vec2 random2(vec2 st){
|
||||
st = vec2( dot(st,vec2(127.1,311.7)),
|
||||
dot(st,vec2(269.5,183.3)) );
|
||||
return -1.0 + 2.0*fract(sin(st)*43758.5453123);
|
||||
}
|
||||
|
||||
// Value Noise by Inigo Quilez - iq/2013
|
||||
// https://www.shadertoy.com/view/lsf3WH
|
||||
float noise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 st = gl_FragCoord.xy/u_resolution.xy;
|
||||
st.x *= u_resolution.x/u_resolution.y;
|
||||
vec3 color = vec3(0.0);
|
||||
|
||||
// Comment and uncomment the following lines:
|
||||
st += noise(st*2.)*abs(1.0-sin(u_time*.1))*5.; // Animate the coordinate space
|
||||
color = vec3(1.) * smoothstep(.18,.2,noise(st)); // Big black drops
|
||||
color += smoothstep(.15,.2,noise(st*10.)); // Black splatter
|
||||
color -= smoothstep(.35,.4,noise(st*10.)); // Holes on splatter
|
||||
|
||||
gl_FragColor = vec4(1.-color,1.0);
|
||||
}
|
||||
34
11/wood.frag
34
11/wood.frag
|
|
@ -15,23 +15,16 @@ float random (in vec2 st) {
|
|||
* 43758.5453123);
|
||||
}
|
||||
|
||||
// Based on Morgan McGuire @morgan3d
|
||||
// https://www.shadertoy.com/view/4dS3Wd
|
||||
float noise (in vec2 st) {
|
||||
// Value noise by Inigo Quilez - iq/2013
|
||||
// https://www.shadertoy.com/view/lsf3WH
|
||||
float noise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
// Four corners in 2D of a tile
|
||||
float a = random(i);
|
||||
float b = random(i + vec2(1.0, 0.0));
|
||||
float c = random(i + vec2(0.0, 1.0));
|
||||
float d = random(i + vec2(1.0, 1.0));
|
||||
|
||||
vec2 u = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
return mix(a, b, u.x) +
|
||||
(c - a)* u.y * (1.0 - u.x) +
|
||||
(d - b) * u.x * u.y;
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
return mix( mix( random( i + vec2(0.0,0.0) ),
|
||||
random( i + vec2(1.0,0.0) ), u.x),
|
||||
mix( random( i + vec2(0.0,1.0) ),
|
||||
random( i + vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
mat2 rotate2d(float angle){
|
||||
|
|
@ -39,10 +32,9 @@ mat2 rotate2d(float angle){
|
|||
sin(angle),cos(angle));
|
||||
}
|
||||
|
||||
float lines(in vec2 pos, float angle, float b){
|
||||
float lines(in vec2 pos, float b){
|
||||
float scale = 10.0;
|
||||
pos *= scale;
|
||||
pos = rotate2d( angle ) * pos;
|
||||
return smoothstep(0.0,
|
||||
.5+b*.5,
|
||||
abs((sin(pos.x*3.1415)+b*2.0))*.5);
|
||||
|
|
@ -56,11 +48,11 @@ void main() {
|
|||
|
||||
float pattern = pos.x;
|
||||
|
||||
// Stripes
|
||||
pattern = lines(pos, 0.0, 0.5 );
|
||||
|
||||
// Add noise
|
||||
pattern = lines(pos, noise(pos), .5 );
|
||||
pos = rotate2d( noise(pos) ) * pos;
|
||||
|
||||
// Draw lines
|
||||
pattern = lines(pos,.5);
|
||||
|
||||
gl_FragColor = vec4(vec3(pattern),1.0);
|
||||
}
|
||||
Loading…
Reference in New Issue