-2

だから、私はレイトレーサーを書いていて、ビューポートを表す基本的なクラスがあります。次のようになります。

camera.hpp:

#define real double

class Camera
{
    // self explanatory
    Vector3 origin, destination, up;

    // camera's coordinate system
    // N    = normal to projection plane ("z-axis")
    // U, V = x- and y-axes of projection plane
    Vector3 N, U, V;

    // Directional increment vectors for screen-space X and Y
    Vector3 xInc, yInc;

    // vFOV derived from hFOV
    real    horizontalFOV, verticalFOV;

    // width and height of projection buffer in pixels
    real    width, height;

public:
    // Constructs a camera
    // pO   = point of origin (i.e., where rays are emitted)
    // pLA  = point looked at, (i.e., pLA - pO = direction looked at)
    // vUp  = Up vector relative to camera's position
    // hFOV = Horizontal field-of-view in degrees. Vertical is calculated based on
    //        aspect ratio of viewport.
    // vW   = width of viewport in pixels
    // vH   = height of viewport in pixels
    Camera(Vector3 pO, Vector3 pLA, Vector3 vUp,
           real hFOV,  real vW,     real vH);

    // Constructs a ray from pO looking in the direction of the 
    // specified pixel on the viewport. Note that floating values
    // can be given, in case we want to do supersampling.
    Ray RayForPixel(const real x, const real y);

    // Prints this camera's information to stdout.
    void dump();
};

カメラ.cpp:

#include "raytracer.hpp"

Camera::Camera(Vector3 pO, Vector3 pLA, Vector3 vUp, real hFOV, real vW, real vH) :
    origin(pO), destination(pLA), up(vUp), horizontalFOV(hFOV), width(vW), height(vH)
{
    // Non-square aspect ratios are not yet supported!
    assert(width == height);

    N = (pLA - pO);
    normalize(N);

    U = cross(N, vUp);
    normalize(U);

    V = cross(U, N);
    normalize(V);

    real aspectRatio = (width / height);
    verticalFOV      = (horizontalFOV / aspectRatio);

    // TODO: verify this.
    real hFov2 = horizontalFOV / 2;
    real vFov2 = verticalFOV / 2;

    // TODO: implement non-square aspect ratios
    xInc = -U * ((2.0 * tan(DEG2RAD(vFov2))) / width);
    yInc = -V * ((2.0 * tan(DEG2RAD(vFov2))) / height);
}

Ray Camera::RayForPixel(const real x, const real y)
{
    Vector3 direction = N + 
         (yInc * (0.5 * ((2.0 * y) - 1.0 - height) ) ) +
         (xInc * (0.5 * ((2.0 * x) - 1.0 - width ) ) );

    printf("<%f, %f, %f> ", xInc.x, xInc.y, xInc.z);
    normalize(direction);

    return Ray(origin, direction);
}

void Camera::dump()
{
    Vector3 rfp00 = RayForPixel((real)0, (real)0).direction;
    Vector3 rfp01 = RayForPixel((real)0, height - 1).direction;
    Vector3 rfp10 = RayForPixel(width - 1, (real)0).direction;
    Vector3 rfp11 = RayForPixel(width - 1, height - 1).direction;

    Vector3 rfp50 = RayForPixel((width/2) - 1, (real)0).direction;
    Vector3 rfp05 = RayForPixel((real)0, (height/2) - 1).direction;
    Vector3 rfp55 = RayForPixel((width/2) - 1, (height/2) - 1).direction;

    printf(
    "Camera at <%+7.5f, %+7.5f, %+7.5f>\n"
      "    hFOV = %+7.5f, vFOV = %+7.5f\n"
      "    xInc = <%+7.5f, %+7.5f, %+7.5f>\n"
      "    yInc = <%+7.5f, %+7.5f, %+7.5f>\n"
      "  Coordinate system:\n"
      "    N: <%+7.5f, %+7.5f, %+7.5f>\n"
      "    U: <%+7.5f, %+7.5f, %+7.5f>\n"
      "    V: <%+7.5f, %+7.5f, %+7.5f>\n"
      "  Rays for screen-space extents:\n"
      "    < 0,  0> -> <%+7.5f, %+7.5f, %+7.5f>\n"
      "    < 0,  1> -> <%+7.5f, %+7.5f, %+7.5f>\n"
      "    < 1,  0> -> <%+7.5f, %+7.5f, %+7.5f>\n"
      "    < 1,  1> -> <%+7.5f, %+7.5f, %+7.5f>\n"
      "    <.5,  0> -> <%+7.5f, %+7.5f, %+7.5f>\n"
      "    < 0, .5> -> <%+7.5f, %+7.5f, %+7.5f>\n"
      "    <.5, .5> -> <%+7.5f, %+7.5f, %+7.5f>\n",
        origin.x, origin.y, origin.z,
        horizontalFOV, verticalFOV,
        xInc.x, xInc.y, xInc.z,
        yInc.x, yInc.y, yInc.z,
        N.x, N.y, N.z,
        U.x, U.y, U.z,
        V.x, V.y, V.z,
        rfp00.x, rfp00.y, rfp00.z,
        rfp01.x, rfp01.y, rfp01.z,
        rfp10.x, rfp10.y, rfp10.z,
        rfp11.x, rfp11.y, rfp11.z,
        rfp50.x, rfp50.y, rfp50.z,
        rfp05.x, rfp05.y, rfp05.z,
        rfp55.x, rfp55.y, rfp55.z);
}

私はこのように作成し、呼び出していdump()ます:

Camera camera = Camera(
        Vector3(0, 0, -5), // Look from <0, 0, -5>
        Vector3(0, 0, 0),  // Look at world-space origin
        Vector3(0, 1, 0),  // Camera is XZ axis-aligned.
        70,                // 70 degree horizontal FoV
        OUT_W, OUT_H);

raytracer.SetCamera(&camera);

// later, in raytracer::render:
camera->dump();

そして、私はこの出力を取得します:

Camera at <+0.00292, +0.99996, +0.00292>
    hFOV = +0.02527, vFOV = -0.00891
    xInc = <+0.01170, -0.00878, +0.00292>
    yInc = <+0.99996, +0.00292, +0.99964>
  Coordinate system:
    N: <+0.99996, +0.00292, -0.00875>
    U: <+0.00292, +0.99996, +0.00292>
    V: <+0.99996, +0.00292, +0.99989>
  Rays for screen-space extents:
    < 0,  0> -> <-0.00292, +0.00292, +0.99999>
    < 0,  1> -> <-0.00292, +0.00875, +0.99996>
    < 1,  0> -> <-0.00875, +0.00292, +0.99996>
    < 1,  1> -> <-0.00875, +0.00875, +0.99992>
    <.5,  0> -> <-0.00875, +0.00292, +0.99996>
    < 0, .5> -> <+0.99989, +0.01170, -0.00878>
    <.5, .5> -> <+0.99964, +0.02527, -0.00891>

なぜこれが起こっているのかまったくわかりません.これは、過去3日間のWTFの主な原因でした.

編集: 私は実際に私の問題を説明する必要がありました, 申し訳ありません D: (この問題について少しストレスを感じていました. 私のコードでは、hFOV = vFOV を設定していますが、出力はそれに対応していません。私の二重算術の残りの部分もうまくいきませんでした。

Michael Dorgan は、カメラが範囲外のスタック var であった可能性があると指摘しましたが、まさにそれでした!

4

1 に答える 1

6

Camera は(おそらく)スタック変数であり、保存しています。対象外になるのでしょうか?:)

于 2013-05-29T23:29:45.290 に答える