c++中一个简单的光线追踪器的问题

Posted

技术标签:

【中文标题】c++中一个简单的光线追踪器的问题【英文标题】:Problems with a simple raytracer in c++ 【发布时间】:2015-04-15 10:53:38 【问题描述】:

它所做的基本上是检查与三角形数组的碰撞,并根据它击中的三角形的颜色绘制图像。我认为我的问题在于碰撞检测。代码在这里:

for (int i = 0; i < triangles.size(); i++)
    vec3 v0 = triangles[i].v0;
    vec3 v1 = triangles[i].v1;
    vec3 v2 = triangles[i].v2;
    vec3 e1 = v1 - v0;
    vec3 e2 = v2 - v0;
    vec3 b = start - v0;
    mat3 A(-dir, e1, e2);
    vec3 x = glm::inverse(A) * b;

    if (x.x > 0 && x.y > 0 && (x.x + x.y < 1) && (x.z - start.z>= 0))
        return true;
    

...其中“dir”是来自相机的光线方向,计算方式为“x - SCREEN_WIDTH / 2, y - SCREEN_HEIGHT / 2, focusLength”。 SCREEN_WIDTHSCREEN_HEIGHTfocalLength 是常量。 Start是相机的位置,设置为0,0,0。

我不确定 x 到底是什么以及在返回 true 之前我应该​​检查什么。 "x.x > 0 && x.y > 0 && (x.x + x.y " 应该检查光线是否不仅在同一平面上而且实际上在三角形内部,最后一部分 (" x.z - start.z>= 0",我最不确定的那个),如果碰撞发生在相机前面。

我得到图像,但无论我尝试多少,它都不会正确。它应该是一个具有不同颜色墙壁和两种形状的房间的经典 TestModel。我认为我最近的一次是把五堵墙中的四堵墙弄对了,最远的那堵不见了,另一边的一个形状的一部分。

【问题讨论】:

【参考方案1】:

我不熟悉三角形交集的矩阵公式 - 听起来很昂贵。

下面是我自己的代码,其中我的e1e2 与你的相同——即它们分别代表从v0v1v2 的边向量:

// NB: triangles are assumed to be in world space
vector3 pvec = vector3::cross(ray.direction(), e2);
double det = e1.dot(pvec);
if (::fabs(det) < math::epsilon) return 0;

double invDet = 1.0 / det;
vector3 tvec(p0, ray.origin());

double u = tvec.dot(pvec) * invDet;
if (u < 0 || u > 1) return 0;

vector3 qvec = vector3::cross(tvec, e1);
double v = ray.direction().dot(qvec) * invDet;
if (v < 0 || u + v > 1) return 0;

double t = e2.dot(qvec) * invDet;
if (t > math::epsilon)         // avoid self intersection
    // hit found at distance "t"

我怀疑问题出在您计算的光线矢量上,应该对其进行归一化。

【讨论】:

以上是关于c++中一个简单的光线追踪器的问题的主要内容,如果未能解决你的问题,请参考以下文章

实现光线追踪

提高光线追踪器的性能

3D渲染-光线追踪-包围盒

光线追踪、光线投射、光线行进和路径追踪有啥区别?

两块C++代码结合ASCII码,即可实现NVIDIA光线追踪技术!

光线追踪出了问题