2016-03-03 95 views
1

我正在做一個雙向路徑示蹤和我有一些麻煩。雙向路徑追蹤

要明確: 1)一個點光源 2)中的所有對象都漫 3)的所有對象是球體,甚至壁(它們是非常大的) 4)NO MIS WEIGHTING

發光是一個3D矢量。球體的BRDF是3D矢量。硬編碼。

在主要功能如下我產生EyePath和光路,然後我將它們連接起來。至少我嘗試。

在這篇文章中,我將談論的主要功能則EyePath然後光路。關於連接功能的討論一旦出現EyePath和Light就會出現。

  1. 第一個問題:
    • 做的第一光點的產生是好的?
    • 我需要根據光源的發射來計算這個點嗎?還是僅僅是排放?該行被註釋到我填充Vertices結構的地方。
    • 我需要翻譯fromlight嗎?爲了把它放在球

下面的代碼在主功能採樣。在它上面有兩個for循環遍歷所有像素。 Camera.o是眼睛。 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];

#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。但我只使用點光源和球體。

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(); 
} 

對於光路,對於給定的點,我根據前述一個,並在該點的值計算它。就像在一個共同的路徑追蹤\ n

第三個問題:是顏色計算好?

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(); 
} 

目前我得到了這個結果。

enter image description here

連接功能來一次EyePath和光路都不錯。

謝謝大家

回答