2015-02-19 5 views
1

Я действительно не знаю, что еще можно сделать, чтобы исправить эту проблему. Я написал трассировщик путей, используя явную выборку света в C++, и я продолжаю получать эти странные действительно черные тени, которые, как я знаю, ошибочны. Я сделал все, чтобы исправить это, но я все равно продолжаю получать его, даже на более высоких образцах. Что я делаю неправильно? Ниже приведен образ сцены.Ошибка трассировки трассировки

enter image description here

И Сияние Основной код

RGB Radiance(Ray PixRay,std::vector<Primitive*> sceneObjects,int depth,std::vector<AreaLight> AreaLights,unsigned short *XI,int E) 
{ 
    int MaxDepth = 10; 

    if(depth > MaxDepth) return RGB(); 

    double nearest_t = INFINITY; 
    Primitive* nearestObject = NULL; 

    for(int i=0;i<sceneObjects.size();i++) 
    { 
     double root = sceneObjects[i]->intersect(PixRay); 
     if(root > 0) 
     { 
      if(root < nearest_t) 
      { 
       nearest_t = root; 
       nearestObject = sceneObjects[i]; 
      } 
     } 
    } 

    RGB EstimatedRadiance; 

    if(nearestObject) 
    {  
     EstimatedRadiance = nearestObject->getEmission() * E;  
     Point intersectPoint = nearestObject->intersectPoint(PixRay,nearest_t); 
     Vector intersectNormal = nearestObject->surfacePointNormal(intersectPoint).Normalize(); 

     if(nearestObject->getBRDF().Type == 1) 
     {  
      for(int x=0;x<AreaLights.size();x++) 
      { 

       Point pointOnTriangle = RandomPointOnTriangle(AreaLights[x].shape,XI); 
       Vector pointOnTriangleNormal = AreaLights[x].shape.surfacePointNormal(pointOnTriangle).Normalize(); 
       Vector LightDistance = (pointOnTriangle - intersectPoint).Normalize(); 

       //Geometric Term 
       RGB Geometric_Term = GeometricTerm(intersectPoint,pointOnTriangle,sceneObjects); 
       //Lambertian BRDF 
       RGB LambertianBRDF = nearestObject->getColor() * (1./M_PI); 
       //Emitted Light Power 
       RGB Emission = AreaLights[x].emission; 

       double MagnitudeOfXandY = (pointOnTriangle - intersectPoint).Magnitude() * (pointOnTriangle - intersectPoint).Magnitude(); 
       RGB DirectLight = Emission * LambertianBRDF * Dot(intersectNormal,-LightDistance) * 
        Dot(pointOnTriangleNormal,LightDistance) * (1./MagnitudeOfXandY) * AreaLights[x].shape.Area() * Geometric_Term; 

       EstimatedRadiance = EstimatedRadiance + DirectLight; 
      } 
      // 
      Vector diffDir = CosWeightedRandHemiDirection(intersectNormal,XI); 
      Ray diffRay = Ray(intersectPoint,diffDir);  
      EstimatedRadiance = EstimatedRadiance + (Radiance(diffRay,sceneObjects,depth+1,AreaLights,XI,0) * nearestObject->getColor() * (1./M_PI) * M_PI);  
     } 

     //Mirror 
     else if(nearestObject->getBRDF().Type == 2) 
     { 
      Vector reflDir = PixRay.d-intersectNormal*2*Dot(intersectNormal,PixRay.d); 
      Ray reflRay = Ray(intersectPoint,reflDir); 

      return nearestObject->getColor() *Radiance(reflRay,sceneObjects,depth+1,AreaLights,XI,0); 
     } 
    } 

    return EstimatedRadiance;  
} 
+0

http://i.stack.imgur.com/h6NRm.jpg – hecatonchries

+0

Простите меня. Это мой первый вопрос. Вопрос к изображению: http://i.stack.imgur.com/h6NRm .jpg – hecatonchries

+0

Если вы можете поделиться несколькими соответствующими строками кода, это также может быть полезно. Это будет работать лучше всего, если вы используете кнопку кода в редакторе (фигурные скобки) или вставляете код с четырьмя (или более) пробелами. Тогда он будет отформатирован как код довольно красиво! Добро пожаловать в Stackoverflow :) – amenthes

ответ

1

Я не отлажена код, так что может быть любое количество ошибок, конечно, но я могу дать вам несколько советов: во-первых, посмотрите на SmallPT и посмотрите, что он делает, чего не делал. Это крошечно, но все еще довольно легко читать.

Из-за внешнего вида, кажется, что есть проблемы с выборкой и/или гамма-коррекцией. Самый простой из них - гамма: при преобразовании интенсивности RGB в диапазоне от 0..1 до RGB в диапазоне 0..255 помните, что всегда гамма исправлена. Используйте гамму 2.2.

R = r^(1.0/gamma) 
G = g^(1.0/gamma) 
B = b^(1.0/gamma) 

Наличие неправильной гаммы приведет к тому, что любое изображение с трассировкой будет выглядеть плохо. Второй: выборка. Из кода не видно, как взвешивается выборка. Я знаком с Path Tracing с использованием русской выборки рулетки. С RR сияние в основном работает следующим образом:

if (depth > MaxDepth) 
    return RGB(); 

    RGB color = mat.Emission; 

    // Russian roulette: 
    float survival = 1.0f; 
    float pContinue = material.Albedo(); 
    survival = 1.0f/pContinue; 
    if (Rand.Next() > pContinue) 
    return color; 

    color += DirectIllumination(sceneIntersection); 
    color += Radiance(sceneIntersection, depth+1) * survival; 

RR в основном способ прекращения лучей в случайном порядке, но по-прежнему сохраняя объективную оценку истинного сияния. Поскольку он добавляет вес косвенному члену, а тень и дно речей только косвенно горит, я подозреваю, что это имеет к ней какое-то отношение (если это не только гамма).

+0

Я уже добавил функции гамма-коррекции и зажима от smallPT, а также код русской рулетки от smallPT. Он все еще не работал. Я просто решил удалить его. Но я бы попробовал еще раз и посмотрю. Спасибо за ваша помощь. – hecatonchries

Смежные вопросы