今回、簡単なボクセライザーを作ったのでその実装方法を紹介しようかと思います。
ボクセル化自体、いろいろな方法がありますが今回はポリゴンデータからラスタライザの要領で直接ボクセル化を行う方法です。
FrameBufferを用いてボクセル化を行うにはGLUT入門で有名な@tokoik先生が記事を書いているのでそちらを参照してもらえればと思います。
さて、本題。
ラスタライザの要領と書きましたがラスタライザにも色々な実装方法がありますが、今回行った方法は一番簡単な(と思ってる)、三辺の一辺を終点とし、
開始点から徐々に辺を満たすように線を引く方法です。
実際のコード
//in the raster voxel func
v4f end_line = t.p[2] - t.p[1];
float const end_line_length = length(end_line);
end_line = norm(end_line);
unsigned const end_count = end_line_length / vox_len;
for(unsigned i = 0;i <= end_count;++i)
{
v4f const end_pos = t.p[1] + end_line * (i*vox_len);
v4f rast_line = end_pos - t.p[0];
float const rast_line_length = length(rast_line);
rast_line = norm(rast_line);
unsigned const rast_count = rast_line_length / vox_len;
//line painting
for(unsigned j = 0;j <= rast_count;++j)
{
v4f const p = t.p[0] + rast_line * (j*vox_len);
float const min_x = center[0] - (RES*vox_len)/2.f;
unsigned const x = std::max(static_cast<int>((p[0] - min_x)/vox_len),0);
float const min_y = center[1] - (RES*vox_len)/2;
unsigned const y = std::max(static_cast<int>((p[1] - min_y)/vox_len),0);
float const min_z = center[2] - (RES*vox_len)/2;
unsigned const z = std::max(static_cast<int>((p[2] - min_z)/vox_len),0);
voxel[x][y][z] = t.c;//painting voxel
}
}
この方法での利点はどれだけ広大なシーンであっても問題なくvoxelizeを行えるという点です。
しかし、この方法の場合テクスチャ参照を行い、色を決定する場合かなり面倒なことになるので基本的にはFrameBufferを用いた実装をした方がいいと思います。
最後に今回の実行結果。それでは皆様、良い御年を。
[...] 同人ゲーム制作日誌 床井研究室 – とっても簡単なボクセル化 Voxelizer実装 – LongGate Development Blog Robust Inside and Outside Solid Voxelization A New Method on Voxelizing Triangular Mesh Model [...]
返信削除