作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
您好,我正在实现蒙特卡洛路径追踪,并且运行良好,但看起来交集代码存在一些问题。以下是图片
如果您在左下角看到红色,则似乎显示了背景色。
以下是
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;
我不确定我在哪里犯了错误。
最佳答案
您的光线缺少两个四边形;这是一个“裂缝”。 HitTest 代码中的任何不一致或数值不准确都可能导致“裂缝”或“接缝”,即光线应该恰好命中一个多边形时却没有命中任何一个多边形。这是一个常见的问题,但可以解决。这也是光栅化要避免的问题,不仅仅是光线追踪。请记住, float 和 double 并不是无限精确的。始终确保对一个多边形上的边的计算与相邻多边形上的相同边的计算相同。换句话说,你的四边形是顺时针还是逆时针?
这是一篇不错的论文:jcgt.org/published/0002/01/05/paper.pdf
关于c++ - 光线四边形相交代码的问题(看起来像撕裂),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55465453/
我正在尝试使用 Sfml 编写 2D 游戏。对于那个游戏,我需要一个 Lightengine 和一些代码,这些代码可以为我提供玩家可见的世界区域。由于这两个问题非常吻合(实际上是相同的),我想同时解决
我是一名优秀的程序员,十分优秀!