LoginSignup
14
13

More than 5 years have passed since last update.

GLSLでifを使わずに条件分岐

Last updated at Posted at 2016-11-12

前提:モデルが複数の頂点座標を持ち、時間に応じて頂点座標を切り替える

main()から抜粋
// 速度
float speed = time * 2.0;

/* ======================================
 * ※1 アニメーション係数
 * ====================================== */ 

// mod : 除算の剰余
// 余りの計算なので割る数以上にはならない
// mod(x, 2.0) = 0.0 ~ 1.99999...
// animation = 0.0 ~ 0.99999...
float animation = max(mod(speed, 2.0) - 1.0, 0.0);

/* ======================================
 * ※2 条件分岐
 * ====================================== */ 

// ステップ数
float steps = 3.0;
// 現在のアクティブなインデックスを計算
float index = floor(mod(speed, 2.0 * steps) / 2.0);
// floor(0.0 ~ 2.99999...)
// 小数点以下を切り捨てると、index = 0 or 1 or 2

// step(閾値, x)
// 閾値 <= x のときは 1.0 , 閾値 > x のときは 0.0
// 1つ目の座標:index = 0.0 のときだけ first = 1.0
float first  = 1.0 - step(1.0, index); 
// 2つ目の座標:index = 1.0 のときだけ second = 1.0
float second = step(1.0, index) * (1.0 - step(2.0, index));
// 3つ目の座標:index = 2.0 のときだけ third = 1.0
float third  = step(2.0, index);

/* ======================================
 * 頂点座標の算出
 * ====================================== */

// mix : 線形補間
// mix(1.0, 6.0, 0.5) === 3.5 (1.0と6.0の50%の地点)
vec3 pos = vec3(0.0);
pos  = mix(positionZero, positionOne,  animation) * first;
pos += mix(positionOne,  positionTwo,  animation) * second;
pos += mix(positionTwo,  positionZero, animation) * third;
// first, second, thirdが 0.0 or 1.0 の状態なので、これでオンオフ(条件分岐)をしている
// mix(x,y,z)の値がなんであろうと、0.0をかけてしまえばゼロ!

// あとはこの座標を gl_Position に渡してあげればよい

引用
GLSLスクール サンプル018 より

アニメーション係数

mod(speed, 1.0) = 0.0 ~ 0.99999...を取得できるけれど、
0.0の状態を(静止状態)を一定時間維持したいので、
以下のようなノコギリ型の数値を得るためにmod(speed, 2.0) - 1.0という式で-1.0~1.0を取得し、max(x, 0.0)で0.0以下は0.0として扱っている。

1.0    /|   /|   /|
0.0 __/ |__/ |__/ |

【イージングする場合の参考】
見本 / コードはこちらをコピペ
smoothstepについて

条件分岐

secondの計算が肝

float second = step(1.0, index) * (1.0 - step(2.0, index));

second(index=1.0) より前のindexのとき、step(1.0, index)で 全体に0.0をかけることで、second = 0.0 にしている
second(index=1.0) より後のindexのとき、1.0 - step(2.0, index)で 全体に0.0をかけることで、second = 0.0 にしている

条件分岐を増やす場合
float second = step(1.0, index) * (1.0 - step(2.0, index));
float third = step(2.0, index) * (1.0 - step(3.0, index));
float fourth = step(3.0, index) * (1.0 - step(4.0, index));

参考
プログラマブルシェーダとGPUについて

14
13
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
14
13