私は学習の練習として単純なボクセルレイキャスターを書こうとしています。これは純粋にCPUをベースにしています。今のところ、どのように動作するかを理解するまでは、OpenGLは単に生成されたビットマップを可能な限り頻繁にブリットするために使用されています。歪んだ:単純なCPUベースのボクセルレイキャスター/レイトレーサーの回転カメラ
私は遠近投影カメラが世界を動かすことができるようになりました。私は、「世界」の3次元視点を遠近法で正確に(現在は調査が必要なアーティファクトを除いて)レンダリングできます。基本的に空ですが、Stanford Bunnyのボクセルキューブを含んでいます。
私はカメラを持っていますので、上下左右にずらして前後に歩くことができます。すべての軸は今まで通り、カメラの回転はありません。ここに私の問題があります。
スクリーンショット:(1) raycasting voxels while......(2) the camera remains......(3) strictly axis-aligned.
は今、私は数日のために働く回転を取得しようとしています。理論上の行列と3D回転の基本的な論理と理論は、私には非常に明確です。しかし、カメラが回転すると「2.5レンダリング」しか達成できませんでした。Google Streetviewのような魚眼では、ボリュームメトリックな世界表現を持っていても、最初に「正面図」からレンダリングを作成し、次にカメラの回転に従ってその平坦なレンダリングを回転させます。言うまでもなく、私は、回転する光線が特に必要ではなく、エラーを起こしやすいことを認識しています。
はまだ、私の最も最近のセットアップでは、最も単純化されたレイキャスト線位置と方向のアルゴリズム可能で、私の回転がまだ同じ魚eyeyフラットレンダリング回転スタイルが見え生産:
camera "rotated to the right by 39 degrees" - - この回転では、スクリーン#2の立方体の青い影付きの左側がどのように見えているのか、今は "本当にすべき"ことに注意してください。
もちろん私はこれを知っています:最初に持っていたような簡単な軸 - 整列 - 回転設定では、光線は小さなステップで正のz方向を単に横切って左に発散しますまたはピクセルの位置および投影行列に応じて右および上または下にのみ移動する。私は "カメラを右または左に回転させる" - すなわち、私はそれをY軸の周りに回転させる - それらの非常に踏み込んだステップは、適切な回転行列で簡単に変換する必要があります。したがって、順方向のトラバーサルの場合、Zステップは、カムが回転するほど小さくなり、Xステップの「増加」によって相殺されます。しかし、画素位置ベースの水平+垂直発散については、xステップの増加分をzステップに「加算」する必要があります。何とか、私が実験した多くの行列のどれも、行列のないハードコードの冗長なsin/cos計算を使った私の実験でも、実際にこの部分を正しく取得することはできません。
- FXと年度:ピクセル位置xとy
- rayPosゴーで構文が、擬似コードとしてそれを取る -
は、ここに私の基本的なにつき線前トラバーサルアルゴリズムです:ワールド空間での光線開始位置のvec3(下に計算されます)
- rayDir:各ステップでrayPosにxyz-stepsを追加するvec3線トラバーサル
- rayStep一時vec3
- カンポス:ワールド空間内のカメラ位置のvec3
- camRad:ラジアンカメラ回転用vec3
- PMAT:典型的な透視投影マトリックス
アルゴリズム/擬似コード:
// 1: rayPos is for now "this pixel, as a vector on the view plane in 3d, at The Origin"
rayPos.X, rayPos.Y, rayPos.Z = ((fx/width) - 0.5), ((fy/height) - 0.5), 0
// 2: rotate around Y axis depending on cam rotation. No prob since view plane still at Origin 0,0,0
rayPos.MultMat(num.NewDmat4RotationY(camRad.Y))
// 3: a temp vec3. planeDist is -0.15 or some such -- fov-based dist of view plane from eye and also the non-normalized, "in axis-aligned world" traversal step size "forward into the screen"
rayStep.X, rayStep.Y, rayStep.Z = 0, 0, planeDist
// 4: rotate this too -- 0,zstep should become some meaningful xzstep,xzstep
rayStep.MultMat(num.NewDmat4RotationY(CamRad.Y))
// set up direction vector from still-origin-based-ray-position-off-rotated-view-plane plus rotated-zstep-vector
rayDir.X, rayDir.Y, rayDir.Z = -rayPos.X - me.rayStep.X, -rayPos.Y, rayPos.Z + rayStep.Z
// perspective projection
rayDir.Normalize()
rayDir.MultMat(pmat)
// before traversal, the ray starting position has to be transformed from origin-relative to campos-relative
rayPos.Add(camPos)
Iはトラバーサルをスキップし、部品をサンプリングいる - それらが、「基本的にほとんど正しい」(きれいではないが)であり、スクリーン#1に従って#3を介して - たときに軸整列/非回転。