2016-09-15 6 views
1

現在、CPUベースの単純なレイトレーサを使用して、プロジェクトとしての三角形をほとんどレンダリングしていません。私は実際の光線を生成することを除いて、それのあらゆる面で大丈夫です。世界座標をスクリーン空間に投影するのではなく、3D座標でのカメラの位置に応じて実際に光線を作成します。回転コンポーネントを使用した3D空間でのキャスティングレイ

今、私はかなり良いアルゴリズムを持っています。これは、Y軸の周りの回転に対してスクリーン上の各ピクセルの光線を生成することを可能にし、X軸も取り込み、ユーザが見上げたり見下ろしたりすると、画像が歪んでしまいます。

これは私がこれまで働いてきたものである:

Ray ray = new Ray(Camera.position, 
       new Vector3(
         Math.sin(Camera.rotation.y+(x*2/Main.renderSize.width)/2) * Math.cos(Camera.rotation.x+(y*2/Main.renderSize.height)/2), 
         Math.sin(Camera.rotation.x+(-y*2/Main.renderSize.height)/2), 
         Math.cos(Camera.rotation.y+(x*2/Main.renderSize.width)/2) * Math.cos(Camera.rotation.x-(y*2/Main.renderSize.height)/2) 
         )); 

これは私のカメラが任意の上向きまたは下向きの方向に向いていない良好な視野投影を与えます。投影の

画像カメラが前方である:

img

投影画像カメラが若干上向き

imgを探しています。

誰でもアルゴリズムを手伝ったり、新しいものや良い情報源に向けることができれば幸いです。速度はすべてリアルタイムであるため、速度が必要です。ありがとう。

+0

PS、xとyは画面中心からの距離(ピクセル単位) –

+0

各スクリーンピクセルを世界座標に変換すると、光線の原点があり、方向は焦点から同じピクセル位置ですユニットベクトルに正規化された)回転を忘れてください。代わりに、[4x4均質行列](http://stackoverflow.com/a/28084380/2521214)を使用してください。 – Spektre

+0

@ Spektreのコメントを詳しく説明してください。順方向レンダリングで通常行うように、内在パラメータを投影行列として使用します。次に、すべてのスクリーン座標を逆座標でワールド座標のレイに投影します。 [この回答](http://stackoverflow.com/a/19153090/1210053)が役立ちます。 –

答えて

0

次に、方向が間違っている可能性があります。そこでここではより明確にすることは、私はより詳細に、私のコメントで何を意味するのかである:

ray

だから、すべてのものは、カメラ座標系の空間であると仮定してみましょう。画面は平面z=0にあり、中央のピクセルは(0,0,0)です。焦点はfocus=(0,0,-f)です。fは投影の焦点距離です。あなたのx、y座標は、ワールド単位が、ピクセルでない場合

pos = (x,y,0); 
dir = pos-focus = (x,y,f); 
// most likely you should also normalize it so 
dir = dir/|dir|; 

ではなく、それに応じてそれらを再スケールする必要があります。その位置と方向があるので、今、あなたは、画素ごとに線(またはそれ以上)をキャストする必要があります。だから、あなたは、このすべてのビットを変更する必要があり、画面xs,ysの解像度を持ってみましょう、我々はxFOVx = 60.0degの視野を持つようにしたい:

// pixel size 
sz = f*tan(0.5*FOVx)/(0.5*xs); 
// x,y screen position [pixels] -> xx,yy [world units] 
xx=(x-(0.5*xs))*sz; 
yy=(y-(0.5*ys))*sz; 
// ray 
pos = (xx,yy,0); 
dir = pos-focus = (xx,yy,f); 
dir = dir/|dir|; 

は今transformation matrixに入っています。あなたの画面を表す変換行列をMとします。原点は画面の中央に設定され、x,yの軸ベクトルは画面の軸に対応します。あなたはすべてのものを作りたいとあなたはまた、世界に画面空間から変換するために、その後GCS世界グローバル座標系M0Mのコピーであるマトリックスが、(0,0,0)

に設定原点としない必要があります。

world_position = M *screen_position; 
world_direction = M0*screen_direction; 

ただし、上記のリンクで異なる行列要素とオペランドの順序の規則を使用すると、これはわずかに異なる可能性があります。

だから今、世界の光線GCSは次のようになります。

// pixel size 
sz = f*tan(0.5*FOVx)/(0.5*xs); 
// x,y screen position [pixels] -> xx,yy [world units] 
xx=(x-(0.5*xs))*sz; 
yy=(y-(0.5*ys))*sz; 
// ray 
pos = (xx,yy,0); 
dir = pos-focus = (xx,yy,f); 
// convert to world GCS 
pos = M *pos; 
dir = M0*dir; 
// normalize 
dir = dir/|dir|; 

通常あなたが単位行列としてMで始めることができますし、それからだけでビューの移動と回転を処理するために、キーストロークに回転し、翻訳を掛けます。各レンダリングの前に、M0=Mを計算し、原点を保持する3つの要素をゼロに設定するだけです。

関連する問題