completing noise

pull/19/head
Patricio Gonzalez Vivo 9 years ago
parent 28e8a13271
commit 8b34688057

@ -29,13 +29,7 @@ vec2 brickTile(vec2 st, float zoom){
}
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);
return dot(st,st);
}
void main(){
@ -48,11 +42,16 @@ void main(){
float pct = 1.0-fract(u_mouse.y/u_resolution.y);
float A = circleDF(vec2(0.5)-st);
float B = circleDF(vec2(0.25)-st)*5.;
B = min(B, circleDF(vec2(0.75,0.25)-st)*5.);
B = min(B, circleDF(vec2(0.5,0.75)-st)*5.);
B = min(B, circleDF(vec2(0.,0.75)-st)*5.);
B = min(B, circleDF(vec2(1.,0.75)-st)*5.);
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);
d = mix(A,B,pct);
d = aastep(.21,d);
color = vec3(d);
gl_FragColor = vec4(color,1.0);

@ -9,13 +9,14 @@ uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
// 2D Random
float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
vec2(12.9898,78.233)))
* 43758.5453123);
}
// Based on Morgan McGuire @morgan3d
// 2D Noise based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 st) {
vec2 i = floor(st);
@ -27,8 +28,10 @@ float noise (in vec2 st) {
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);
// Smooth interpolation
vec2 u = smoothstep(0.,1.,f);
// Mix 4 coorners porcentages
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
@ -36,11 +39,13 @@ float noise (in vec2 st) {
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
// Scale the coordinate system to see
// some noise in action
vec2 pos = vec2(st*5.0);
color = vec3( noise(pos) );
// Use the noise function
float n = noise(pos);
gl_FragColor = vec4(color,1.0);
gl_FragColor = vec4(vec3(n), 1.0);
}

@ -0,0 +1,95 @@
// Author @patriciogv - 2015
// http://patriciogonzalezvivo.com
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
// Some useful functions
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); }
//
// Description : GLSL 2D simplex noise function
// Author : Ian McEwan, Ashima Arts
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License :
// Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//
float snoise(vec2 v) {
// Precompute values for skewed triangular grid
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 (x0)
vec2 i = floor(v + dot(v, C.yy));
vec2 x0 = v - i + dot(i, C.xx);
// Other two corners (x1, x2)
vec2 i1 = vec2(0.0);
i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0);
vec2 x1 = x0.xy + C.xx - i1;
vec2 x2 = x0.xy + C.zz;
// Do some permutations to 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(x1,x1),
dot(x2,x2)
), 0.0);
m = m*m ;
m = m*m ;
// 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);
// Compute final noise value at P
vec3 g = vec3(0.0);
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * vec2(x1.x,x2.x) + h.yz * vec2(x1.y,x2.y);
return 130.0 * dot(m, g);
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
vec2 pos = vec2(st*10.);
color = vec3(snoise(pos)*.5+.5);
gl_FragColor = vec4(color,1.0);
}

@ -14,42 +14,29 @@ uniform float u_time;
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
// License :
// Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//
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); }
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);
// Other corners
vec2 i1;
vec2 i1 = vec2(0.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
// 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),
@ -57,24 +44,13 @@ float snoise(vec2 v) {
), 0.0);
m = m*m ;
m = m*m ;
// 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);
// Compute final noise value at P
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
vec3 g = vec3(0.0);
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);
}

