13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GPU で暖を取りたい人のための GLSLAdvent Calendar 2017

Day 11

glslで良く作られるユーティリティ関数

Last updated at Posted at 2017-12-13

ランダム関数

恐らくもっとも使われている関数ですが、このオリジナルを使うとモバイル系がほぼ全滅するので、後述のものを使う。原因は精度不足。

float rand(vec2 co){
   return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453);
}
highp float rand(vec2 co){
    highp float a = 12.9898;
    highp float b = 78.233;
    highp float c = 43758.5453;
    highp float dt= dot(co.xy ,vec2(a,b));
    highp float sn= mod(dt,3.14);
    return fract(sin(sn) * c);
}

もしくはモバイルの場合は、すべて高精度にしてしまう方法がある。

#ifdef GL_ES
precision highp float;
#endif

但し、この場合、高精度を指定したことによってシェーダーが動作しなくなってしまう端末があるらしい。※未確認

saturate関数

float saturate(float f){
   return clamp(f,0.,1.);
}

これは同名のhlslのシェーダー関数から、入力された値を0と1の間に限定する。フラグメントシェーダーでgl_FragColorで出力時0.より小さい数値は0.、1.より大きい数値は1.(saturateされて)として表示されるが、その前段で複数のシェイプ同士を+などで加算した場合は、特にsaturateされていないので、思わぬ不具合の元となる。
シェイプ同士の合成のあとは必ずと言って掛けるので、中級以上の場合、必ずと言っていいほど作っている。

#define saturate(x) clamp(x,0.,1.)

saturate関数の場合はdefineで作ったほうがいい

アフィン変換

回転(2D)

mat2 rot(float r){float c=cos(r);float s=sin(r);return mat2(c,-s,s,c);}

拡大・縮小(2D)

mat2 scale(vec2 s){
    return mat2(s.x,0.,0.,s.y);
}

拡大・縮小に関して言えばvec2(s.x,s.y)と同じなので使われることは少ないかもしれない。

mat2(s.x,0.,0.,s.y) = vec2(s.x,s.y);
p*=mat2(s.x,0.,0.,s.y);
p*=vec2(s.x,s.y);

xとyが同じ拡大・縮小率の場合は単にnを掛けるだけである

p*=n;

シアー(せん断・スキュー) (2D)

mat2 sheerX(float a){return mat2(1.,tan(a),0.,1.);}
mat2 sheerY(float a){return mat2(1.,0.,tan(a),1.);}

あまり、使われないが、任意の四角形変形が使えない時に使える

ホモグラフィ homography (四角形変形) (2D)

ここで、難度がとても高くなる。

外積(二次元)

//float cross(vec2 v1, vec2 v2) {return v1.x*v2.y - v1.y*v2.x;}
float cross(vec2 v1, vec2 v2) {return dot(v1,vec2(v2.y,-v2.x));}

3次元の外積は組み込み関数として用意されているが2次元は用意されていないので、作っておくと便利
外積の3次元ベクトルで返ってくるが、2次元はスカラー、ベクトルで返すこともできるが有効成分がスカラーなので、使われることはない。

公式通りとしてもいいが、組み込み関数がないので、内積(dot)にv2の逆行列を掛けてもいいのでこれで高速化している。

pow(vec3対応)

トーンカーブ的に、コントラストを上げたい時に使う

vec3 pow(vec3 c,float p){return vec3(pow(c.r,p),pow(c.g,p),pow(c.b,p));}
13
14
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
13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?