のぐそんブログ

暗いおじさんがシコシコ書くブログです。

for文でタイルレイアウトをやってみる

以前の記事mod関数をつかってもタイルレイアウトを試したのですが、for文のほうが馴染みがあるのでfor文を使ってやってみます。

最終的な完成イメージは↓のような感じです。

参考

今回は「GLSL で光の点をぐるぐるアニメーションさせるやつ書いてみた」を参考にさせていただきました。 私の記事を見るより参考記事を見たほうが遥かにわかりやすいです。

考え方

当たり前ですが、タイルの数分for文を回す。

//行数
const int col = 5;
//列数
const int row = 3;

for(int i ; i < col; i ++){
    for(int j; j < row; j ++){
    
    }
}

各タイルの基準点を決める。 イメージ的には下記の画像のような感じです。

//行数
const int col = 5;
//列数
const int row = 3;
//画面幅
float w = resolution.x;
//画面高さ
float h = resolution.y;
//タイルの幅
float tileW = w/float(col);
//タイルの高さ
float tileH = h/float(row);


for(int i ; i < col; i ++){
    for(int j; j < row; j ++){
        float x = tileW * float(i) + tileW/2.0;
        float y =  tileH * float(j) + tileH/2.0;
        vec2 pos = vec2(x,y);
    }
}

描画されるピクセルの座標(gl_FragCoord.xy)と各基準点との距離を取得する。

//行数
const int col = 5;
//列数
const int row = 3;
//画面幅
float w = resolution.x;
//画面高さ
float h = resolution.y;
//タイルの幅
float tileW = w/float(col);
//タイルの高さ
float tileH = h/float(row);


for(int i ; i < col; i ++){
    for(int j; j < row; j ++){
        float x = tileW * float(i) + tileW/2.0;
        float y =  tileH * float(j) + tileH/2.0;
        vec2 pos = vec2(x,y);
        //距離を取得
        float dist = length(gl_FragCoord.xy - pos);
    }
}

あとは、距離の長さによって色を制御する。 基準点より距離が離れれば、離れるほど0.0に近づくようにします。

※pow関数で2乗してるのは、白くなりすぎないようにするためです。

//行数
const int col = 5;
//列数
const int row = 3;
//画面幅
float w = resolution.x;
//画面高さ
float h = resolution.y;
//タイルの幅
float tileW = w/float(col);
//タイルの高さ
float tileH = h/float(row);
//最終的な描画色
float color = 0.0;


for(int i ; i < col; i ++){
    for(int j; j < row; j ++){
        float x = tileW * float(i) + tileW/2.0;
        float y =  tileH * float(j) + tileH/2.0;
        vec2 pos = vec2(x,y);
        //距離を取得
        float dist = length(gl_FragCoord.xy - pos);
        //色の調整
        color += pow(size/dist, 2.0);
    }
    //描画
    gl_FragColor = vec4(vec3(color), 1.0);
}

動かしてみる

描画した白丸を動かしてみます。 考え方てきには、基準点をtime変数をつかって動かしていくだけです。

void main() {
    float size = 1.0 ;
    float color = 0.0;
    for (int i = 0; i < col; ++i) {
        for (int j = 0; j < row; ++j) {
            float x = tileW * float(i) + tileW/2.0 + cos(time) * 20.0;
            float y =  tileH* float(j) + tileH/2.0+ sin(time)* 20.0;
            vec2 pos = vec2(x, y);
            float dist = length(gl_FragCoord.xy - pos);
            color += pow(size/dist, 2.0);
        }
    }
    gl_FragColor = vec4(vec3(color), 1.0);
}

回転しだします。

test.gif