WebGL Canvas2D 原点位置の違い

この記事は、webgl-jp Slack内の情報を元に構成されています。

webgl-jp.slack

 

 

canvas2dで画像を読み込み、各頂点色を抜き出し、抜き出した色をパーティクルに適応するということをやっているのですが、canvas2dとwebglの原点位置の違いから、画像が90度反時計回りに表示されています。
多分行列で回転掛けるのだと思うのですが、javascriptのFloat32Arrayは1次元配列なのでそのままじゃ計算できない気がします。

 

これは WebGL 云々というより、パーティクルに相当する頂点のひとつひとつに、どのように色をアタッチするのかを変えることによって解決すべきじゃないかな。

行列なんかで回転させる処理を記述してしまうと、そのあとが大変になってしまいそう。

たとえば、一次元配列の imagedata を、恐らく二重の for ループとかで処理していると思うんですけど、外側と内側との役割を反転させるだけでも、色のアタッチされる順序が変化するような気がするけど、どうですかね。

 

var imagedata = なんか;
var w = canvas.width;
var h = canvas.height;
var i, j, k, l;
var x, y;

var position = [];
var texCoord = [];

for(i = 0; i < h; ++i){
    k = i / h; // ここが texCoord.y に相当
    y = (k + 1.0) / 2.0;
    for(j = 0; j < w; ++j){
        l = j / w; // ここが texCoord.x に相当
        x = (l + 1.0) / 2.0;
        position.push(x, y, 0.0);
        texCoord.push(l, k);
    }
}

 

上のコードに、そのまま imagedata から抜いてきた色を適用するとしたらを下に書きますね。

 

var imagedata = なんか;
var w = canvas.width;
var h = canvas.height;
var i, j, k, l, m, n;
var x, y;

var position = [];
var texCoord = [];
var color = [];

for(i = 0; i < h; ++i){
    k = i / h; // ここが texCoord.y に相当
    y = k * 2.0 - 1.0; // -1.0 ~ 1.0 の position.y
    m = i * w; // これが imagedata 内の縦方向のインデックス
    for(j = 0; j < w; ++j){
        l = j / w; // ここが texCoord.x に相当
        x = l * 2.0 - 1.0; // -1.0 ~ 1.0 の position.x
        position.push(x, y, 0.0);
        texCoord.push(l, k);
        
        n = (m + j) * 4; // これが imagedata 内の対象ピクセルのインデックス
        color.push(
            imagedata[n],
            imagedata[n + 1],
            imagedata[n + 2],
            imagedata[n + 3]
        );
    }
}

 

要は RGBA ごとに格納されている一次元配列の imagedata から、きちんと縦方向と横方向が破綻しないように色を抜き出して VBO の元になるデータに突っ込むわけです。