光线追踪旋转
Raytracing Rotations
我目前正在用 C 语言编写一个简单的光线追踪器。一切正常,除了旋转。我正在尝试旋转我的物体(在那个问题上是圆柱体)。圆柱体旋转,但阴影完全消失,对象仅在 0° 和 90° 之间旋转,并在 360° 时恢复正常(很明显)。如果有人可以提示我做错了什么,我将不胜感激。这是一些示例代码。
查找圆柱相交的函数:
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));
我的 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);
}
shadow/color 文件:
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);
}
一些截图。
场景文件:0°旋转
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
场景文件:42°旋转
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
场景文件:91°旋转
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
任何事情都会有所帮助,在此先感谢!
考虑绕 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);
}
请注意,输入向量的 y 坐标对 y 和 z[=25= 都有贡献] 结果向量的坐标。现在请注意,您在计算结果 z 坐标时实际使用的不是输入 y,而是计算结果 y。这是错误的。
同样适用于您的其他旋转函数。
我目前正在用 C 语言编写一个简单的光线追踪器。一切正常,除了旋转。我正在尝试旋转我的物体(在那个问题上是圆柱体)。圆柱体旋转,但阴影完全消失,对象仅在 0° 和 90° 之间旋转,并在 360° 时恢复正常(很明显)。如果有人可以提示我做错了什么,我将不胜感激。这是一些示例代码。
查找圆柱相交的函数:
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));
我的 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);
}
shadow/color 文件:
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);
}
一些截图。
场景文件:0°旋转
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
场景文件:42°旋转
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
场景文件:91°旋转
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
任何事情都会有所帮助,在此先感谢!
考虑绕 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); }
请注意,输入向量的 y 坐标对 y 和 z[=25= 都有贡献] 结果向量的坐标。现在请注意,您在计算结果 z 坐标时实际使用的不是输入 y,而是计算结果 y。这是错误的。
同样适用于您的其他旋转函数。