@ -0,0 +1,77 @@
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm
vec2 random2( vec2 p ) {
return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
}
#define ANIMATE
vec3 voronoi( in vec2 x, float rnd ) {
vec2 n = floor(x);
vec2 f = fract(x);
// first pass: regular voronoi
vec2 mg, mr;
float md = 8.0;
for (int j=-1; j<=1; j++ ) {
for (int i=-1; i<=1; i++ ) {
vec2 g = vec2(float(i),float(j));
vec2 o = random2( n + g )*rnd;
#ifdef ANIMATE
o = 0.5 + 0.5*sin( u_time + 6.2831*o );
#endif
vec2 r = g + o - f;
float d = dot(r,r);
if( d<md ) {
md = d;
mr = r;
mg = g;
}
}
}
// second pass: distance to borders
md = 8.0;
for (int j=-2; j<=2; j++ ) {
for (int i=-2; i<=2; i++ ) {
vec2 g = mg + vec2(float(i),float(j));
vec2 o = random2(n + g)*rnd;
#ifdef ANIMATE
o = 0.5 + 0.5*sin( u_time + 6.2831*o );
#endif
vec2 r = g + o - f;
if( dot(mr-r,mr-r)>0.00001 )
md = min( md, dot( 0.5*(mr+r), normalize(r-mr) ) );
}
}
return vec3( md, mr );
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
float d = dot(st-.5,st-.5);
vec3 c = voronoi( 20.*st, pow(d,.4) );
// isolines
// color = c.x*(0.5 + 0.5*sin(64.0*c.x))*vec3(1.0);
// borders
color = mix( vec3(1.0), color, smoothstep( 0.01, 0.02, c.x ) );
// feature points
float dd = length( c.yz );
color += vec3(1.)*(1.0-smoothstep( 0.0, 0.1, dd));
gl_FragColor = vec4(color,1.0);
}

@ -0,0 +1,75 @@
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
vec2 random2( vec2 p ) {
return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
}
#define ANIMATE
vec3 voronoi( in vec2 x, float rnd ) {
vec2 n = floor(x);
vec2 f = fract(x);
// first pass: regular voronoi
vec2 mg = vec2(0.0);
vec2 mr = vec2(0.0);
float md = 8.0;
for (int j=-1; j<=1; j++ ) {
for (int i=-1; i<=1; i++ ) {
vec2 g = vec2(float(i),float(j));
vec2 o = random2( n + g )*rnd;
#ifdef ANIMATE
o = 0.5 + 0.5*sin( u_time + 6.2831*o );
#endif
vec2 r = g + o - f;
float d = dot(r,r);
if( d<md ) {
md = d;
mr = r;
mg = g;
}
}
}
return vec3( md, mr );
// // second pass: distance to borders
// md = 8.0;
// for (int j=-2; j<=2; j++ ) {
// for (int i=-2; i<=2; i++ ) {
// vec2 g = mg + vec2(float(i),float(j));
// vec2 o = random2(n + g)*rnd;
// #ifdef ANIMATE
// o = 0.5 + 0.5*sin( u_time + 6.2831*o );
// #endif
// vec2 r = g + o - f;
// if( dot(mr-r,mr-r)>0.00001 )
// md = min( md, dot( 0.5*(mr+r), normalize(r-mr) ) );
// }
// }
// return vec3( md, mr );
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
float d = dot(st-.5,st-.5);
vec3 c = voronoi( 10.*st, 1.);//pow(d,.4) );
// isolines
color = c.x*(0.5 + 0.5*sin(64.0*c.x))*vec3(1.0);
// borders
color = mix( vec3(1.0), color, smoothstep( 0.01, 0.02, c.x ) );
// feature points
// float dd = length( c.yz );
// color += vec3(1.)*(1.0-smoothstep( 0.0, 0.1, dd));
gl_FragColor = vec4(color,1.0);
}

@ -67,10 +67,10 @@ void main() {
// isolines
color = c.x*(0.5 + 0.5*sin(64.0*c.x))*vec3(1.0);
// borders
color = mix( vec3(1.0,.0,.0), color, smoothstep( 0.01, 0.02, c.x ) );
color = mix( vec3(1.0), color, smoothstep( 0.01, 0.02, c.x ) );
// feature points
float dd = length( c.yz );
color += vec3(.0,1.,1.)*(1.0-smoothstep( 0.0, 0.04, dd));
color += vec3(1.)*(1.0-smoothstep( 0.0, 0.04, dd));
gl_FragColor = vec4(color,1.0);
}

