10

私はレイトレーサーを書いています(主に楽しみのために)。過去に1つ書いたことがあり、検索にかなりの時間を費やしましたが、透視投影で視線を計算する方法に光を当てるチュートリアルはないようです。 、行列を使用せずに。

私が最後にそれを行ったのは、クラスx/yを使用してカメラの方向ベクトルから目のベクトルの角度を(潜在的に)非効率的に回転させることによるものだと思います。QuaternionこれはC++で行われ、私はこれをC#で行っていますが、それほど重要ではありません。

擬似コード(V * Q =変換操作を想定)

yDiv = fovy / height
xDiv = fovx / width

for x = 0 to width
    for y = 0 to height

        xAng = (x / 2 - width) * xDiv
        yAng = (y / 2 - height) * yDiv
        Q1 = up vector, xAng
        Q2 = camera right vector, yAng
        Q3 = mult(Q1, Q2)

        pixelRay = transform(Q3, camera direction)
        raytrace pixelRay

    next
next

これに関する実際の問題は、フラットスクリーン表面ではなく、球面スクリーン表面をシミュレートしていることだと思います。

クロス積、ドット積、行列などを使用する方法と理由はわかっていますが、実際の3D数学の問題解決スキルは素晴らしいものではありません。

そのように与えられた:

  • カメラの位置、方向、アップベクトル
  • 視野
  • スクリーンピクセルおよび/またはサブサンプリング分割

レイトレーサーのx/yピクセル座標のアイレイを生成する実際の方法は何ですか?

明確にするために:私は正確に私が計算しようとしているものです、私はそれを計算するための3D数学を思い付くのが得意ではありません、そして私が見つけたレイトレーサーコードは私が目の光線を計算するために必要なコードを持っていないようです個々のピクセル。

ここに画像の説明を入力してください

4

1 に答える 1

13

ここに画像の説明を入力してください

INPUT: camera_position_vec, direction_vec, up_vec, screen_distance

right_vec = direction_vec x up_vec
for y from 0 to 1600:
    for x from 0 to 2560:
        # location of point in 3d space on screen rectangle
        P_3d = camera_position_vec + screen_distance*direction_vec
               + (y-800)*-up_vec
               + (x-1280)*right_vec

        ray = Ray(camera_position_vec, P_3d)
        yield "the eye-ray for `P_2d` is `ray`"

xクロス積を意味します

編集direction_vec:あるべきであるように、答えは正規化されていると仮定しました。right_vec写真にありますが(左があるように見えます)、right_vec必須ではなく、含まれている場合は、常にと同じ方向にある必要があります-(up_vec x direction_vec)。さらに、この図は、右に行くとx座標が増加し、下に行くとy座標が増加することを示しています。それを反映して、記号が少し変更されています。ズームは、方程式のx項とy項を乗算することによって実行することも、より効率的には、ベクトルを乗算してとを使用して実行することもできますscaled_up_vecscaled_right_vec。ただし、ズームは視野(FoV)を変更することと同等です(絞りは関係ありません。これは完璧なピンホールカメラです)。これは、任意の「ズーム」よりもはるかに適切な量です。FoVの実装方法については、以下の私のコメントをご覧ください。

于 2011-05-10T02:00:36.317 に答える