gpt4 book ai didi

java - Raytracer,计算观察光线(Java)

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:11:30 26 4
gpt4 key购买 nike

为了学校,我最近开始创建自己的光线追踪器。但是,我在计算观察光线或检查三角形与光线之间的交点时遇到了障碍。据我所知,计算似乎是正确执行的,因为我将我的相机放在原点并让它面向 -z 轴朝向它正前方的一个物体,允许手动进行简单的 vector 数学运算。一切似乎都已检查完毕,但屏幕上没有绘制任何内容。

我将发布我正在使用的计算观察光线的代码。

public Ray generateRay(float nX, float nY , Point2f coordinates)
{
// Compute l, r, b and t.
Vector3f temp = VectorHelper.multiply(u, nX/2.0f);
float r = temp.x + Position.x;
temp = VectorHelper.multiply(u, -nX/2.0f);
float l = temp.x + Position.x;
temp = VectorHelper.multiply(v, nY/2.0f);
float t = temp.y + Position.y;
temp = VectorHelper.multiply(v, -nY/2.0f);
float b = temp.y + Position.y;

// Compute the u and v coordinates.
float uCo = (l + (r - l) * (coordinates.x + 0.5f)/nX);
float vCo = (b + (t - b) * (coordinates.y + 0.5f)/nY);

// Compute the ray's direction.
Vector3f rayDirection = VectorHelper.multiply(w, -FocalLength);
temp = VectorHelper.add(VectorHelper.multiply(u, uCo), VectorHelper.multiply(v, vCo));
rayDirection = VectorHelper.add(rayDirection, temp);
rayDirection = VectorHelper.add(rayDirection, Position);
rayDirection = VectorHelper.normalize(VectorHelper.add(rayDirection, temp));

// Create and return the ray.
return new Ray(Position, rayDirection);
}

下面的代码是我用来计算交集的。它使用 Cramer 规则求解矩阵方程。

public static Point3f rayTriangleIntersection(
Ray ray, Point3f vertexA, Point3f vertexB, Point3f vertexC)
{
// Solve the linear system formed by the ray and the parametric surface
// formed by the points of the triangle.
// | a d g | | B | | j |
// | b e h | * | Y | = | k |
// | c f i | * | t | = | l |
// The following uses Cramer's rule to that effect.
float a = vertexA.x - vertexB.x; float d = vertexA.x - vertexC.x; float g = ray.getDirection().x;
float b = vertexA.y - vertexB.y; float e = vertexA.y - vertexC.y; float h = ray.getDirection().y;
float c = vertexA.z - vertexB.z; float f = vertexA.z - vertexC.z; float i = ray.getDirection().z;

float j = vertexA.x - ray.getOrigin().x;
float k = vertexA.y - ray.getOrigin().y;
float l = vertexA.z - ray.getOrigin().z;

// Compute some subterms in advance.
float eihf = (e * i) - (h * f);
float gfdi = (g * f) - (d * i);
float dheg = (d * h) - (e * g);
float akjb = (a * k) - (j * b);
float jcal = (j * c) - (a * l);
float blkc = (b * l) - (k * c);
// Compute common division number.
float m = (a * eihf) + (b * gfdi) + (c * dheg);

// Compute unknown t and check whether the point is within the given
// depth interval.
float t = -((f * akjb) + (e * jcal) + (d * blkc)) / m;
if (t < 0)
return null;

// Compute unknown gamma and check whether the point intersects the
// triangle.
float gamma = ((i * akjb) + (h * jcal) + (g * blkc)) / m;
if (gamma < 0 || gamma > 1)
return null;

// Compute unknown beta and check whether the point intersects the
// triangle.
float beta = ((j * eihf) + (k * gfdi) + (l * dheg)) / m;
if (beta < 0 || beta > (1 - gamma))
return null;

// Else, compute the intersection point and return it.
Point3f result = new Point3f();
result.x = ray.getOrigin().x + t * ray.getDirection().x;
result.y = ray.getOrigin().y + t * ray.getDirection().y;
result.z = ray.getOrigin().z + t * ray.getDirection().z;
return result;
}

我的问题很简单。我究竟做错了什么?我已经查看并调试了这段代码,但无法找出错误,谷歌提供的只是我正在使用的书中已有的理论。此外,代码仍然相当粗糙,因为我只是专注于在清理它之前让它工作。

提前致谢

凯文

最佳答案

很难准确说出哪里出了问题。特别是因为您没有使用描述性变量名称(nX、nY 等是什么??)

这里有一些提示:

  • 首先确保它不是显示代码中的错误。伪造一个十字路口以证明当你撞到某物时你会得到可见的输出,例如使屏幕右下角的所有光线都击中轴对齐的平面或类似的东西,以便您可以轻松验证坐标
  • 首先尝试光线/球体相交。它比射线/三角形相交更容易。
  • 考虑使用 vector/矩阵运算,而不是手动计算所有组件。很多行乱七八糟的字母很容易出错。
  • 如果您遇到比例问题(例如对象太小),请仔细检查您在世界坐标和屏幕坐标之间的转换。世界坐标将在小双数范围内(例如 0.2 ....5.0),而屏幕坐标应该是根据您的 View 大小(例如 0 .. 1024)的像素位置。您应该在世界坐标中进行大部分数学运算,仅在渲染代码的开头和结尾处与屏幕坐标进行转换。
  • 在调试器中逐步执行顶级光线跟踪代码,并确保为每个屏幕坐标(尤其是屏幕的角落)在合理的方向上产生光线
  • 检查您的相机方向是否指向目标对象。让它朝完全相反的方向看是一个很容易犯的错误!

应该工作的示例设置:

  • 相机位置 [0 0 4]
  • 对象位置 [0 0 0]
  • Camera DIRECTION [0 0 -1](如果你想让它朝原点看,请注意减号!)
  • 向上 vector [0 0.75 0]
  • 右 vector [+/-1 0 0]

然后你的光线方向应该是这样的(对于一个像素 [screenX, screenY]):

ray = DIRECTION + (2*(screenX / screenWidth)-1)*RIGHT + (1-2*(screenY/screenHeight))*UP

ray = normalize(ray)

关于java - Raytracer,计算观察光线(Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13091871/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com