我真的不知道还能做什么来解决这个问题。我在c++中写了一个使用显式光线采样的路径跟踪器,我一直得到这个奇怪的、真正的黑色阴影,我知道这是错误的。我已经做了所有的事情来解决它,但我仍然得到它,即使在更高的samples.What上,我做错了吗?下面是场景的图像。

和Radiance主代码
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;
}发布于 2015-02-20 06:35:46
我还没有调试过你的代码,所以当然可能有很多bug,但我可以给你一些提示:首先,去看看SmallPT,看看它做了什么,你没有做什么。它很小,但仍然很容易阅读。
从外观上看,似乎在采样和/或伽马校正方面存在问题。最简单的是gamma:将范围为0..1的RGB强度转换为范围为0..255的RGB时,请记住始终进行gamma校正。使用2.2的gamma
R = r^(1.0/gamma)
G = g^(1.0/gamma)
B = b^(1.0/gamma)使用错误的gamma将使任何路径跟踪图像看起来都很糟糕。第二:抽样。从代码中看不出采样是如何加权的。我只熟悉使用俄罗斯轮盘赌采样的路径跟踪。在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基本上是一种随机终止光线的方法,但仍然保持对真实辐射度的无偏估计。由于它增加了间接项的权重,而speheres的阴影和底部只是间接照明,我怀疑这与它有关(如果不只是gamma)。
https://stackoverflow.com/questions/28617480
复制相似问题