4

As I understand, the 'lookat' method is one of the simplest way to placing/rotate the camera in a scene. So I implemented the Matrix available on (https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/lookat-function) in the code of my ray-tracing but I have no idea of how using it to compute rays.

Basically what I do is place the camera at negatives Z, send a ray to positive Z and select the pixel iterating the X and Y of my view plane. It is easy because the view plane is in front of the camera and I have to simply assign X and Y of my iterations to ray destination X and Y. However I would like to be able to send ray in any part of the space.

Could you please help me to understand how to do that?

Thank you!

What I do basically:

{        
    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);
        }
    }
}

The functions to handle the lookat matrix:

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);
}
peppone
  • 85
  • 6
  • Transform the ray with the inverse look-at matrix. – Nico Schertler Jun 14 '19 at 02:46
  • Could you please provide me a more concrete example? – peppone Jun 14 '19 at 04:14
  • Please also provide the definitions of `t_vector` and more importantly `t_lookat`. – meowgoesthedog Jun 14 '19 at 08:28
  • see [Reflection and refraction impossible without recursive ray tracing?](https://stackoverflow.com/a/45140313/2521214) look for vertex shader in there `ray_dir` is the ray direction and `tm_eye` holds the [transformation](https://stackoverflow.com/a/28084380/2521214) of camera and `pos` is the input vertex representing position of pixel on the screen in `<-1,+1>` range. Beware on top of all that a perspective projection is applied ... – Spektre Jun 14 '19 at 09:31

1 Answers1

0

Thank you guys, finally I solved the problem reading this guide (https://steveharveynz.wordpress.com/2012/12/20/ray-tracer-part-two-creating-the-camera) which suggests to normalize coordinates (like the pixel range of the user "Spektre") without using a matrix.

Ps.

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;
peppone
  • 85
  • 6