光线追踪三角形 [英] Ray-tracing triangles

查看:276
本文介绍了光线追踪三角形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Java编写raytracer,并且能够跟踪工作的球体,但是我认为跟踪三角形的方式有问题。

I am writing a raytracer in java, and I was able to get tracing of spheres working, but I believe I have something wrong with how I am tracing triangles.

据我所知,这是基本算法:

Here is the basic algorithm, as I understand it:


  1. 首先确定射线是否与平面相交

  2. 修剪所有点,使它们与三角形在同一平面上(因此,在 xy 平面上,例如)。

  3. 根据在沿任意方向发射光线时所穿过的多边形边的数量,确定潜在的相交点是落在三角形的内部还是外面。新飞机。

  1. First determine if the ray even intersects the plane that the triangle is on.
  2. Clip all points so they are on the same plane as the triangle (so to the xy plane, as an example).
  3. Determine if the potential intersection point falls inside or out of the triangle, based on the number of polygon edges you cross when sending out a ray in an arbitrary direction along the new plane.

现在,这是我的实现(特别是第一点):

Now, here is my implementation of that (specifically the first point):

public Vector getIntersectionVector(Ray ray)
{
    Vector planeIntersectionVector = getPlaneIntersectionVector(ray, getPlaneNormal());
    if (planeIntersectionVector != null)
    {
        if (isIntersectionVectorInsideTriangle(planeIntersectionVector))
        {
            return planeIntersectionVector;
        }
        else
        {
            return null;
        }
    }
    else
    {
        return null;
    }
}

其中 getPlaceIntersectionVector()是:

private Vector getPlaneIntersectionVector(Ray ray, Vector planeNormal)
{
    double vd = planeNormal.dotProduct(ray.getDirection());
    //(p_n \dot r_d) == 0, parallel. (p_n \dot r_d) > 0 Plane normal pointing away from ray.
    if (vd >= 0)
    {
        return null;
    }
    double distance = planeNormal.distance(0d, 0d, 0d);
    double vo = -(planeNormal.dotProduct(ray.getOrigin()) + distance);
    double intersectionDistance = vo / vd;

    //intersectionDistance <= 0 means the "intersection" is behind the ray, so not a real intersection
    return (intersectionDistance <= 0) ? null : ray.getLocation(intersectionDistance);
} 

基本上试图模仿以下内容:

Which basically tries to mimic this:

这是:

And this:

其中 t 是沿点命中的沿射线的距离,r o 是射线的原点, r d 是射线的方向,p n 是三角形/平面的平面法线, d 是从三角形所在的平面到原点的距离(0,0,0)

Where t is the distance along the ray that the point hits, ro is the origin of the ray, rd is the direction of the ray, pn refers to the plane normal of the triangle/plane, and d is the distance from the plane that the triangle is on to the origin (0,0,0)

我做错了吗?当我从图像(0,0)的第一个像素发出光线时,我发现 intersectionDistance (或 t )几乎是 1100 ,这在我看来直觉是错误的。我认为交叉点会更近。

Am I doing that wrong? When I send out the ray from the first pixel in the image (0,0), I am seeing that the intersectionDistance (or t) is almost 1100, which intuitively seems wrong to me. I would think that the intersection point would be much closer.

以下是相关数据:
射线源(0,0,1),射线方向大致为(0.000917,-0.4689,-0.8833)

三角形的顶点为(-0.2,0.1,0.1) (-0.2,-0.5、0.2)(-0.2、0.1,-0.3),这使平面变为正常(-1,0,0)

根据我的代码,Ray与平面<$相交c $ c> 1090 的距离,就像我之前提到的,对我来说似乎是错误的。场景在每个方向上都只有-1.0到1.0,这意味着相交处的距离非常远。

我在做平面相交时错了吗?

Here is the relevant data: Ray origin (0,0,1), Ray Direction is roughly (0.000917, -0.4689, -0.8833).
Triangle has vertices as (-0.2, 0.1, 0.1), (-0.2, -0.5, 0.2), (-0.2, 0.1, -0.3), which makes the plane normal (-1, 0, 0).
According to my code, the Ray intersects the plane 1090 distance away, which as I mentioned before, seems wrong to me. The scene is only -1.0 to 1.0 in every direction, which means the intersection is very very far in the distance.
Am I doing the plane intersection wrong?

请让我知道在哪里澄清点,以及是否需要更多信息。

Please let me know where to clarify points, and if you need any more information.

推荐答案

问题是这个行:

double distance = planeNormal.distance(0d, 0d, 0d);

平面由法线和从平面到原点的距离定义。向量到原点的距离是向量的长度,因此您要计算的只是平面法线的长度(如果已经归一化,它将始终为1.0)。

A plane is defined by a normal and a distance from the plane to the origin. The distance of a vector from the origin is the length of a vector, so what you are calculating there is just the length of the plane normal (which will always be 1.0 if it has been normalized).

平面到原点的距离是一条额外的信息,需要传递给函数,您不能仅仅根据法线来计算它,因为它是独立于它的(您可以许多飞机的法线指向同一方向,距原点的距离不同。

The distance of the plane from the origin is an extra piece of information that needs to be passed into your function, you can't just calculate it from the normal because it's independent of it (you can can have lots of planes with normals pointing in the same direction at different distances from the origin).

因此,请定义您的函数,如下所示:

So define your function something like this:

private Vector getPlaneIntersectionVector(Ray ray, Vector planeNormal, double planeDistance)

并这样称呼它:

Vector planeIntersectionVector = getPlaneIntersectionVector(ray, getPlaneNormal(), getPlaneDistance());

然后您可以像这样计算 vo

Then you can calculate vo like this:

double vo = -(planeNormal.dotProduct(ray.getOrigin()) + planeDistance);

这篇关于光线追踪三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