@ -137,7 +137,7 @@ Another way to get interesting patterns from noise is to treat it like a distanc
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>
<a href="../edit.html#11/circleWave-noise.frag"><canvas id="custom" class="canvas" data-fragment-url="circleWave-noise.frag" width="300px" height="300"></canvas></a>
* What other generative pattern can you make? What about granite? marble? magma? water? Find three pictures of textures you are interested and implement them algorithmically using noise.
* Use noise to modulate a shapes.
@ -162,17 +162,19 @@ Yeah, right? I know what you are thinking... "Who is this man?". Yes, his work i
That means that the simplex shape for N dimensions is a shape with N + 1 corners. In other words one less corner to compute in 2D, 4 less coorners in 3D and 11 less coorners in 4D! That's a huge improvement!
In 2D the interpolation happens between those three corners in a similar way we where seen before.
So, in two dimension the interpolation happens, in a similar way than regular noise, by interpolating the values of the corners of a section. But, in this particular case, because we are using a simplex grid we just need to interpolate the sum of only 3 coornes (or contributors) to interpolate.
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:
![](simplex-grid-01.png)
_"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."_
How the simplex grid works? In another brillant and elegant move, simplex grid can be obtain by subdividing the cells of a regular 4 corners grid into two isoceles triangles and then skewing it unitl each triangle is equilateral.
![](simplex-grid-01.png)
![](simplex-grid-02.png)
Then, as [Stefan Gustavson describe in this paper](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): _"...by looking at the integer parts of the transformed coordinates (x,y) for the point we want to evaluate, we can quickly determine which cell of two simplices that contain the point. By also compareing the magnitudes of x and y, we can determine whether the points is in the upper or the lower simplex, and traverse the correct three corners points."_
Following is an actual GLSL implementation of this algorithm:
Following is an actual GLSL implementation of this algorithm made by Ian McEwan and Ashima Arts, which is probably over complicated for educational porposes because have been higly optimized.
<div class="codeAndCanvas" data="2d-snoise.frag"></div>
<div class="codeAndCanvas" data="2d-snoise-clear.frag"></div>
Now:
@ -182,5 +184,10 @@ Now:
<a href="../edit.html#11/lava-lamp.frag"><canvas id="custom" class="canvas" data-fragment-url="lava-lamp.frag" width="520px" height="200px"></canvas></a>
Nothing like having some control over the chaos and chances. Right?
* Use Signed Noise to add some texture to a work you already made
<a href="../edit.html#11/iching-02.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-02.frag" width="520px" height="520px"></canvas></a>
Nothing like having some control over the chaos and chances. Right?
Noise is one of those subjects that you can dig and always find new exciting formulas. In fact if you think of it, noise means different things for different people. Musicians will think in audio noise, communicators into interference, and astrophysics on cosmic microwave background. On the next chapter we will use some related concepts from sign and audio behavior to our noise function to explore more uses of noise.

@ -105,11 +105,10 @@ void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.y *= u_resolution.y/u_resolution.x;
float t = u_time*0.1;
float t = u_time*0.5;
float df = 1.0;
df = mix(hex(st,t),hex(st,t+1.),fract(t));
df += snoise(vec3(st*100.,t*0.1))*0.03;
df += snoise(vec3(st*75.,t*0.1))*0.03;
gl_FragColor = vec4(mix(vec3(0.),vec3(1.),step(0.7,df)),1.0);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

@ -85,5 +85,5 @@ The following is a list of examples present in this book.
* [Moon](../edit.html#examples/moon.frag&examples/images/moon-texture.jpg)
* [Matrix](../edit.html#08/matrix.frag)
* [I Ching](../edit.html#09/iching.frag)
* [I Ching](../edit.html#11/iching-02.frag)
* Ikeda's series: [test pattern](../edit.html#10/ikeda-00.frag), [data path](../edit.html#10/ikeda-03.frag) and [data defrag](../edit.html#10/ikeda-04.frag), [digits](../edit.html#10/ikeda-digits.frag), [radar](../edit.html#10/ikeda-simple-grid.frag), [numered grid](../edit.html#10/ikeda-numered-grid.frag)

Loading…
Cancel
Save