のぐそんブログ

暗いおじさんがシコシコ書くブログです。

GLSLでノイズを使うメモ

フラグメントシェーダをつかってのノイズを作成するためのメモです。

ホワイトノイズをつくる

ホワイトノイズは砂嵐のようなノイズです。 ホワイトノイズは品質は良くないが、処理が高速らしいです。

frac関数は少数の値のみ抜き出す関数です。

float random (vec2 st) {
    return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);
}

void main() {
    vec2 st = gl_FragCoord.xy/resolution.xy;

    float rnd = random( st);

    gl_FragColor = vec4(vec3(rnd),1.0);
}

random関数の引数の値を大きくすると低解像度のノイズができます。

float random (vec2 st) {
    return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);
}

void main() {
    vec2 st = gl_FragCoord.xy/resolution.xy;

    float rnd = random(floor(st*10.0));

    gl_FragColor = vec4(vec3(rnd),1.0);
}

バリューノイズをつくる

バリューノイズは雲や煙のようなノイズです。 バリューノイズはもはや私では理解不能です。

低解像度のノイズを作成して、その間を保管して引き伸ばすらしいです。

Kobito.TkHDG9.png

float random (vec2 st) { 
   return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);
}


//参考:https://thebookofshaders.com/11/
float noise (in vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);

    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;
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;

    vec2 pos = vec2(st*5.0);

    float n = noise(pos);

    gl_FragColor = vec4(vec3(n), 1.0);
}

グラデーションノイズ

グラデーションノイズは2次元のランダム関数を使って生成するようです。

//参考:https://thebookofshaders.com
vec2 random(vec2 st){
    st = vec2( dot(st,vec2(127.1,311.7)),
              dot(st,vec2(269.5,183.3)) );
              
    return 2.0*fract(sin(st)*43758.5453123) - 1.0;
}


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( random(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 
                     dot( random(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
                mix( dot( random(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
                     dot( random(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}

void main() {
    vec2 st = gl_FragCoord.xy/resolution.xy;
    vec3 color = vec3(0.0);

    vec2 pos = vec2(st*10.0);

    color = vec3( noise(pos)*.5+.5 );

    gl_FragColor = vec4(color,1.0);
}