LoginSignup
3
4

More than 5 years have passed since last update.

glslで疑似ディスプレイメントマップをプロシージャルにやってみる その2 ノイズ編

Posted at

まずは単純にノイズを乗せてみます。

tegaqkiichimatsu.png
https://goo.gl/f6ogDt

precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

const int   oct  = 8;
const float per  = 0.5;
const float PI   = 3.1415926;

// 乱数生成
float rnd(vec2 p){
    return fract(sin(dot(p ,vec2(12.9898,78.233))) * 43758.5453);
}

void main(void){
    vec2 q = (gl_FragCoord.xy * 2.0 - r);// / min(r.x, r.y);
    float d = rnd(q+floor(t*10.))*.01;

    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    p+=d;
    p*=8.;
    float l = mod(floor(p.x)+floor(p.y),2.0);
    gl_FragColor = vec4(vec3(l), 1.0);
}

手書き風の図形になってこれはこれで面白いですね。

次にバリューノイズを乗せてみます。

ノイズ生成ルーチンはこちらを参考に

valuenoise.png
https://goo.gl/Js47SX

precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

const int   oct  = 8;
const float per  = 0.5;
const float PI   = 3.1415926;

// 補間関数
float interpolate(float a, float b, float x){
    float f = (1.0 - cos(x * PI)) * 0.5;
    return a * (1.0 - f) + b * f;
}

// 乱数生成
float rnd(vec2 p){
    return fract(sin(dot(p ,vec2(12.9898,78.233))) * 43758.5453);
}

// 補間乱数
float irnd(vec2 p){
    vec2 i = floor(p);
    vec2 f = fract(p);
    vec4 v = vec4(rnd(vec2(i.x,       i.y      )),
                  rnd(vec2(i.x + 1.0, i.y      )),
                  rnd(vec2(i.x,       i.y + 1.0)),
                  rnd(vec2(i.x + 1.0, i.y + 1.0)));
    return interpolate(interpolate(v.x, v.y, f.x), interpolate(v.z, v.w, f.x), f.y);
}

// ノイズ生成
float noise(vec2 p){
    float t = 0.0;
    for(int i = 0; i < oct; i++){
        float freq = pow(2.0, float(i));
        float amp  = pow(per, float(oct - i));
        t += irnd(vec2(p.x / freq, p.y / freq)) * amp;
    }
    return t;
}

// シームレスノイズ生成
float snoise(vec2 p, vec2 q, vec2 r){
    return noise(vec2(p.x,       p.y      )) *        q.x  *        q.y  +
           noise(vec2(p.x,       p.y + r.y)) *        q.x  * (1.0 - q.y) +
           noise(vec2(p.x + r.x, p.y      )) * (1.0 - q.x) *        q.y  +
           noise(vec2(p.x + r.x, p.y + r.y)) * (1.0 - q.x) * (1.0 - q.y);
}

void main(void){
    vec2 q = (gl_FragCoord.xy * 2.0 - r);// / min(r.x, r.y);
    float d = noise(q+t*10.)*.2;
    //float d = snoise(q+t*10.,gl_FragCoord.xy/r,r)*.3;

    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    p+=d;
    p*=8.;
    float l = mod(floor(p.x)+floor(p.y),2.0);
    gl_FragColor = vec4(vec3(l), 1.0);
}

次にシームレスノイズを乗せてみます。

snoise.png

precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

const int   oct  = 8;
const float per  = 0.5;
const float PI   = 3.1415926;

// 補間関数
float interpolate(float a, float b, float x){
    float f = (1.0 - cos(x * PI)) * 0.5;
    return a * (1.0 - f) + b * f;
}

// 乱数生成
float rnd(vec2 p){
    return fract(sin(dot(p ,vec2(12.9898,78.233))) * 43758.5453);
}

// 補間乱数
float irnd(vec2 p){
    vec2 i = floor(p);
    vec2 f = fract(p);
    vec4 v = vec4(rnd(vec2(i.x,       i.y      )),
                  rnd(vec2(i.x + 1.0, i.y      )),
                  rnd(vec2(i.x,       i.y + 1.0)),
                  rnd(vec2(i.x + 1.0, i.y + 1.0)));
    return interpolate(interpolate(v.x, v.y, f.x), interpolate(v.z, v.w, f.x), f.y);
}

// ノイズ生成
float noise(vec2 p){
    float t = 0.0;
    for(int i = 0; i < oct; i++){
        float freq = pow(2.0, float(i));
        float amp  = pow(per, float(oct - i));
        t += irnd(vec2(p.x / freq, p.y / freq)) * amp;
    }
    return t;
}

// シームレスノイズ生成
float snoise(vec2 p, vec2 q, vec2 r){
    return noise(vec2(p.x,       p.y      )) *        q.x  *        q.y  +
           noise(vec2(p.x,       p.y + r.y)) *        q.x  * (1.0 - q.y) +
           noise(vec2(p.x + r.x, p.y      )) * (1.0 - q.x) *        q.y  +
           noise(vec2(p.x + r.x, p.y + r.y)) * (1.0 - q.x) * (1.0 - q.y);
}

void main(void){
    vec2 q = (gl_FragCoord.xy * 2.0 - r);// / min(r.x, r.y);
    //float d = noise(q+t*10.)*.2;
    float d = snoise(q+t*10.,gl_FragCoord.xy/r,r)*.3;

    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    p+=d;
    p*=8.;
    float l = mod(floor(p.x)+floor(p.y),2.0);
    gl_FragColor = vec4(vec3(l), 1.0);
}

あれ、なんか変わりないかも...。
どちらも、水面っぽくなりましたが、なんか微妙かも。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4