Graphics 光线三角形交点的路径跟踪

Graphics 光线三角形交点的路径跟踪,graphics,geometry,raytracing,Graphics,Geometry,Raytracing,我目前正在写一个pathtracer。现在我想实现光线-三角形相交。所以我的三角形由三个点组成(v0,v1,v2)。我看了其他关于这个主题的帖子()。不幸的是,它不能正常工作,所以我想检查问题是否在交叉口一侧。以下是我的两个三角形函数: public float intersect(Ray ray){ Vector3D e1 = v1.sub(v0); Vector3D e2 = v2.sub(v0); Vector3D e1e2 = e1.cross(e2).norma

我目前正在写一个pathtracer。现在我想实现光线-三角形相交。所以我的三角形由三个点组成(v0,v1,v2)。我看了其他关于这个主题的帖子()。不幸的是,它不能正常工作,所以我想检查问题是否在交叉口一侧。以下是我的两个三角形函数:

public float intersect(Ray ray){
    Vector3D e1 = v1.sub(v0);
    Vector3D e2 = v2.sub(v0);
    Vector3D e1e2 = e1.cross(e2).normalize();

    Vector3D p = ray.direction.cross(e2);

    float a = e1.dot(p);
    if(a < 0.0)
        return -1.0f;

    float f = 1.0f / a;
    Vector3D s = ray.origin.sub(v0);
    float u = f*(s.dot(p));
    if(u < 0.0 || u > 1.0)
        return -1.0f; //no hit

    Vector3D q = s.cross(e1);
    float v = f * (ray.direction.dot(q));
    if(v < 0.0 || v > 1.0)
        return -1.0f; //no hit

    float t = f * (e2.dot(q)); //distance
    return t;
}

public Vector3D normal(Vector3D nVec){
    Vector3D e1 = v1.sub(v0);
    Vector3D e2 = v2.sub(v0);
    Vector3D e1e2 = e1.cross(e2).normalize();
    return e1e2;
}
public float intersect(光线){
Vector3D e1=v1.sub(v0);
Vector3D e2=v2.sub(v0);
Vector3D e1e2=e1.cross(e2).normalize();
Vector3D p=射线方向交叉(e2);
浮点数a=e1.点(p);
如果(a<0.0)
返回-1.0f;
浮球f=1.0f/a;
Vector3D s=ray.origin.sub(v0);
浮点数u=f*(s.dot(p));
如果(u<0.0 | | u>1.0)
返回-1.0f;//未命中
矢量3d q=s.交叉(e1);
浮点v=f*(光线方向点(q));
如果(v<0.0 | | v>1.0)
返回-1.0f;//未命中
浮点t=f*(e2.点(q));//距离
返回t;
}
公共矢量3D法线(矢量3D nVec){
Vector3D e1=v1.sub(v0);
Vector3D e2=v2.sub(v0);
Vector3D e1e2=e1.cross(e2).normalize();
返回e1e2;
}

那么这段代码正确吗?

老实说,我发现您的代码很难阅读,因为您没有使用非常描述性的名称。 我将向您介绍我在伪代码中所做的工作:

//1.Find intersection point of the ray and the infinite Plane created by triangle,
//or find if the ray is parralel to the plane (no intersection Point)
//2.Find out if the intersection point is within the triangle itself

Triangle: Vector A, Vector B, Vector C
ray: Vector rayOrig, Vector rayDir
Intersection: boolean hasHit = false, Vector hitPoint, float t

Vector normal = (B-A)CrossProduct(C-A) //I think you had basically the same with e1e2
float d = (normal)DotProduct(A)
float nd = (normal)DotProduct(rayDir)
if(nd!=0)
{    //The ray hits the triangles plane
    Intersection.t=(d- (normal).DotProduct(rayOrig))/nd
    Intersection.hitPoint=rayOrig+(rayDir*Intersection.t)
    if (pointInTriangle(Intersection.hitPoint, A, B, C))
    {
         Intersection.hasHit = true
    }
}
return Intersection
请注意,在获得与平面的交点后,将调用三角形中的函数点,该函数点应返回布尔值。我的方法来自:使用第二重心坐标,看起来你们在这部分做了类似的事情

if(u < 0.0 || u > 1.0)
    return -1.0f; //no hit

Vector3D q = s.cross(e1);
float v = f * (ray.direction.dot(q));
if(v < 0.0 || v > 1.0)
    return -1.0f; //no hit
if(u<0.0 | | u>1.0)
返回-1.0f//没有击中
矢量3d q=s.交叉(e1);
浮点v=f*(光线方向点(q));
如果(v<0.0 | | v>1.0)
返回-1.0f//没有击中

看起来你根本不是在检查射线平面的交点,你是用不同的函数来做的吗?如果是这样的话,我认为三角形测试实际上不需要光线方向。

您实现的是著名的求交算法。代码是正确的。如果您的代码没有检测到这种情况,可能是因为它检查了背面消隐。您可以通过将第一个if测试更改为
if(a==0.0f)
来删除该测试

另外,在第四行,
Vector3D e1e2=e1.cross(e2.normalize(),您正在计算三角形平面的法向量,这是不必要的