【问题标题】:Ray tracing, translucent sphere has a dot in centre光线追踪,半透明球体中心有一个点
【发布时间】:2015-04-10 20:13:54
【问题描述】:

我正在构建一个光线追踪器作为任务。我试图让折射对球体起作用,但我得到了一半的工作。问题是我无法摆脱球体中心的黑点

这是交叉口的代码:

double a = rayDirection.DotProduct(rayDirection);
double b = rayOrigin.VectAdd(sphereCenter.Negative()).VectMult(2).DotProduct(rayDirection);
double c = rayOrigin.VectAdd(sphereCenter.Negative()).DotProduct(rayOrigin.VectAdd(sphereCenter.Negative())) - (radius * radius);
double discriminant = b * b - 4 * a * c;

if (discriminant >= 0)
{
    // the ray intersects the sphere
    // the first root
    double root1 = ((-1 * b - sqrt(discriminant)) / 2.0 * a) - 0.000001;
    double root2 = ((-1 * b + sqrt(discriminant)) / 2.0 * a) - 0.000001;

    if (root1 > 0.00001)
    {
        // the first root is the smallest positive root
        return root1;
    }
    else
    {
        // the second root is the smallest positive root    
        return root2;
    }
}
else
{
    // the ray missed the sphere
    return -1;
}

这是负责计算新折射光线方向的代码:

double n1 = refractionRay.GetRefractiveIndex();
double n2 = sceneObjects.at(indexOfWinningObject)->GetMaterial().GetRefractiveIndex();

if (n1 == n2)
{
    // ray inside the same material, means that it is going to be refracted outside, 
    n2 = 1.000293;
}

double n  = n1 / n2;

Vect I = refractionRay.GetRayDirection();
Vect N = sceneObjects.at(indexOfWinningObject)->GetNormalAt(intersectionPosition);

double cosTheta1 = -N.DotProduct(I);
// we need the normal pointing towards the side the ray is coming from
if (cosTheta1 < 0) 
{
    N = N.Negative();
    cosTheta1 = -N.DotProduct(I);
}

double cosTheta2 = sqrt(1 - (n * n) * (1 - (cosTheta1 * cosTheta1)));
Vect refractionDirection = I.VectMult(n).VectAdd(N.VectMult(n * cosTheta1 - cosTheta2));


Ray newRefractionRay(intersectionPosition.VectAdd(refractionDirection.VectMult(0.001)), refractionDirection, n2, refractionRay.GetRemainingIntersections());

在创建新的折射光线时,我尝试将方向乘以一个小值到相交位置,以使这条新光线的原点位于球体内。如果我改变那个小值,黑点的大小就会改变。如果我把它做得太大,球体的边缘也会开始变黑。

如果我给对象添加颜色,它看起来像这样:

如果让那个小常数变大(0.1),就会发生这种情况:

是否有我应该考虑的特殊情况?谢谢!

【问题讨论】:

  • 请注意,绿色球体中的反射也有一个。如果相关,我相信前景球体是无色透明的,而不是反光的?
  • 我建议首先检查您的折射方程 - 球体相交看起来很有效(并且场景中不透明球体的正确渲染支持这一点)。
  • 此外,只要确保找到的根的值确实超过了 epsilon,就不需要从两个根中减去那个 epsilon 因子。这些因素只需要确保从球体表面开始新生成的光线不会再次与球体相交。
  • 哦,你的影子看起来很奇怪。它们不应小于投射它们的球。

标签: transparency raytracing translucency


【解决方案1】:

在计算两个根时,应该去掉减去的 epsilon 因子:

double root1 = ((-1 * b - sqrt(discriminant)) / 2.0 * a);
double root2 = ((-1 * b + sqrt(discriminant)) / 2.0 * a);

根据我的经验,您需要与 epsilon 进行比较的唯一地方是检查找到的根是否沿着射线的路径而不是在其原点,根据您的:

if (root1 > 0.00001)

注意:您可以通过只进行一次平方根计算以及仅计算 root2 if root1 &lt;= epsilon 来获得更多性能

【讨论】:

    猜你喜欢
    • 2019-11-29
    • 1970-01-01
    • 2017-03-26
    • 2019-11-29
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 2011-12-08
    相关资源
    最近更新 更多