ランダム関数
恐らくもっとも使われている関数ですが、このオリジナルを使うとモバイル系がほぼ全滅するので、後述のものを使う。原因は精度不足。
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)
- ホモグラフィについて
- http://shogo82148.github.io/homepage/memo/geometry/homography/
- http://yaju3d.hatenablog.jp/entry/2013/08/04/152524
ここで、難度がとても高くなる。
外積(二次元)
//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));}