光线追踪器中的错误紫外线
Wrong uv in ray tracer
我的光线追踪程序有问题。图像看起来不对。这是输出图像:
重心坐标和碰撞计算代码如下:
bool CTriangle::Intersect(Calculus::CRay& ray, CIntersection* isect) const {
// Möller–Trumbore intersection algorithm
const Calculus::CPoint3<float>& p1 = v_points[0];
const Calculus::CPoint3<float>& p2 = v_points[1];
const Calculus::CPoint3<float>& p3 = v_points[2];
Calculus::CVector3<float> e1 = p2 - p1;
Calculus::CVector3<float> e2 = p3 - p1;
Calculus::CVector3<float> s1 = Calculus::Math::Cross(ray.direction, e2);
float determinant = Calculus::Math::Dot(s1, e1);
if (determinant == 0.0f)
return false;
float inv_determinant = 1.0f / determinant;
Calculus::CVector3<float> s = ray.origin - p1;
float b1 = Calculus::Math::Dot(s, s1) * inv_determinant;
if (b1 < 0.0f || b1 > 1.0f)
return false;
Calculus::CVector3<float> s2 = Calculus::Math::Cross(s, e1);
float b2 = Calculus::Math::Dot(ray.direction, s2) * inv_determinant;
if (b2 < 0.0f || b1 + b2 > 1.0f)
return false;
float b0 = 1 - b1 - b2;
float thit = Calculus::Math::Dot(e2, s2) * inv_determinant;
if (thit < ray.mint || thit > ray.maxt)
return false;
isect->p = ray(thit);
isect->n = Calculus::Math::Normalize(Calculus::CVector3<float>
(v_normals[0].x, v_normals[0].y, v_normals[0].z) * b0 +
Calculus::CVector3<float>(v_normals[1].x, v_normals[1].y,
v_normals[1].z) * b1 +
Calculus::CVector3<float>(v_normals[2].x, v_normals[2].y,
v_normals[2].z) * b2);
isect->uv = v_uvs[0] * b0 + v_uvs[1] * b1 + v_uvs[2] * b2;
isect->tHit = thit;
isect->ray_epsilon = 1e-5f * thit;
return true;
}
我在光线追踪程序中使用的纹理:(文件类型:bmp)
我的obj文件如下。背景形状由两个三角形组成。纹理投影仅应用于背景形状:
v -24.1456 -11.1684 -26.2413
v 24.1455 -11.1684 -26.2413
v -24.1456 37.1227 -26.2413
v 24.1455 37.1227 -26.2413
# 4 vertices
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
# 6 vertex normals
vt 0.9995 0.0005 0.0000
vt 0.0005 0.0005 0.0000
vt 0.9995 0.9995 0.0000
vt 0.0005 0.9995 0.0000
# 4 texture coords
o back
g back
usemtl default
s 1
f 1/1/1 2/2/2 4/4/3
f 4/4/4 3/3/5 1/1/6
# 2 faces
这是插值 uv 绘图调用。
这是索引算法,我从零开始:
...
Calculus::CPoint3<unsigned short> p, t, n;
sscanf_s(token, "%hu/%hu/%hu %hu/%hu/%hu %hu/%hu/%hu",
&p.x, &t.x, &n.x, &p.y, &t.y, &n.y, &p.z, &t.z, &n.z);
pi.push_back(p);
ti.push_back(t);
ni.push_back(n);
…
index = ti[i].x - 1;
temp_t[0] = vt[index]; // first uv
index = ti[i].y - 1;
temp_t[1] = vt[index]; // second uv
index = ti[i].z - 1;
temp_t[2] = vt[index]; // third uv
我想知道我哪里弄错了。谢谢。
isect->uv = v_uvs[0] * b1 + v_uvs[1] * b2;
这不是顶点属性的正确参数化插值:
- 参数
b1, b2
被应用到错误的顶点
- 您没有考虑第三个顶点
v_uvs[2]
正确版本:
isect->uv = v_uvs[0] * b0 + v_uvs[1] * b1 + v_uvs[2] * b2;
我的光线追踪程序有问题。图像看起来不对。这是输出图像:
重心坐标和碰撞计算代码如下:
bool CTriangle::Intersect(Calculus::CRay& ray, CIntersection* isect) const {
// Möller–Trumbore intersection algorithm
const Calculus::CPoint3<float>& p1 = v_points[0];
const Calculus::CPoint3<float>& p2 = v_points[1];
const Calculus::CPoint3<float>& p3 = v_points[2];
Calculus::CVector3<float> e1 = p2 - p1;
Calculus::CVector3<float> e2 = p3 - p1;
Calculus::CVector3<float> s1 = Calculus::Math::Cross(ray.direction, e2);
float determinant = Calculus::Math::Dot(s1, e1);
if (determinant == 0.0f)
return false;
float inv_determinant = 1.0f / determinant;
Calculus::CVector3<float> s = ray.origin - p1;
float b1 = Calculus::Math::Dot(s, s1) * inv_determinant;
if (b1 < 0.0f || b1 > 1.0f)
return false;
Calculus::CVector3<float> s2 = Calculus::Math::Cross(s, e1);
float b2 = Calculus::Math::Dot(ray.direction, s2) * inv_determinant;
if (b2 < 0.0f || b1 + b2 > 1.0f)
return false;
float b0 = 1 - b1 - b2;
float thit = Calculus::Math::Dot(e2, s2) * inv_determinant;
if (thit < ray.mint || thit > ray.maxt)
return false;
isect->p = ray(thit);
isect->n = Calculus::Math::Normalize(Calculus::CVector3<float>
(v_normals[0].x, v_normals[0].y, v_normals[0].z) * b0 +
Calculus::CVector3<float>(v_normals[1].x, v_normals[1].y,
v_normals[1].z) * b1 +
Calculus::CVector3<float>(v_normals[2].x, v_normals[2].y,
v_normals[2].z) * b2);
isect->uv = v_uvs[0] * b0 + v_uvs[1] * b1 + v_uvs[2] * b2;
isect->tHit = thit;
isect->ray_epsilon = 1e-5f * thit;
return true;
}
我在光线追踪程序中使用的纹理:(文件类型:bmp)
我的obj文件如下。背景形状由两个三角形组成。纹理投影仅应用于背景形状:
v -24.1456 -11.1684 -26.2413
v 24.1455 -11.1684 -26.2413
v -24.1456 37.1227 -26.2413
v 24.1455 37.1227 -26.2413
# 4 vertices
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 1.0000
# 6 vertex normals
vt 0.9995 0.0005 0.0000
vt 0.0005 0.0005 0.0000
vt 0.9995 0.9995 0.0000
vt 0.0005 0.9995 0.0000
# 4 texture coords
o back
g back
usemtl default
s 1
f 1/1/1 2/2/2 4/4/3
f 4/4/4 3/3/5 1/1/6
# 2 faces
这是插值 uv 绘图调用。
这是索引算法,我从零开始:
...
Calculus::CPoint3<unsigned short> p, t, n;
sscanf_s(token, "%hu/%hu/%hu %hu/%hu/%hu %hu/%hu/%hu",
&p.x, &t.x, &n.x, &p.y, &t.y, &n.y, &p.z, &t.z, &n.z);
pi.push_back(p);
ti.push_back(t);
ni.push_back(n);
…
index = ti[i].x - 1;
temp_t[0] = vt[index]; // first uv
index = ti[i].y - 1;
temp_t[1] = vt[index]; // second uv
index = ti[i].z - 1;
temp_t[2] = vt[index]; // third uv
我想知道我哪里弄错了。谢谢。
isect->uv = v_uvs[0] * b1 + v_uvs[1] * b2;
这不是顶点属性的正确参数化插值:
- 参数
b1, b2
被应用到错误的顶点 - 您没有考虑第三个顶点
v_uvs[2]
正确版本:
isect->uv = v_uvs[0] * b0 + v_uvs[1] * b1 + v_uvs[2] * b2;