2012年2月24日金曜日

Raycasting

3D CG Programmingnの時間です。

さて、前回ボクセルシーンを生成した訳ですが。
今回はそのデータを用いてRayCastを行ってみました。

RayCastとは:
RayMarchingとほぼ同じ意味で使われますが、簡単に言えばボリュームデータに対し、線分を少しづつ進めて交差判定を行う方法の事です。
用途としては、1[煙等、透過するオブジェクトのレンダリング]
2[X線画像等の体積を持ったデータの可視化]
ですが、最近リアルタイムレンダリングの界隈でライティング計算に用いるようになってきました。

流行に乗るために簡単な実装を行いました。
video

で、問題のRaycasting部分
//in raycast function
//*r is ray
int const size = res * center.w;
float4 const mini = center - size*0.5f;

for(int i = 1;1;++i)
{
float4 const p = r.orig_ + r.dir_*i*center.w;
float4 const r_vox_pos = ( p - mini )/center.w;
int4 const r_vox_pos_i = convert_int(r_vox_pos);

//exit without hit
if(r_vox_pos_i.x < 0 || r_vox_pos_i.x >= res-1 ||
r_vox_pos_i.y < 0 || r_vox_pos_i.y >= res-1 ||
r_vox_pos_i.z < 0 || r_vox_pos_i.z >= res)
return false;

sphere sp;
sp.pos_ = convert_float(r_vox_pos_i)*center.w - size/2.f + center.w*0.5f;
sp.r_ = center.w*0.5f;
float t;

if( sphere_intersect(r,sp,&t) )
{
// hit actions
return true;
}

ここで交差した部分のボリュームデータが半透明な物であれば線分の開始点を書き換え(必要であればライティングも)て再びRaycastを行えばボリュームレンダリングになります。
また、今回は交差判定にbounding sphereを用いてますが、一般的にはAABBを使った方がクオリティの問題で良いと思います。

ではまた何かネタが出来たときに。

0 件のコメント:

コメントを投稿