光线追踪 - 光线与平行四边形
Raytracing - Ray vs. Parallelogram
我正在为学校开发一个简单的光线追踪器,我正在尝试实现一个 ray-parallelogram 交集。我的平行四边形以参数形式定义 (p = origin + u * A + v * B)。第一步类似于 ray-plane 交点,我从中得到可能的交点 P。但是如何检查该点是否在平行四边形内?我查看了 Whosebug 并发现了这个 3D Ray-Quad intersection test in java 但是尽管标题表明接受的答案似乎只适用于矩形?我没有通过一些秘密测试(意思是我不知道为什么我没有通过测试,我只知道我没有通过 x))。也许我错过了一些边缘案例?
这是我的代码
const auto normal = cross(a_, b_);
const auto num = dot(origin_ - ray.o, normal);
const auto denom = dot(ray.d, normal);
if (-epsilon < denom && denom < epsilon)
{
return false;
}
const auto t = num / denom;
const auto p = (ray.o + t * ray.d) - origin_;
const auto u = dot(p, a_);
const auto v = dot(p, b_);
return -epsilon < t && t < previous && 0.f < u && u <= a_.length_squared() && 0.f < v && v <= b_.length_squared();
您可以进行两次射线-三角形相交测试,但由于某些计算需要进行两次,因此成本会更高。
您可以使用三个向量 a_
、b_
和 ray.d
作为平行四边形局部 space 的基础来测试射线-平行四边形相交。使用 ray.d
作为 "normal" 组件的好处是,当您在此基础上表达 ray.o
时,交集测试简化为检查局部 x 和 y 坐标是否在 0 和 1 之间, z 坐标编码距离。
整个过程是:
- 使用列
a_
、b_
和 ray.d
构建矩阵 B
- 反转它:
B_inv = inverse(B)
- 在本地space计算
ray.o
:ol = B_inv * (ray.o - origin_)
- 距离
t
是-ol.z
- 交集测试:
if (t >= 0 && t < previous && ol.x >= 0 && ol.x <= 1 && ol.y >= 0 && ol.y <= 1)
我正在为学校开发一个简单的光线追踪器,我正在尝试实现一个 ray-parallelogram 交集。我的平行四边形以参数形式定义 (p = origin + u * A + v * B)。第一步类似于 ray-plane 交点,我从中得到可能的交点 P。但是如何检查该点是否在平行四边形内?我查看了 Whosebug 并发现了这个 3D Ray-Quad intersection test in java 但是尽管标题表明接受的答案似乎只适用于矩形?我没有通过一些秘密测试(意思是我不知道为什么我没有通过测试,我只知道我没有通过 x))。也许我错过了一些边缘案例?
这是我的代码
const auto normal = cross(a_, b_);
const auto num = dot(origin_ - ray.o, normal);
const auto denom = dot(ray.d, normal);
if (-epsilon < denom && denom < epsilon)
{
return false;
}
const auto t = num / denom;
const auto p = (ray.o + t * ray.d) - origin_;
const auto u = dot(p, a_);
const auto v = dot(p, b_);
return -epsilon < t && t < previous && 0.f < u && u <= a_.length_squared() && 0.f < v && v <= b_.length_squared();
您可以进行两次射线-三角形相交测试,但由于某些计算需要进行两次,因此成本会更高。
您可以使用三个向量 a_
、b_
和 ray.d
作为平行四边形局部 space 的基础来测试射线-平行四边形相交。使用 ray.d
作为 "normal" 组件的好处是,当您在此基础上表达 ray.o
时,交集测试简化为检查局部 x 和 y 坐标是否在 0 和 1 之间, z 坐标编码距离。
整个过程是:
- 使用列
a_
、b_
和ray.d
构建矩阵 - 反转它:
B_inv = inverse(B)
- 在本地space计算
ray.o
:ol = B_inv * (ray.o - origin_)
- 距离
t
是-ol.z
- 交集测试:
if (t >= 0 && t < previous && ol.x >= 0 && ol.x <= 1 && ol.y >= 0 && ol.y <= 1)
B