ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Ray Tracing - Intersection

2021-05-11 08:32:49  阅读:337  来源: 互联网

标签:ray auto Tracing vec 曲面 交点 Intersection Ray


在光线追踪算法中, 光线与各类几何体求交, 是渲染着色的基础. 几何体根据表示方式不同可以分为两个大类:

  • 隐式曲面, Implicit Surface. (隐含几何体的点信息)
  • 显式曲面, Explicit Surface. (直接包含几何体的点线面信息)

几何体的隐式曲面和显式曲面表示形式, 区别有点类似于图形与图像的区别.

  • 图形: 具有数学表达的几何对象 (点线面); 例如, 矢量图.
  • 图像: 离散表达, 像素, 光栅化; 例如, 栅格图.

关于隐式曲面和显示曲面的详细介绍可以参考 [1]

Ray Equation

Ray, 光线, 定义为射线, 从一个点出发, 沿着某一方向前行.

image-20210421192612936

在 Ray 传播路径上的点 \(P(x_p,y_p,z_p)\), 都可以表示为以下形式:

\[(x_p, y_p, z_p) = (o_x+td_x, o_y+td_y, o_z+td_z) = \vec{o} + t\vec{d} \]

\(t\) 的直观含义: 从光源出发, 沿着光线传播方向传播的距离/时间.

Implicit Surface

隐式曲面不会告诉任何点的信息, 只会告诉该曲面上所有点满足的关系.

三维空间中的隐式曲面可以统一表示为以下形式:

\[f(x,y,z) = 0 \]

Ray 与曲面相交, 交点即在Ray上, 又在几何体上. 即:

\[f(x,y,z) = f(o_x+td_x, o_y+td_y, o_z+td_z) = 0 \]

只有一个变量 \(t\), 因此对于各种隐式曲面表达式, 结合各种数值方法 [2], 总能找到一个合适的解.

Sphere

交点计算结果

image-20210508183511569

具体推导过程

对于简单几何体, 例如球, 我们可以推导交点与法线的坐标表示.

image-20210508182241743

球的隐式曲面表示: 假设圆心为 \(\vec{c} = (c_x, c_y, c_z)\)

\[(x-c_x)^2 + (y-c_y)^2 + (z-c_z)^2 = R^2 \]

交点 \(P(x_p,y_p,z_p)\) 即在 Ray 上, 又在 Sphere 上, 满足:

\[\begin{cases} (x_p, y_p, z_p) = (o_x+td_x, o_y+td_y, o_z+td_z) \\ (x_p-c_x)^2 + (y_p-c_y)^2 + (z_p-c_z)^2 = R^2 \\ \end{cases} \]

此时未知量仅有 \(t\), 即:

\[At^2 + Bt + C = 0 \\ \]

\(A, B, C\) 的向量形式表示如下:

\[\begin{cases} A = \vec{d} \cdot \vec{d} \\ B = 2(\vec{o} - \vec{c}) \cdot \vec{d} \\ C = (\vec{o}-\vec{c}) \cdot (\vec{o}-\vec{c}) - R^2 \end{cases} \]

对于 \(t\) 为未知量的二元一次方程, 存在闭式解:

\[t=\frac{-B \pm \sqrt{B^{2}-4 A C}}{2 A} \]

根据 \(t\) 的含义可知, \(t\) 的最小正数解对应于光线与物体最近的点 \(P\), 正数解的个数对应于球与光线的交点个数.

  • 交点 \(P = \vec{o} + t\vec{d}\);
  • 法线 \(\vec{n} = \vec{CP}\), (圆心与交点的连线)

代码实现

auto x = ray.o - center;
double a = dot(ray.d, ray.d);
double b = 2 * dot(x, ray.d);
double c = dot(x, x) - radius * radius;

double t0, t1;
if (!Quadratic(a, b, c, &t0, &t1)) return false;
if (t0 > ray.tmax || t1 < 0.0) return false;

auto t = t0 < 0.0? t1: t0;
auto p_hit = ray.at(t);
auto p_norm = (p_hit - center).normalized();

Explicit Surface

Triangle Mesh, 三角网格, 由多个三角形组成, 是一类重要的隐式曲面. 三维物体常常组织为 Mesh 形式. 光线与三角形求交是光线与 Mesh 求交的基础.

Triangle Mesh

  • 在不使用加速结构的情况下, 可以测试 Ray 与 Mesh 中的每一个三角形检测是否相交, 所有交点中最近的交点位置, 即是 Ray 与 Mesh 的交点.
  • 当 Mesh 表示的物体有"内外"之分时: 奇数交点表示光源在 Mesh 内部; 偶数交点表示光源在物体外部. (不考虑相切)

image-20210421185053931

  • 简单实现: 遍历每个三角形, 获取 Ray 与 Mesh 的交点.
bool TriMesh::intersect(const Ray &ray, double &t_hit, Interaction &isect) const {
    bool hit = false;
    for (auto triangle : triangles) {
        if (triangle.get()->intersect(ray, t_hit, isect)) {
            ray.tmax = t_hit;
            hit = true;
        }
    }
    return hit;
}

Triangle

有多种方法可以计算射线与三角形的交点, 比如高效的 Möller–Trumbore 算法[3]. 这里我们使用最直观的一种方式, 将射线与三角形求交分解为一下两个过程:

  • 计算射线与三角形所在平面的交点
  • 判断交点是否在三角形内部

交点计算结果

计算射线与三角形所在平面的交点计算;

image-20210508191300612

判断交点是否在三角形内部 (叉乘判断) [4]

image-20210508190951599

  • 除了使用叉乘同向法, 还有内角和法[5], 面积法[6]等方法, 来计算判断一个点是否在三角形内部.
    • 面积法: 当点在三角形内部时, 有 \(S_{\triangle{ABC}} = S_{\triangle{OAB}}+S_{\triangle{OBC}}+S_{\triangle{OCA}}\).

image-20210508184551891

代码实现

// 1. Ray 与 三角形所在的平面相交, 得到交点 p
double t = dot((a - ray.o), n) / dot(ray.d, n);
if (t < 0 || t > ray.tmax) return false;
// 2. 判断交点 p 是否在三角形内部
auto p = ray.at(t);
auto ap = p - a;
auto bp = p - b;
auto cp = p - c;
auto t0 = cross(ab, ap);
auto t1 = cross(bc, bp);
auto t2 = cross(ca, cp);
auto ret_0 = dot(t0, t1);
auto ret_1 = dot(t1, t2);
auto ret_2 = dot(t2, t0);
// 3. 使用点乘判断叉乘结果是否同向
if (ret_0 < 0 || ret_1 < 0 || ret_2 < 0) return false;

References


  1. 计算机图形学九:隐式曲面(代数形式,CSG, 距离函数,分型几何)与显式曲面 ↩︎

  2. 数值计算非线性方程求根 ↩︎

  3. Möller–Trumbore intersection algorithm ↩︎

  4. Cross product ↩︎

  5. 判断点是否在三角形内 ↩︎

  6. 如何判断一个点是否在三角形内? ↩︎

标签:ray,auto,Tracing,vec,曲面,交点,Intersection,Ray
来源: https://www.cnblogs.com/crayonsea/p/14687052.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有