Raytracer Refraction Bug

Raytracer Refraction Bug

本文关键字:Bug Refraction Raytracer      更新时间:2023-10-16

我正在用c++写一个光线追踪器,我一直有一些折射问题。我正在绘制一个球体和一个地平面,球体应该会折射。然而,它看起来更像是球中球:"外"球看起来有适当的阴影,但没有折射,而"内"球看起来像是自阴影。这里有一个链接可以看到它的样子:https://i.stack.imgur.com/fRmxP.jpg.

这是相关的代码。

//inside main raytrace function
     if(refraction > 0.0f){ //the surface is refractive
        //calculate refraction vector
        Ray refract(intersection,
          objList[bestObj]->refractedRay(
            ray.dir,intersection,&cos_theta,&R0));
        //recurse
        refrColor = raytrace(refract);
      }
      else{ //no refraction
        refrColor = background;
      }

//refractedRay(vec3,vec3,float*,float*)
  //...initialize variables, do geometric transforms
  //into air out of obj
  if(dot(ray,normal) < 0){
    n1 = ior;
    n2 = 1.0f;
    *cos = dot(ray,-normal);
  }
  //into obj out of air
  else{
    n1 = 1.0f;
    n2 = ior;
    *cos = dot(ray,normal);
    normal = -normal;
  }
  //check value under sqrt
  float n = n1/n2;
  float disc = 1-(pow(n,2)*(1-pow(*cos,2)));
  if(disc < 0){ //total internal reflection
    return ray - 2*-(*cos)*normal; //reflection vector
  }
  return (n*ray)+(((n*(*cos))-sqrt(disc))*normal);

这个球体以前看起来更糟,然后我想起了对向量进行标准化,它看起来是这样的。以前,它看起来只是内部的球体。在主光线追踪函数中,我用和反射相同的方式进行折射,只是使用折射光线代替。我也试着用epsilon修改交点和射线的入射点,以检查自折射,因为你可以在阴影中得到。

任何帮助都将是感激的:)

我没有检查你的折射公式,但这看起来不对:

//into air out of obj
if(dot(ray,normal) < 0){
  n1 = ior;
  n2 = 1.0f;
  *cos = dot(ray,-normal);
}

如果入射光线和法线的点积小于零,并且假设法线点向外(很可能是这样),那么这种情况对应于air -> inside,所以你的折射率应该交换。就像现在,你正在渲染一个具有ior 1 / ior的球体,并且由于折射率小于1,你正在观察边缘的全内反射。

这是我的一个实现,你可以看看是否有什么缺失(它有更多的功能,但你应该能够识别你感兴趣的部分,并检查你的计算是否匹配)。对我来说,它看起来很好,所以我认为固定折射率应该可以做到。

球体中心的不确定图案,虽然,肯定看起来像自交。确保在反射的情况下,将反射的光线稍微推到相交面的外面,在折射的情况下,将折射的光线稍微推到里面,以避免自相交。