GAMES101 HW5
这里回顾GAMES101 HW5,这次作业的内容是光线与三角形相交。
课程主页:
课程作业:
课程视频:
参考资料:
Render
首先要将屏幕上的像素点恢复成对应的物体坐标,而从物体坐标变成像素点即Lecture 4和Lecture5介绍的方法。
第一步,从物体坐标变成标准立方体:
第二步,从标准立方体投影到屏幕:
- 像素的索引采用$(x, y)$的形式,其中$x$和$y$都是整数;
- 像素的索引从$(0, 0)$到$(width - 1, height - 1)$;
- 像素$(x, y)$以$(x + 0.5, y + 0.5)$为中心;
- 屏幕覆盖范围$(0, 0)$到$(width, height)$;
对于将屏幕上的像素点恢复成对应的物体坐标,第一步为屏幕投影到标准矩形,对应代码为:
// [0, a) -> [-1, 1)
x = (i + 0.5 - scene.width / 2.0) / (scene.width / 2.0);
y = -(j + 0.5 - scene.height / 2.0) / (scene.height / 2.0);
注意$y$的符号是根据实际结果调整的。
第二步为从标准矩形恢复物体的坐标,假设相机距离屏幕的距离为$d$,即屏幕的$z$坐标为$-d$,根据公式:
以及下图:
可得屏幕的半宽度为:
半长度为:
即对应关系为:
因为最后只需要方向即可,所以这里取$d=1$(因为方向的原因,最后实际使用的值为$-1$),对应代码为:
// [-1, 1) -> [p, q)
x = x * scale * imageAspectRatio;
y = y * scale;
Vector3f dir = Vector3f(x, y, -1); // Don't forget to normalize this direction!
dir = normalize(dir);
rayTriangleIntersect
利用Möller Trumbore算法即可:
最后需要判断是否满足如下条件即可:
- $t< 0$;
- $0\le b_1 \le 1$;
- $0\le b_2 \le 1$;
- $0\le b_1 + b_2 \le 1$;
代码:
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.
// u, v重心坐标
Vector3f e1 = v1 - v0;
Vector3f e2 = v2 - v0;
Vector3f s = orig - v0;
Vector3f s1 = crossProduct(dir, e2);
Vector3f s2 = crossProduct(s, e1);
float a = dotProduct(s1, e1);
tnear = dotProduct(s2, e2) / a;
u = dotProduct(s1, s) / a;
v = dotProduct(s2, dir) / a;
float b = u + v;
return tnear > 0 && 0 <= u && u <= 1 && 0 <= v && v <= 1 && 0 <= b && b <= 1;
}
示例
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere