2017-02-02 4 views
0

Je suis actuellement en train de coder un raytracer simple en C. Tout fonctionne correctement, sauf pour les rotations. J'essaye de faire pivoter mes objets (cylindres d'ailleurs). Les cylindres tournent, mais les ombres sont complètement éteintes et l'objet ne fait que tourner entre 0 ° et 90 °, et revient à la normale à 360 ° (ce qui est évident). J'apprécierais que quelqu'un puisse me donner un indice sur ce que je fais de mal. Voici un exemple de code.Raytracing Rotations

Fonction qui trouvent des intersections pour les cylindres:

double  mininter; 
    double  inter; 
    t_vect  *normal; 
    t_color  *c; 
    t_cyl  *cyl; 

    cyl = e->scene.cyls; 
    mininter = -1; 
    while (cyl != NULL && limiter-- != 0) 
    { 
     ray = rotate_eye(ray, cyl->rotate, -1); 
     inter = cylinder_inter(cyl, ray); 
     if (inter > ACCURACY && (inter < mininter || mininter == -1)) 
     { 
      mininter = inter; 
      p = vect_add(ray->og, vect_mult(ray->dir, inter)); 
      ray = rotate_eye(ray, cyl->rotate, 1); 
      normal = cylinder_normal(cyl->og, p); 
      c = cyl->color; 
     } 
     cyl = cyl->next; 
    } 
    return (new_inter(normal, mininter, c, p)); 

Mon fichier rotation.c:

static t_vect *x(t_vect *v, double rot, int stage) 
{ 
    rot = DEG_TO_RAD(rot * stage); 
    v->y = v->y * cos(rot) + v->z * -sin(rot); 
    v->z = v->y * sin(rot) + v->z * cos(rot); 
    return (v); 
} 

static t_vect *y(t_vect *v, double rot, int stage) 
{ 
    rot = DEG_TO_RAD(rot * stage); 
    v->x = v->x * cos(rot) + v->z * sin(rot); 
    v->z = v->x * -sin(rot) + v->z * cos(rot); 
    return (v); 
} 

static t_vect *z(t_vect *v, double rot, int stage) 
{ 
    rot = DEG_TO_RAD(rot * stage); 
    v->x = v->x * cos(rot) + v->y * -sin(rot); 
    v->y = v->x * sin(rot) + v->y * cos(rot); 
    return (v); 
} 

t_ray   *rotate_eye(t_ray *ray, t_vect *rot, int stage) 
{ 
    ray->og = x(ray->og, rot->z, stage); 
    ray->og = y(ray->og, rot->y, stage); 
    ray->og = z(ray->og, rot->x, stage); 
    ray->dir = x(ray->dir, rot->z, stage); 
    ray->dir = y(ray->dir, rot->y, stage); 
    ray->dir = z(ray->dir, rot->x, stage); 
    return (ray); 
} 

Le fichier ombre/couleur:

static double shadows(t_env *e, t_inter *inter) 
{ 
    t_ray  *iray; 
    t_vect  *v; 
    t_vect  *l; 

    l = e->scene.spot->pos; 
    v = new_vector(l->x - inter->point->x, l->y - inter->point->y, 
     l->z - inter->point->z); 
    iray = new_ray(inter->point, l); 
    return (calc_inter(e, iray)->dist); 
} 

t_color   *find_color_at(t_env *e, t_ray *ray) 
{ 
    t_color  *result; 
    t_inter  *mininter; 
    t_vect  *dist_l; 
    double  shade; 

    mininter = calc_inter(e, ray); 
    if (mininter->dist > ACCURACY) 
    { 
     dist_l = normalize(vect_add(e->scene.spot->pos, negative(ray->og))); 
     shade = dot_product(dist_l, mininter->normal); 
     if (shadows(e, mininter) > ACCURACY) 
      result = color_scalar(AMBIENTLIGHT * shadows(e, mininter), 
       mininter->color); 
     else 
      result = shade < 0 ? color_scalar(AMBIENTLIGHT + DIFFUSELIGHT * 
       0, mininter->color) : color_scalar(AMBIENTLIGHT + 
       DIFFUSELIGHT * shade, mininter->color); 
    } 
    else 
     result = new_color(0, 0, 0); 
    return (result); 
} 

Quelques screeshots.

fichier Scène: 0 ° rotation

camera: 
pos: 
0, 0, 100 
dir: 
0, 0, 0 
---- 
spheres: 
new: 
pos: 
20, 0, 20 
radius: 
30 
color: 
42, 255, 255 
---- 
---- 
cylinders: 
new: 
pos: 
-20, 0, -30 
radius: 
20 
color: 
255, 42, 23 
rotate: 
0, 0, 0 
---- 
---- 
spot: 
pos: 
50, 0, 150 
---- 
END 

https://gyazo.com/6ab10dbfba27a889ac6397c30aa4adda

fichier de scène: 42 ° rotation

camera: 
pos: 
0, 0, 100 
dir: 
0, 0, 0 
---- 
spheres: 
new: 
pos: 
20, 0, 20 
radius: 
30 
color: 
42, 255, 255 
---- 
---- 
cylinders: 
new: 
pos: 
-20, 0, -30 
radius: 
20 
color: 
255, 42, 23 
rotate: 
42, 0, 0 
---- 
---- 
spot: 
pos: 
50, 0, 150 
---- 
END 

https://gyazo.com/f244f6c7e2d2a81b6001fc175c16c289

fichier de scène: 91 ° rotation

camera: 
pos: 
0, 0, 100 
dir: 
0, 0, 0 
---- 
spheres: 
new: 
pos: 
20, 0, 20 
radius: 
30 
color: 
42, 255, 255 
---- 
---- 
cylinders: 
new: 
pos: 
-20, 0, -30 
radius: 
20 
color: 
255, 42, 23 
rotate: 
91, 0, 0 
---- 
---- 
spot: 
pos: 
50, 0, 150 
---- 
END 

https: //gyazo.com/86cda440cfca079d07e04d1ef19b8a21

Tout va aider, merci d'avance!

+0

Vos matrices de rotation semblent être non conventionnelles. Voir [ici] (https://en.wikipedia.org/wiki/Rotation_matrix) –

Répondre

1

Considérez votre rotation autour de l'axe x:

static t_vect *x(t_vect *v, double rot, int stage) 
{ 
    rot = DEG_TO_RAD(rot * stage); 
    v->y = v->y * cos(rot) + v->z * -sin(rot); 
    v->z = v->y * sin(rot) + v->z * cos(rot); 
    return (v); 
} 

Notez que la y coordonnée du vecteur d'entrée contribue à la fois aux y et z coordonnées du vecteur de résultat. Maintenant, notez que ce que vous utilisez réellement dans le calcul de la coordonnée z résultante n'est pas l'entrée et, mais plutôt le résultat calculé y. C'est erroné.

La même chose s'applique à vos autres fonctions de rotation.

+0

J'ai changé mon code et calculé avec les valeurs d'entrée. J'ai obtenu ce résultat: https://gyazo.com/ce3e4c35fefa3eb29d9804e4395ca2fb Il me semble qu'il y a une ombre au sommet du cylindre. Des indices? Merci. – Exilia

+0

Peu importe, j'avais juste besoin de tourner à nouveau pour calculer le point d'intersection. Je dois encore comprendre certaines choses au sujet de mon observation, mais vous en avez fait plus qu'assez. Merci encore ! – Exilia