パーリンノイズ
※ちょっと間違ってるかも 気づいたら直します
https://gyazo.com/a150499f102776fbab15cb649a30407d
Perlinが考案したノイズ。勾配ノイズの1種。
初期パーリンノイズ
勾配ノイズは値ノイズに比べてムラが目立ちにくくなるという利点があった。1983年にPerlinが発表した、補間は3次関数で行い、勾配の方向は制限なくランダムに決める勾配ノイズを初期パーリンノイズと呼ぶ。
しかし、それでも勾配の方向が座標系の軸方向や対角線方向になってしまうとムラが見えてしまうという欠点があった。
それを解決する案としてPerlinが2002年に発表したノイズを改良版パーリンノイズと呼ぶらしい。
改良版パーリンノイズの2つの特徴
エルミート補間に5次関数を使う
勾配の方向をあえて限定する
軸方向や対角線方向を除外した方向に勾配の方向を制限する
例えば3次元においては立方体の各辺の中点に向かう12方向
実装
以下はiqによる2Dのパーリンノイズ(高速版)
https://www.shadertoy.com/view/XdXGW8
高速化のための妥協ポイント
勾配の方向の制限はしているが、この例では対角線方向と軸方向のみに制限している(対角線方向と軸方向”以外”ではない)
補間は3次関数を使っている
code:glsl
vec2 grad( ivec2 z ) // replace this anything that returns a random vector
{
// 2D to 1D (feel free to replace by some other)
int n = z.x+z.y*11111;
// Hugo Elias hash (feel free to replace by another one)
n = (n<<13)^n;
n = (n*(n*n*15731+789221)+1376312589)>>16;
// Perlin style vectors
n &= 7;
vec2 gr = vec2(n&1,n>>1)*2.0-1.0;
return ( n>=6 ) ? vec2(0.0,gr.x) :
( n>=4 ) ? vec2(gr.x,0.0) :
gr;
}
float noise( in vec2 p )
{
ivec2 i = ivec2(floor( p ));
vec2 f = fract( p );
vec2 u = f*f*(3.0-2.0*f); // feel free to replace by a quintic smoothstep instead
return mix( mix( dot( grad( i+ivec2(0,0) ), f-vec2(0.0,0.0) ),
dot( grad( i+ivec2(1,0) ), f-vec2(1.0,0.0) ), u.x),
mix( dot( grad( i+ivec2(0,1) ), f-vec2(0.0,1.0) ),
dot( grad( i+ivec2(1,1) ), f-vec2(1.0,1.0) ), u.x), u.y);
}