gpt4 book ai didi

graphics - 为什么我的光线追踪器不会重新创建 "mount"场景?

转载 作者:行者123 更新时间:2023-12-04 06:48:19 28 4
gpt4 key购买 nike

我正在尝试从 Eric Haines' Standard Procedural Database (SPD) 渲染“mount”场景,但折射部分就是不想配合。我已经尝试了所有我能想到的方法来修复它。

这是我的渲染(使用瓦特公式):

My render.
(来源:philosoraptor.co.za)

这是我使用“正常”公式的渲染:

Normal formula.
(来源:philosoraptor.co.za)

这是正确的渲染:

Correct render.
(来源:philosoraptor.co.za)

如您所见,只有几个错误,主要是在球体的两极附近。这让我认为应该归咎于折射或某些精度误差。

请注意,场景中实际上有 4 个球体,它们的 NFF 定义( s x_coord y_coord z_coord radius )是:

s -0.8 0.8 1.20821 0.17
s -0.661196 0.661196 0.930598 0.17
s -0.749194 0.98961 0.930598 0.17
s -0.98961 0.749194 0.930598 0.17

也就是说,在前景中更明显的三个球体后面还有第四个球体。可以从这三个球体之间留下的间隙中看出。

这是第四个球体的图片:

'Fourth' sphere.
(来源: philosoraptor.co.za)

这是第一个球体的图片:

'First' sphere.
(来源: philosoraptor.co.za)

您会注意到我的版本和正确版本中存在的许多奇怪之处都缺失了。我们可以得出结论,这些影响是球体之间相互作用的结果,问题是哪些相互作用?

我究竟做错了什么?以下是我已经考虑过的一些潜在错误:
  • 折射矢量公式。

  • 据我所知,这是正确的。这是几个网站使用的相同公式,我亲自验证了推导。这是我的计算方法:
    double sinI2 = eta * eta * (1.0f - cosI * cosI); Vector transmit = (v * eta) + (n * (eta * cosI - sqrt(1.0f - sinI2))); transmit = transmit.normalise();
    我在 Alan Watt 的第三版 3D Computer Graphics 中找到了一个替代公式。它更接近于正确的图像:
    double etaSq = eta * eta;
    double sinI2 = etaSq * (1.0f - cosI * cosI);
    Vector transmit = (v * eta) + (n * (eta * cosI - (sqrt(1.0f - sinI2) / etaSq)));
    transmit = transmit.normalise();

    唯一的区别是我最后除以 eta^2 。
  • 全内反射。

  • 我对此进行了测试,在其余交叉代码之前使用以下条件:
    if (sinI2 <= 1)
  • eta的计算。

  • 我使用类似堆栈的方法来解决这个问题:
            /* Entering object. */
    if (r.normal.dot(r.dir) < 0)
    {
    double eta1 = r.iorStack.back();
    double eta2 = m.ior;
    eta = eta1 / eta2;

    r.iorStack.push_back(eta2);
    }
    /* Exiting object. */
    else
    {
    double eta1 = r.iorStack.back();
    r.iorStack.pop_back();
    double eta2 = r.iorStack.back();

    eta = eta1 / eta2;
    }

    如您所见,这会将包含此光线的先前对象存储在堆栈中。当退出代码时,将当前 IOR 从堆栈中弹出并使用它,连同它下面的 IOR 来计算 eta。据我所知,这是最正确的方法。

    这适用于嵌套传输对象。但是,它会因交叉传输对象而崩溃。这里的问题是你需要独立定义交集的 IOR,而 NFF 文件格式没有这样做。目前还不清楚,什么是“正确”的行动方针。
  • 移动新光线的原点。

  • 新光线的原点必须沿着传输路径稍微移动,这样它就不会与前一条在同一点相交。
    p = r.intersection + transmit * 0.0001f;
    p += transmit * 0.01f;
    我试过使这个值更小 (0.001f) 和 (0.0001f) 但这会使球体看起来很坚固。我猜这些值不会将光线从前一个交点移开足够远。

    编辑:这里的问题是反射代码在做同样的事情。因此,当一个物体既具有反射性又具有折射性时,光线的原点最终会出现在完全错误的位置。
  • 光线反弹的数量。

  • 我人为地将光线反弹的数量限制为 4。我测试将此限制提高到 10,但这并没有解决问题。
  • 法线。

  • 我很确定我正在正确计算球体的法线。我取交点,减去球心并除以半径。

    最佳答案

    只是基于进行图像差异的猜测(并且没有阅读您的其余问题)。在我看来,问题是球体背面的折射。你可能是:

  • 向后做:例如反转(或不反转)折射率。
  • 完全错过了吗?

  • 检查这一点的一种方法是通过几乎面向相机的立方体查看安装座。如果折射是正确的,图片应该稍微偏移但不改变。如果不正确,那么图片会看起来稍微倾斜。

    关于graphics - 为什么我的光线追踪器不会重新创建 "mount"场景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3476102/

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