座標をメッシュワープする時の考え方

先日openFramworksでテクスチャのメッシュワープのような形で座標のメッシュワープをすることになったのだが、メッシュワープはメッシュの四角形それぞれの透視変換の集合ではない、という落とし穴にハマった。てっきりそう思ってたので透視変換行列を計算してたのだが、境界で滑らかに座標を移動してくれなくて困ってたら考え方が間違っていた。単純に縦横の比率で計算して出してやればよかった。

具体的には、上辺と下辺で元の比率と同じ場所に点を打ってその点どうしを結び、それを右辺と左辺でも同様にやった交点が変換後の座標になる。図を見てもらったほうが早いと思う。

f:id:miso_engine:20180508171437j:plain

テクスチャのメッシュワープ自体は、OpenGLなど、3Dのフレームワークの基礎なので、特に問題なくofxMeshWarpを利用した。
https://github.com/nariakiiwatani/ofxMeshWarp

GLSLで座標から角度を取得するためのatan2と角度のラップ

座標から角度を求めるatan2

フラグメントシェーダーを使っててある場所とある場所の角度を求めたい時がある。今回はGLSLなんだけど、atanを使えばいいのかな?と思ってやってみると円の反対側も同じ値が返ってきてしまうので微妙に使えない。C言語系統でいうatan2だといけるのだが、GLSLにatan2はないのでググって出てきたスタックオーバーフローの実装を使った。

c++ - Robust atan(y,x) on GLSL for converting XY coordinate to angle - Stack Overflow

float PI = 3.141592653589793;

float atan2(in float y, in float x)
{
    return x == 0.0 ? sign(y)*PI/2 : atan(y, x);
}

角度をラップする関数

角度って難しいので常に-180度 ~ 180度に収めるための関数をopenFrameworksのofWrapDegreesを参考に実装。atan2とあわせて色々ゴニョゴニョとやっていた。

https://github.com/openframeworks/openFrameworks/blob/master/libs/openFrameworks/math/ofMath.cpp

float wrapDegrees(in float value){
    float from = -180;
    float to = 180;
    float cycle = to - from;
    return value - cycle * floor((value - from) / cycle);
}

おわりに

オープンソースのプロジェクトは言語が異なってもコピペで持ってこれることがあるので大変ありがたいですね。みなさんも素敵なシェーダーライフをお送りください。

OpenGL 4.0 シェーディング言語 -実例で覚えるGLSLプログラミング-

OpenGL 4.0 シェーディング言語 -実例で覚えるGLSLプログラミング-

openFrameworksでマルチモニタの時に、ofSetFullscreen()を使わずに全画面化する

f:id:miso_engine:20180119221819p:plain

OSはWindows10で、画面配置はこんな感じ。左の画面はオペレーション用にoFの画面を表示せず、右の2つの表示用画面(720P x 2 = 1280 x 1440)にまたがってフルスクリーンにしたかったのです。

main.cppでofGLFWWindowSettingsを使ってウィンドウのサイズと場所を指定し、decoratedをfalseにすると出来る。簡単ですね。このdecoratedオプション、デフォルトだとtrueで、その場合だとウィンドウの枠が表示されるんですな。

Beyond Interaction[改訂第2版] -クリエイティブ・コーディングのためのopenFrameworks実践ガイド

Beyond Interaction[改訂第2版] -クリエイティブ・コーディングのためのopenFrameworks実践ガイド