我正在实现一个基本的光线跟踪器,所以我正在阅读理论和其他实现。这是我目前提到的代码
template<typename T>
void render(const std::vector<Sphere<T> *> &spheres)
{
int width = 800, height = 800;//define width and height of the screen
Vector3d<T> *image = new Vector3d<T>[width * height], *pixel = image;
T invWidth = 1 / T(width), invHeight = 1 / T(height);
T fov = 90, aspectratio = width / T(height);//defining field of view angle and aspect ratio
T fovDist = tan(M_PI * 0.5 * fov / T(180));//Calculates half screen width / perpendicular distance to the camer
a position
// For each ray crossing a pixel on the view screen.
for (int y = 0; y < height; ++y) //For each scan line
{
for (int x = 0; x < width; ++x, ++pixel) //for each pixel on a scan line
{
//Calculate the x position using centre of the pixel.
/*By simple trig (width/2)/perpendicular distance to camera = tan (fov/2)
=>width = distance * tan (fov/2)
*/
T xx = (2 * ((x + 0.5) * invWidth) - 1) * fovDist * aspectratio;
T yy = (1 - 2 * ((y + 0.5) * invHeight)) * fovDist;//Calculate the y position
Vector3d<T> raydir(xx, yy, -1);
raydir.normalize();
*pixel = trace(Vector3d<T>(0), raydir, spheres, 0);
}
}
我正在评论我的理解,但我仍然坚持计算xx和yy。
据我所知,通过简单的三角法宽度= 2 *(从相机到视平面的垂直距离)* tan(fov / 2)。但我无法找出T xx和T yy的表达式。
请有人帮忙澄清。
此致 莫伊拉
答案 0 :(得分:1)
好的,所以如果我理解了这一点,你的框架与XY平面平行,坐在Z = -1,你的相机/眼睛在原点。现在,您正在尝试查找每个像素中心的X和Y位置。是吗?
所以x + 0.5
会将你偏移到当前像素的中心,这很好。除以总像素数就可以得出整个画面的百分比:好。乘以2,然后减1,你在-1到1的范围内,分别对应于从中心到左边的100%,以及从中心到右边的100%(或者副) -versa)。现在乘以宽度的一半(fovDist),所以它会让你在左边的一半宽度和右边的一半宽度之间。这一切都很好。最后,你乘以纵横比,因为fovDist实际上是高度的一半,而不是necc。宽度的一半。因此,如果你的宽高比为2:1,它应该比它高,所以你想要将像素水平展开,所以你也都很好。
你的yy设置方式相同,除了反转,因为扫描线通常是另一种方式。所以看起来也很好。
它是否有效,你只是想了解它?或者它不能正常工作?如果它不能正常工作,你会看到什么样的行为呢?
如果它不能正常工作,那么唯一突然出现的就是所有不同的数字类型。例如,您的invWidth
和invHeight
变量都会将整数1除以某种值。我不记得C ++是如何处理这个问题的,但是你可能会通过整数除法将其截断为0。同样,你的xx和yy表达式中有很多整数。不确定编译器是否可以正常工作,但如果它不能正常工作,我会从那里开始。