光线四边形相交代码的问题(看起来像撕裂)
problem with ray quad intersection code (looks like tearing)
您好,我正在实施 monte carlo 路径跟踪,并且运行良好,但交叉口代码似乎存在一些问题。以下是图片
如果您在左下角看到红色,则似乎显示了背景颜色。
以下是
float intersectQuad(Ray r, float3 p1, float3 p2, float3 p3, float3 p4,
float3* outNormal)
{
const float3 x1 = p2 - p1;
const float3 x2 = p4 - p1;
const float3 n = (cross(x2, x1));
const float denom = dot(n, r.dir);
if (denom < 0.00000000001f) return 0.0f;
const float3 p0l0 = (p1 - r.origin);
const float t = dot(p0l0, n) / denom;
if( t < 0.000000000001f ) return 0.0f;
const float3 hitPoint = r.origin + r.dir * t;
const float3 V1 = normalize(p2 - p1);
const float3 V2 = normalize(p3 - p2);
const float3 V3 = normalize(p4 - p3);
const float3 V4 = normalize(p1 - p4);
const float3 V5 = normalize(hitPoint - p1);
const float3 V6 = normalize(hitPoint - p2);
const float3 V7 = normalize(hitPoint - p3);
const float3 V8 = normalize(hitPoint - p4);
if (dot(V1,V5) < 0.0f) return 0.0f;
if (dot(V2,V6) < 0.0f) return 0.0f;
if (dot(V3,V7) < 0.0f) return 0.0f;
if (dot(V4,V8) < 0.0f) return 0.0f;
*outNormal = n;
return t;
}
我调用代码的方式是
const float inf = 1e20f;
float t = inf;
float hitDistance = 0.0f;
for(int j = 0; j < numberOfQuads; j+=16)
{
//v1 , v2 , v3 , v4 are 4 vertices of quad in counter clockwise order
hitDistance = intersectQuad(*ray, v1, v2, v3 ,v4, &n);
if(hitDistance != 0.0f && hitDistance < t )
{
t = hitDistance;
colorIndex = k;
normal = n;
}
}
return t < inf;
我不确定我哪里弄错了。
您的光线缺少两个四边形;这是一个 "crack"。命中测试代码中的任何不一致或数值不准确都可能导致 "cracks" 或 "seams",当光线应该恰好命中一个多边形时,它没有命中任何一个多边形。这是一个常见的问题,但可以解决。这也是光栅化要避免的问题,不仅仅是光线追踪。请记住,浮点数和双精度数并不是无限精确的。始终确保对一个多边形上的边的计算与相邻多边形上的相同边的计算相同。换句话说,你的四边形是顺时针还是逆时针?
这是一篇不错的论文:jcgt.org/published/0002/01/05/paper.pdf
您好,我正在实施 monte carlo 路径跟踪,并且运行良好,但交叉口代码似乎存在一些问题。以下是图片
如果您在左下角看到红色,则似乎显示了背景颜色。
以下是
float intersectQuad(Ray r, float3 p1, float3 p2, float3 p3, float3 p4,
float3* outNormal)
{
const float3 x1 = p2 - p1;
const float3 x2 = p4 - p1;
const float3 n = (cross(x2, x1));
const float denom = dot(n, r.dir);
if (denom < 0.00000000001f) return 0.0f;
const float3 p0l0 = (p1 - r.origin);
const float t = dot(p0l0, n) / denom;
if( t < 0.000000000001f ) return 0.0f;
const float3 hitPoint = r.origin + r.dir * t;
const float3 V1 = normalize(p2 - p1);
const float3 V2 = normalize(p3 - p2);
const float3 V3 = normalize(p4 - p3);
const float3 V4 = normalize(p1 - p4);
const float3 V5 = normalize(hitPoint - p1);
const float3 V6 = normalize(hitPoint - p2);
const float3 V7 = normalize(hitPoint - p3);
const float3 V8 = normalize(hitPoint - p4);
if (dot(V1,V5) < 0.0f) return 0.0f;
if (dot(V2,V6) < 0.0f) return 0.0f;
if (dot(V3,V7) < 0.0f) return 0.0f;
if (dot(V4,V8) < 0.0f) return 0.0f;
*outNormal = n;
return t;
}
我调用代码的方式是
const float inf = 1e20f;
float t = inf;
float hitDistance = 0.0f;
for(int j = 0; j < numberOfQuads; j+=16)
{
//v1 , v2 , v3 , v4 are 4 vertices of quad in counter clockwise order
hitDistance = intersectQuad(*ray, v1, v2, v3 ,v4, &n);
if(hitDistance != 0.0f && hitDistance < t )
{
t = hitDistance;
colorIndex = k;
normal = n;
}
}
return t < inf;
我不确定我哪里弄错了。
您的光线缺少两个四边形;这是一个 "crack"。命中测试代码中的任何不一致或数值不准确都可能导致 "cracks" 或 "seams",当光线应该恰好命中一个多边形时,它没有命中任何一个多边形。这是一个常见的问题,但可以解决。这也是光栅化要避免的问题,不仅仅是光线追踪。请记住,浮点数和双精度数并不是无限精确的。始终确保对一个多边形上的边的计算与相邻多边形上的相同边的计算相同。换句话说,你的四边形是顺时针还是逆时针?
这是一篇不错的论文:jcgt.org/published/0002/01/05/paper.pdf