LoginSignup
4
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-11

はじめに

GLSL シェーダスクール 2017 の講義内容の復習を兼ねて、複数の講義内容を組み合わせてやってみます。

まず、背景となる市松模様のパターンを作ります。

ichimatsu.png

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

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

次にハイトマップを作りましょう

今回は水面の波紋をイメージして作っています。
ripple.png
https://goo.gl/hC2MHH

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

void main(void){
    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    float d=sin(length(p)*30.-t*10.);
    gl_FragColor = vec4(vec3(d), 1.0);
}

注意点としては、プロシージャルにヘイトマップを作る場合は、テクスチャーで用意する場合と違って-0.5してマイナスの値を作る必要がないというところです。

合成しましょう。

ripplewater.png
https://goo.gl/1XmQ6Q

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

void main(void){
    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    float d=sin(length(p)*30.-t*10.);
    p+=d*.1;
    p*=4.;
    float l = mod(floor(p.x)+floor(p.y),2.0);
    gl_FragColor = vec4(vec3(l), 1.0);
}

このままだと、ずっと波紋の高さが一緒のままですので、距離に応じて減衰するようにしてもいいでしょう。

最後に

疑似ディスプレイスメントマップめっちゃ簡単ですね。

応用して、ノイズ関数で雲模様を作ってヘイトマップとして適用すると水面の揺れを再現できたり
ヘイトマップをパーティクルにすると、水滴の表現や、炎の陽炎の表現が出来たりするので色々ためしてみましょう!

参考

4
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
4
4