【问题标题】:How to use a lookAt matrix to compute ray in raytracing?如何在光线追踪中使用 lookAt 矩阵来计算光线?
【发布时间】:2019-10-28 09:07:46
【问题描述】:

据我了解,“lookat”方法是在场景中放置/旋转相机的最简单方法之一。所以我在我的光线追踪代码中实现了 (https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/lookat-function) 上可用的矩阵,但我不知道如何使用它来计算光线。

基本上我所做的是将相机放置在负 Z,向正 Z 发送一条射线,然后选择迭代我的视图平面的 X 和 Y 的像素。 这很容易,因为视图平面位于相机前面,我必须简单地将迭代的 X 和 Y 分配给射线目标 X 和 Y。 但是我希望能够在空间的任何部分发送光线。

能否请您帮我理解如何做到这一点?

谢谢!

我基本上是做什么的:

{        
    double deg = 50.;
    double rad = deg / (180.0 / M_PI);
    double distance = (WIDTH / 2) * (cotan(rad / 2));
    ray.orig.x = HEIGH / 2.0;
    ray.orig.y = WIDTH / 2.0;
    ray.orig.z = -distance;
    y = -1;
    while (++y <= HEIGH)
    {
        x = -1;
        while (++x <= WIDTH)
        {
            ray.dest.x = x - ray.orig.x;
            ray.dest.y = y - ray.orig.y;
            ray.dest.z = 0. - ray.orig.z;
            ray.dest = ve_normalize(&ray.dest);
            check_objects(c, &ray, 0);
            add_diffuse_light(c);
            put_pixel(c, &x, &y);
        }
    }
}

处理观察矩阵的函数:

t_lookat    lookati(t_vector *from, t_vector *to)
{
    t_lookat    lookat;
    t_vector    fo;
    t_vector    ri;
    t_vector    up;

    t_vector tmp;
    tmp.x = 0; tmp.y = 1; tmp.z = 0;
    fo = ve_subtraction(from, to);
    fo = ve_normalize(&fo);
    ri = ve_cross(&tmp, &fo);
    ri = ve_normalize(&ri);
    up = ve_cross(&fo, &ri);
    up = ve_normalize(&up);

    lookat.ri.x = ri.x;
    lookat.ri.y = ri.y;
    lookat.ri.z = ri.z;
    lookat.up.x = up.x;
    lookat.up.y = up.y;
    lookat.up.z = up.z;
    lookat.fo.x = fo.x;
    lookat.fo.y = fo.y;
    lookat.fo.z = fo.z;
    lookat.fr.x = from->x;
    lookat.fr.y = from->y;
    lookat.fr.z = from->z;

    return(lookat);
}

t_vector    orientate(t_vector *a, t_vector *from, t_vector *to)
{
    t_lookat k;

    k = lookati(from, to);
    t_vector orientate;

    orientate.x = a->x * k.ri.x + a->y * k.up.x + a->z * k.fo.x + a->x * k.fr.x;
    orientate.y = a->x * k.ri.y + a->y * k.up.y + a->z * k.fo.y + a->x * k.fr.y;
    orientate.z = a->x * k.ri.z + a->y * k.up.z + a->z * k.fo.z + a->x * k.fr.z;

    return(orientate);
}

【问题讨论】:

  • 用逆观察矩阵变换光线。
  • 你能给我一个更具体的例子吗?
  • 请同时提供t_vector的定义,更重要的是t_lookat
  • Reflection and refraction impossible without recursive ray tracing? 在那里寻找顶点着色器ray_dir 是光线方向,tm_eye 持有相机的transformationpos 是表示像素位置的输入顶点&lt;-1,+1&gt; 范围内的屏幕。最重要的是要注意应用透视投影...

标签: c graphics 3d raytracing


【解决方案1】:

谢谢你们,最后我解决了阅读本指南 (https://steveharveynz.wordpress.com/2012/12/20/ray-tracer-part-two-creating-the-camera) 的问题,该指南建议在不使用矩阵的情况下标准化坐标(如用户“Spektre”的像素范围)。

附言

typedef struct  s_vector
{
    double      x;
    double      y;
    double      z;
}               t_vector;

typedef struct  s_lookat
{
    t_vector    ri; //right vector
    t_vector    up; // up
    t_vector    fo; // foorward
    t_vector    fr; // eye position
}               t_lookat;

【讨论】:

    猜你喜欢
    • 2012-05-23
    • 2012-11-13
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    相关资源
    最近更新 更多