首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双向路径跟踪

双向路径跟踪
EN

Stack Overflow用户
提问于 2016-03-03 19:37:05
回答 1查看 467关注 0票数 1

我在做双向路径追踪器我有一些麻烦。

要清楚的是: 1)一点光2)所有物体都是扩散的3)所有物体都是球体,甚至墙壁(它们很大) 4)没有MIS重量

光发射是一个三维矢量。球面的BRDF是三维矢量。硬编码。

在下面的主要函数中,我生成EyePath和LightPath,然后连接它们。至少我尽力了。

在这篇文章中,我将讨论主要函数,然后是EyePath,然后是LightPath。关于连接功能的讨论将在EyePath和Light很好的时候出现。

  1. 第一个问题:
    • 第一个光点的产生好吗?
    • 我需要根据光源的发射量来计算这一点吗?还是仅仅是排放?在填充顶点结构的地方,对这一行进行了注释。
    • 我需要从光中翻译吗?为了把它放在球体上

下面的代码是在主函数中采样的。在它上面有两个for循环,遍历所有像素。凯美拉诺是眼睛。CameraRayDir是指向当前像素的方向。

//The path light starting point is at the same position as the light Ray fromLight(Vec(0, 24.3, 0), Vec()); Sphere light = spheres[7];

代码语言:javascript
复制
#define PDF 0.15915494309 // 1 / (2 * PI)    

for(int i = 0; i < samps; ++i)
{
    std::vector<Vertices> PathEye;
    std::vector<Vertices> PathLight;

    Vec cameraRayDir = cx * (double(x) / w - .5) + cy * (double(y) / h - .5) + camera.d;

    Ray rayEye(camera.o, cameraRayDir.norm());              

    // Hemisphere oriented towards the top
    fromLight.d = generateRayInHemisphere(fromLight.o,Vec(0,1,0)).d;

    double f = clamp(n.dot(fromLight.d.norm()));

    Vertices vert;
    vert.d = fromLight.d;           
    vert.x = fromLight.o;
    vert.id = 7;
    vert.cos = f;
    vert.n = Vec(0,1,0).norm();

    // this one ?
    //vert.couleur = spheres[7].e * f / PDF;

    // Or this one ?
    vert.couleur = spheres[7].e;

    PathLight.push_back(vert);

    int sizeEye = generateEyePath(PathEye, rayEye, maxDepth);
    int sizeLight = generateLightPath(PathLight, fromLight, maxDepth);

    for (int s = 0; s < sizeLight; ++s)
    {
        for (int t = 1; t < sizeEye; ++t)
        {
          int depth = t + s - 1;
          if ((s == 0 && t == 0) || depth < 0 || depth > maxDepth)
            continue;

          pixelValue = pixelValue + connectPaths(PathEye, PathLight, s, t);
        }
     }
}

对于EyePath,我与几何相交,然后根据与光的距离计算光照。如果点在阴影中,颜色是黑色的。

第二个问题:对于眼路和直接照明,计算好吗?我在许多代码中见过,人们使用pdf甚至在直接照明。但我只使用点光和球体。

代码语言:javascript
复制
int generateEyePath(std::vector<Vertices>& v, Ray eye, int maxDepth)
{
  double t;
  int id = 0;

  Vertices vert;

  int RussianRoulette;

  while(v.size() <= maxDepth)
  {

    if(distribRREye(generatorRREye) < 10)
      break;

    // Intersect all the geometry
    // id is the id of the intersected geometry in an array
    intersect(eye, t, id);

    const Sphere& obj = spheres[id];

    // Intersection point
    Vec x = eye.o + eye.d * t;

    // normal
    Vec n = (x - obj.p).norm();  

    Vec direction = light.p - x;   

    // Shadow ray
    Ray RaytoLight = Ray(x, direction.norm());        

    const float distance = direction.length();

    // shadow
    const bool visibility = intersect(RaytoLight, t, id);

    const Sphere &lumiere = spheres[id];

    float degree = clamp(n.dot((lumiere.p - x).norm()));

    // If the intersected geometry is not a light, then in shadow
    if(lumiere.e.x == 0)
    {
      vert.couleur = Vec(); 
    }
    else // else we compute the colour
       // obj.c is the brdf, lumiere.e is the emission
       vert.couleur = (obj.c).mult(lumiere.e / (distance * distance)) * degree;    

    vert.x = x;
    vert.id = id;
    vert.n = n;
    vert.d = eye.d.normn();
    vert.cos = degree;

    v.push_back(vert);

    eye = generateRayInHemisphere(x,n);
  }

  return v.size();
 }

对于LightPath,对于给定的点,我根据前一个点和此时的值计算它。就像在公共路径跟踪中一样。\n

第三个问题:颜色计算好吗?

代码语言:javascript
复制
int generateLightPath(std::vector<Vertices>& v, Ray fromLight, int maxDepth)
{
   double t;
   int id = 0;

   Vertices vert;

   Vec previous;

   while(v.size() <= maxDepth)
   {
    if(distribRRLight(generatorRRLight) < 10)
      break;

    previous = v.back().couleur;

    intersect(fromLight, t, id);

    // intersected geometry
    const Sphere& obj = spheres[id];

    // Intersection point
    Vec x = fromLight.o + fromLight.d * t;

    // normal
    Vec n = (x - obj.p).norm();   

    double f = clamp(n.dot(fromLight.d.norm()));

    // obj.c is the brdf
    vert.couleur = previous.mult(((obj.c / M_PI) * f) / PDF);  

    vert.x = x;
    vert.id = id;
    vert.n = n;
    vert.d = fromLight.d.norm();
    vert.cos = f;

    v.push_back(vert);

    fromLight = generateRayInHemisphere(x,n);
  }

  return v.size();
 }

现在我得到了这个结果。

在这里输入图像描述

一旦EyePath和LightPath良好,连接功能就会出现。

谢谢大家

EN

回答 1

Stack Overflow用户

发布于 2016-03-30 20:26:02

尝试本文中提到的球面参考场景。我想你可以自己解决大部分问题,因为它有一个分析性的解决方案。

场景

它将节省您的时间来实现和验证您的理解与路径跟踪和光跟踪,然后尝试结合他们与权重。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35781443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档