• 2.4 精度问题


      做浮点运算就像移动成堆的沙子。每次你移动一堆,你就会失去一些沙子,捡起一些泥土[5]。这种不精确会导致出现许多问题,必须加以解决。计算机图形学中的一般数值问题的讨论出现在[5]中。下面是对所有光线追踪相交例程的一个常见问题的简要讨论。

      在光线追踪中,光线R0的原点通常是球面上的一个点。从理论上讲,当这些点的t=0时,测试会忽略这些点。然而,在实践中,计算的不精确将会悄悄混入并抛出这些测试。这种不精确会使从表面射来的光线击中表面自己。在计算上所发生的是,t被发现非常接近,但不一定等于零。如果没有校正,大于零的将被认为是有效的交点。使用那些接近0的t会造成一小块表面被自身遮蔽。这个问题如图4所示。这种误差产生了“表面痤疮”,产生阴影疹和斑点。要解决这个问题,必须采取一些措施。下面的讨论也适用于任何其他被相交的图元,因为所有的表面都有这个潜在的问题。(也就是说,t非常接近0的光线折射回球面,从而导致多次反射,光源判定它和球面有间隔,产生了阴影斑。?)

      

      一种避免误差的方法是传递一个标志,说明原点是否真的在球面上。在光线追踪中,最后的交点是已知的,因此程序可以被告知光线从表面开始。然而,如果球体是一个发射器,就必须进行一些测试,以允许折射光线穿过球体并击中另一侧。同样的问题也出现在球体内部的反射上。在这些情况下,t1解是有效答案。

      一个简单的解决方案是检查t是否在某个容忍范围内。例如,如果abs(t) < 0.00001,那么t表示原点在球面上。将这种容忍度扩展到环境的大小是可取的。例如,如果球体是原子,半径以米表示,0.00001米将比任何一个原子都大。选择这些公差可以通过实验或更准确地通过数值方法进行误差分析。例如,公差也可以是基于球面相交的半径。

      root polishing方法也可能有助于解决不精确的问题。例如,跟踪一条光线,找到最近的物体的t(即光线第一次击中的物体)。找到这个交点(方程(A7))并以此作为新光线的原点,新光线的方向相同。通过将球面与新的光线相交,并接受t最接近于零的解(即使t是负的),可以找到更精确的交点。当t大于某个给定的公差时,重复这个过程。这种方法并不消除对公差系数的需要,但它确实允许程序员确信交点在曲面的一定距离内。

      第四个解决方案是根据需要将交点移到球外或球内。也就是说,当相交点被发现并产生新的射线时,确保新的起源是在表面的适当侧面。这可以通过将每条新射线的原点沿正常方向移动,直到发现它位于球体的合适的一侧。这包括通过将交点代入球面方程并检查点位于曲面的哪一边(通过检查曲面表达式的符号来完成)来测试点是在球面内还是在球面外。如果不是在期望的方面,点被一些公差沿着正常移动,然后再次测试。注意,反射和阴影线总是沿正常方向运动,折射光线是负的。这种方法保证了光线不会与球面相交。

      以上所有方法将在不同程度上发挥作用。如果可能的话,第一个方法应该实现,因为它几乎是万无一失的(切光线有时会有问题;但是,这些问题很少见)。对于球和其他四边形,这是可行的。如果不行,那么必须做出一些设计决策来选择适合应用程序的解决方案。

      

  • 相关阅读:
    abstract关键字
    final关键字
    Vue使用枚举类型实现HTML下拉框
    第八节 pandas读取和保存文件
    第七节 pandas新建数据框的两种方式
    第六节 numpy的常用属性和方法
    第五节 numpy的简单使用
    第三节 matplotlib绘制直方图
    第三节 matplotlib绘制条形图
    第二节 matplotlib绘制散点图
  • 原文地址:https://www.cnblogs.com/TooYoungTsukasa/p/9223502.html
Copyright © 2020-2023  润新知