algorithm - 计算光子追踪中的像素值

标签 algorithm 3d raytracing

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

在正常的光线追踪中,我从视点通过图像平面中的一个像素将光线射入场景中,在光线树的这个分支被追踪之后,我最终得到一个分配给该像素的颜色值。我想不出一种方法来扭转这个过程。如果我测试每条光线是否只与图像平面相交,那么我会得到一个 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/

相关文章:

javascript - 图的深度优先遍历 - javascript

python - 创建数组的算法或代码,规则是否符合规定?

algorithm - 如果 Queue 是使用数组实现的,那么最坏情况下的时间复杂度是多少?如何实现?

c# - WPF异常在另一个类中运行动画

math - 光线追踪计算

algorithm - 最小生成树时间复杂度

algorithm - 使用四点相交的线段

graphics - 在 Vulkan 中,您如何将每个单独的视频卡与它们直接连接的显示器相关联

java - 光线追踪三角形

julia - 我使用 julia 编程语言编写了一个路径跟踪器,但我认为它很慢