0

我过去写过两个传统的光线追踪器,但现在我想编写一个反向光线追踪器,它可以追踪从光源到眼点的光子。在过去几天阅读有关此主题的文章后,我知道我不应该尝试,但无论如何我还是想这样做。我现在面临的问题是如何计算我试图生成的图像中每个像素的值。

在普通光线追踪中,我将来自视点的光线通过图像平面中的一个像素发射到场景中,在追踪光线树的这个分支之后,我最终得到一个分配给该像素的颜色值。我想不出办法来扭转这个过程。如果我测试每条光线是否只与图像平面相交,那么我会得到一个 180 度的视野和一个焦点就在图像平面上(一团模糊)。所以我必须测试每条光线是否与图像平面和眼点相交。但由于眼点只是一个无限小的小点,光线击中它的机会应该(几乎)为零,这将导致根本没有图像。

所以我的问题是:如何通过追踪来自光源的光子来计算要渲染的图像的像素值?

在此先感谢,

4

1 回答 1

1

您需要进行“最终收集”才能生成图像。如果您的光线树从光源分支出来,这将有效地“装饰”光线树的叶子,并为眼睛添加额外的光线。

当然,并不是每条这样的光线都是有效的:如果表面背对眼睛,或者它被遮挡,那么它应该被拒绝。请注意,这种生成光线的方法类似于在常规光线追踪中确定照明所需的“阴影”光线。

另一个问题是您接收到的光线将采用随机模式,而不是传统光线追踪提供的规则或分布良好的模式。这意味着您需要对相机接收到的光线进行平均和/或插值,以获得像素值。

我相信您的像素颜色将由样本密度样本颜色值的组合决定;如果是这样,您将需要确保您的平均/插值方法提供该行为。对此的初始近似可能只是将输入样本添加到最近的像素;更好的方法可能是为每个传入的样本“喷溅”一个简单的添加剂贴花。一种更复杂的方法可以根据样本的局部密度按比例缩放贴花的大小 - 同时保持总积分亮度与样本亮度成比例。


编辑:给定一个传入的“眼睛”光线,您仍然需要确定您的传入光线对应的屏幕位置。为此,您需要计算用于光栅化的相机的“ViewProjection”矩阵。这实际上是用于传统光线追踪的过程的逆过程:

conventional ray tracing:
    // find direction vector for given screen coordinates (x,y)
    homog4vector homog_clip_coords( (x - x_offset) / x_resolution,
                                    (y - y_offset) / y_resolution,
                                    1.0,  // z-coordinate
                                    1.0); // w-coordinate
    homog4vector homog_world_coords = InverseViewProjectionMatrix * homog_clip_coords
    ray_vector_x = homog_world_coords.x / homog_world_coords.w - eye_x;
    ray_vector_y = homog_world_coords.y / homog_world_coords.w - eye_y;
    ray_vector_z = homog_world_coords.z / homog_world_coords.w - eye_z;

rasterization or "reverse" ray tracing:
    // find screen coordinates for given source point "p"
    homog4vector eye_ray_source(p.x, p.y, p.z, 1.0);
    homog4vector homog_clip_coords = ViewProjectionMatrix * homog4vector(x,y,z,1);
    screen_coords.x = x_offset + x_resolution * homog_clip_coords.x / homog_clip_coords.w
    screen_coords.y = y_offset + y_resolution * homog_clip_coords.y / homog_c.ip_coords.w

当然,并不是每条入射光线都会出现在屏幕上。确保丢弃从后面进入相机的光线:

    if (homog_clip_coords.z < 0 || homog_clip_coords.w < 0)
      { /* reject ray */ }
于 2012-10-15T18:39:10.287 回答