任何一个光线 r ray 在t时刻的位置为他起始位置 o origin加上时间乘以他的方向 d direction
光线在球上可以解出来
第一步
for (int j = 0; j < scene.height; ++j)
{
for (int i = 0; i < scene.width; ++i)
{
// generate primary ray direction
//刚开始给了我们一个屏幕大小为1280*960的空间,眼睛位置在屏幕的正中间
//我们将屏幕空间归一化,左下角定义为-1,-1 右上角为1,1
float x = (2*((float)i+0.5)/scene.width-1) * imageAspectRatio * scale;
float y = (1.0-2*((float)j+0.5)/scene.height) * scale;
// TODO: Find the x and y positions of the current pixel to get the direction
// vector that passes through it.
// Also, don't forget to multiply both of them with the variable *scale*, and
// x (horizontal) variable with the *imageAspectRatio*
Vector3f dir = Vector3f(x, y, -1); // Don't forget to normalize this direction!
dir = normalize(dir);
framebuffer[m++] = castRay(eye_pos, dir, scene, 0);
}
UpdateProgress(j / (float)scene.height);
}
第二步
MT算法:用重心坐标可以表示平面内任意一个点
bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig,
const Vector3f& dir, float& tnear, float& u, float& v)
{
// TODO: Implement this function that tests whether the triangle
// that's specified bt v0, v1 and v2 intersects with the ray (whose
// origin is *orig* and direction is *dir*)
// Also don't forget to update tnear, u and v.
Vector3f e1 = v1 - v0;
Vector3f e2 = v2 - v0;
Vector3f s0 = orig - v0;
Vector3f s1 = crossProduct(dir, e2);
Vector3f s2 = crossProduct(s0, e1);
Vector3f s = Vector3f(dotProduct(s2, e2), dotProduct(s1, s0), dotProduct(s2, dir)) / dotProduct(s1, e1);
//tnear, u, v对应t b1 b2
tnear = s.x;
u = s.y;
v = s.z;
//保证参数有意义
if (tnear >=0 && u >= 0 && v >=0 && 1-u-v>=0)
{
return true;
}
return false;
}
运行结果 输出文件