6

私は現在レイトレーシング技術に取り組んでおり、かなり良い仕事をしたと思います。しかし、私はまだカメラをカバーしていません。

これまで、(-width/2, height/2, 200)(width/2, -height/2, 200)[200はzの固定数であり、変更可能]の間にあるビュー平面に平面フラグメントを使用していました。

それに加えて、私は主にでカメラe(0, 0, 1000)を使用し、透視投影を使用しています。

ポイントからピクセルに光線を送りe、ピクセルの色を計算した後、画像の対応するピクセルにそれを印刷します。ここに画像の説明を入力してください

これが私が作成した画像です。うまくいけば、画像を見ることで目とビュープレーンがどこにあるかを推測できます。

私の質問はここから始まります。カメラを動かす時が来ましたが、2Dビュー平面座標を正準座標にマッピングする方法がわかりません。そのための変換行列はありますか?

私が思う方法は、ビュー平面上のピクセルの3D座標を知る必要があります。それが正しい方法かどうかはわかりません。それで、あなたは何を提案しますか?

4

2 に答える 2

18

それを行うにはさまざまな方法があります。これが私がすることです:

  1. カメラの位置を表すポイントを選択します(camera_position)。
  2. カメラが向いている方向を示すベクトルを選択します(camera_direction)。(カメラが見ているポイントがわかっている場合は、camera_positionそのポイントから減算することでこの方向ベクトルを計算できます。)正規化(camera_direction)が必要になる場合があります。この場合、これは画像平面の法線ベクトルでもあります。
  3. カメラの観点から(ほぼ)「上」にある別の正規化されたベクトルを選択します(camera_up)。
  4. camera_right = Cross(camera_direction, camera_up)
  5. camera_up = Cross(camera_right, camera_direction)(これは、「上」の選択の傾斜を修正します。)

で画像平面の「中心」を視覚化しcamera_position + camera_directionます。上と右のベクトルは画像平面にあります。

画面に対応する画像平面の長方形のセクションを選択できます。この長方形のセクションの幅または高さとcamera_directionの長さの比率によって、視野が決まります。ズームインするには、camera_directionを大きくするか、幅と高さを小さくします。ズームアウトするには、反対の操作を行います。

したがって、ピクセル位置が与えられた場合、画像平面上のそのピクセルのが(i, j)必要になります。(x, y, z)そこから減算camera_positionして光線ベクトルを取得できます(これを正規化する必要があります)。

Ray ComputeCameraRay(int i, int j) {
  const float width = 512.0;  // pixels across
  const float height = 512.0;  // pixels high
  double normalized_i = (i / width) - 0.5;
  double normalized_j = (j / height) - 0.5;
  Vector3 image_point = normalized_i * camera_right +
                        normalized_j * camera_up +
                        camera_position + camera_direction;
  Vector3 ray_direction = image_point - camera_position;
  return Ray(camera_position, ray_direction);
}

これは説明を目的としているため、最適化されていません。

于 2012-10-25T23:20:43.903 に答える
4

ラスター化レンダラーの場合、3D座標から画面の2D座標に直接マッピングする方法であるため、変換行列が必要になる傾向があります。

レイトレーシングの場合、通常は2D空間の既知のピクセル座標から開始するため、これは必要ありません。

目の位置、画面の中央にある3空間のポイント、および「上」と「右」のベクトルを考えると、目の位置から指定されたものを通過する3D「光線」を計算するのは非常に簡単です。ピクセル。

以前、自分のレイトレーサーからサンプルコードをhttps://stackoverflow.com/a/12892966/6782に投稿しました。

于 2012-10-25T22:32:27.043 に答える