Skip to content

Instantly share code, notes, and snippets.

@pexavc
Last active February 2, 2022 08:24
Show Gist options
  • Save pexavc/c58b4df48a400460f2aa8885029ead5f to your computer and use it in GitHub Desktop.
Save pexavc/c58b4df48a400460f2aa8885029ead5f to your computer and use it in GitHub Desktop.
[ Understanding Shaders ] // :: Simplex Noise
vec2 hash( vec2 p ) // replace this by something better
{
p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
}
float noise( in vec2 p )
{
const float K1 = 0.366025404; // (sqrt(3)-1)/2;
const float K2 = 0.211324865; // (3-sqrt(3))/6;
// It seems here we define the simplex in which we are
vec2 i = floor( p + (p.x+p.y)*K1 );
vec2 a = p - i + (i.x+i.y)*K2;
// This is the fade function
float m = step(a.y,a.x);
// What happens next I have no idea....
// ..........................................................
vec2 o = vec2 (m, 1.0-m);
vec2 b = a - o + K2;
vec2 c = a - 1.0 + 2.0*K2;
vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
return dot( n, vec3(70.0) );
}
@pexavc
Copy link
Author

pexavc commented Feb 2, 2022

float m = a.y>a.x ? 0.0 : 1.0;
This line is needed in order to divide the square into two triangles.

const float K1 = 0.366025404; // (sqrt(3)-1)/2;
const float K2 = 0.211324865; // (3-sqrt(3))/6;
These coefficients are used to turn a regular grid into a sort of honeycomb. Or just misrepresent. Each honeycomb consists of 6 triangles. In fact, these are already calculated sin, cos from the angle of rotation of the grid.
(sqrt(3)-1)/2 = sqrt(3)/2-1/2 is like a complex number cos(30) - sin(30)
(3-sqrt(3))/6 = 1/2- sqrt(3)/6 - and here sin(30) - tg(30)
If this is correctly substituted into the rest of the formulas, we get an Affine transformation or rotation.

vec2 i = floor( p + (p.x+py)*K1 );
Here we get a grid cell with distortion.

vec2 a = p - i + (i.x+iy)*K2;
Here the fractional part is inside the cell (triangle).

vec2 b = a - o + K2;
vec2 c = a - 1.0 + 2.0*K2;
b, c - complement "a" for other corners. "a","b","c" are the distances to each of the corners of the triangle.

vec3 n = h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
Then everything is tied to "hash", here two-layer noise is used. If you take one layer, you will get the usual noise on a two-dimensional grid rotated by 30 degrees. To bring this down, two layers are mixed together for each vertex of the triangle
dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)).

vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
h - acts as a blend factor between vertices. Inverse distances to each of the vertices.

vec3 n = hhhhvec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))) ;

dot( n, vec3(70.0) )
here all vertex values ​​are blended and normalized. These two lines replace the manual mix or lerp to get the gradient between the vertices of the triangle.

Almost the same effect is achieved in a simpler way.

Source: https://gamedev.ru/code/forum/?id=255209
Interesting read. Looking into Perlin noise.


Desired Effect:
Capture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment