我过去写过两个传统的光线追踪器,但现在我想编写一个反向光线追踪器,它可以追踪从光源到视点的光子。在过去几天阅读了有关该主题的文章后,我知道我不应该尝试,但无论如何我还是想这样做。我现在面临的问题是如何计算我要生成的图像中每个像素的值。
在正常的光线追踪中,我从视点通过图像平面中的一个像素将光线射入场景中,在光线树的这个分支被追踪之后,我最终得到一个分配给该像素的颜色值。我想不出一种方法来扭转这个过程。如果我测试每条光线是否只与图像平面相交,那么我会得到一个 180 度的视野和一个正好在图像平面上的焦点(一团模糊)。所以我必须测试每条光线是否与图像平面和眼点相交。但由于眼点只是一个无穷小的小点,光线射中它的机会应该(几乎)为零,这将导致根本没有图像。
所以我的问题是:如何通过追踪来自光源的光子来计算要渲染的图像的像素值?
提前致谢,
简
最佳答案
您需要进行“最终聚集”才能生成图像。如果您的光线树从光源中分支出来,这将有效地用额外的光线“装饰”光线树的叶子。
当然,并不是每一条这样的光线都是有效的:如果表面背对眼睛,或者如果它被遮挡,那么它应该被拒绝。请注意,这种生成光线的方法类似于在常规光线追踪中确定照明所需的“阴影”光线。
另一个问题是您接收到的光线将呈随机模式,而不是传统光线追踪提供的规则或均匀分布的模式。这意味着您需要对相机接收到的光线进行平均和/或插值,以获得像素值。
我相信您的像素颜色将由样本密度和样本的颜色值的组合决定;如果是这样,您将需要确保您的平均/插值方法提供该行为。对此的初始近似可能只是将传入样本添加到最近的像素;更好的方法可能是为每个传入样本“涂抹”一个简单的附加贴花。一种更复杂的方法可以根据样本的局部密度按比例缩放贴花的大小,同时保持总积分亮度与样本亮度成比例。
编辑:给定传入的“眼睛”光线,您仍然需要确定传入光线对应的屏幕位置。为此,您需要计算用于光栅化的相机的“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 */ }
关于algorithm - 计算光子追踪中的像素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12881506/