【发布时间】:2016-10-21 23:59:11
【问题描述】:
当我尝试渲染场景时,我的渲染出现问题。
这是我的遍历算法:
bool KDTree::traverse(Ray &ray, Node &node, double &tMin, double &tMax, double &tNear, double &u, double &v, Triangle* &hitObject)
{
if(node.tris.size() == 0) return 0;
bool current = false;
//bool intersected = false;
if(!node.isLeaf)
{
int axis = node.split_axis;
double tSplit = (node.split_pos - ray.orig[axis]) / ray.dir[axis];
Node* nearNode = ray.orig[axis] < node.split_pos ? node.leftNode : node.rightNode;
Node* farNode = ray.orig[axis] < node.split_pos ? node.rightNode : node.leftNode;
if (tSplit > tMax)
return traverse(ray, *nearNode , tMin, tMax, tNear, u, v, hitObject);//case A
else if (tSplit < tMin)
{
if(tSplit>0)
return traverse(ray, *farNode, tMin, tMax, tNear, u, v, hitObject);//case B
else if(tSplit<0)
return traverse(ray, *nearNode, tMin, tMax, tNear, u, v, hitObject);//case C
else
{//tSplit==0
if(ray.dir[axis]<0)
return traverse(ray, *farNode, tMin, tMax, tNear, u, v, hitObject);//case D
else
return traverse(ray, *nearNode, tMin, tMax, tNear, u, v, hitObject);//case E
}
}
else
{
if(tSplit>0)
{//case F
current = traverse(ray, *nearNode, tMin, tSplit, tNear, u, v, hitObject);
if (current != false)
return current;
else
return traverse(ray, *farNode, tSplit, tMax, tNear, u, v, hitObject);
}
else
{
return traverse(ray, *nearNode,tSplit, tMax, tNear, u, v, hitObject);//case G
}
}
}
else
{
tNear = 9999999;
for(unsigned int i = 0; i < node.tris.size(); ++i)
{
double t = 9999999;
if(node.tris[i]->intersect(ray, t, u, v) && t < tNear)
{
hitObject = node.tris[i];
tNear = t;
}
}
return (hitObject != nullptr);
}
}
这是我的构建算法:
void KDTree::buildkdtree(Node &node)
{
std::cout << "stò inizializzando il nodo di profondità: " << node.depth << std::endl;
if(node.tris.size() <= 30 || node.depth >= 15)
{
std::cout << "ho creato una foglia di livello: " << node.depth << " , con " << node.tris.size() << " triangoli" << std::endl;
node.isLeaf = true;
return;
}
int axis = (node.depth % 3);
std::vector<Vec3d> midPoints;
for(unsigned int i = 0; i < node.tris.size(); ++i)
{
midPoints.push_back(node.tris[i]->getMidPoint());
}
std::vector<double> mid;
node.split_axis = axis;
node.rightNode = new struct Node;
node.leftNode = new struct Node;
double max, min, med;
switch(node.split_axis)
{
case(0):
std::cout << "splitto su x" << std::endl;
for(unsigned int i = 0; i < midPoints.size(); ++i)
{
mid.push_back(midPoints[i].x);
}
std::sort(mid.begin(), mid.end());
if(mid.size() % 2 == 0)
med = (mid[mid.size()/2 - 1] + mid[mid.size()/2]) / 2;
else
med = mid[mid.size()/2];
node.split_pos = med;
std::cout << "l'intervallo e': (" << node.bbox->xMin << " ," << node.bbox->xMax << ")\n";
std::cout << "split_pos = " << node.split_pos << std::endl;
node.rightNode->bbox = new Bbox(node.bbox->xMax, node.split_pos, node.bbox->yMax, node.bbox->yMin, node.bbox->zMax, node.bbox->zMin);
node.leftNode->bbox = new Bbox(node.split_pos, node.bbox->xMin, node.bbox->yMax, node.bbox->yMin, node.bbox->zMax, node.bbox->zMin);
for(unsigned int i = 0; i < node.tris.size(); ++i)
{
node.tris[i]->getExtreme(max, min, axis);
if(min <= node.split_pos)
node.leftNode->tris.push_back(node.tris[i]);
if(max >= node.split_pos)
node.rightNode->tris.push_back(node.tris[i]);
}
break;
case(1):
std::cout << "splitto su y" << std::endl;
for(unsigned int i = 0; i < midPoints.size(); ++i)
{
mid.push_back(midPoints[i].y);
}
std::sort(mid.begin(), mid.end());
if(mid.size() % 2 == 0)
med = (mid[mid.size()/2 - 1] + mid[mid.size()/2]) / 2;
else
med = mid[mid.size()/2];
node.split_pos = med;
std::cout << "l'intervallo e': (" << node.bbox->yMin << " ," << node.bbox->yMax << ")\n";
std::cout << "split_pos = " << node.split_pos << std::endl;
node.rightNode->bbox = new Bbox(node.bbox->xMax, node.bbox->xMin, node.split_pos, node.bbox->yMin, node.bbox->zMax, node.bbox->zMin);
node.leftNode->bbox = new Bbox(node.bbox->xMax, node.bbox->xMin, node.bbox->yMax, node.split_pos, node.bbox->zMax, node.bbox->zMin);
for(unsigned int i = 0; i < node.tris.size(); ++i)
{
node.tris[i]->getExtreme(max, min, axis);
if(min <= node.split_pos)
node.leftNode->tris.push_back(node.tris[i]);
if(max >= node.split_pos)
node.rightNode->tris.push_back(node.tris[i]);
}
break;
case(2):
std::cout << "splitto su z" << std::endl;
for(unsigned int i = 0; i < midPoints.size(); ++i)
{
mid.push_back(midPoints[i].z);
}
std::sort(mid.begin(), mid.end());
if(mid.size() % 2 == 0)
med = (mid[mid.size()/2 - 1] + mid[mid.size()/2]) / 2;
else
med = mid[mid.size()/2];
node.split_pos = med;
std::cout << "l'intervallo e': (" << node.bbox->zMin << " ," << node.bbox->zMax << ")\n";
std::cout << "split_pos = " << node.split_pos << std::endl;
node.rightNode->bbox = new Bbox(node.bbox->xMax, node.bbox->xMin, node.bbox->yMax, node.bbox->yMin, node.split_pos, node.bbox->zMin);
node.leftNode->bbox = new Bbox(node.bbox->xMax, node.bbox->xMin, node.bbox->yMax, node.bbox->yMin, node.bbox->zMax, node.split_pos);
for(unsigned int i = 0; i < node.tris.size(); ++i)
{
node.tris[i]->getExtreme(max, min, axis);
if(min <= node.split_pos)
node.leftNode->tris.push_back(node.tris[i]);
if(max >= node.split_pos)
node.rightNode->tris.push_back(node.tris[i]);
}
break;
default:
std::cout << "Errore, non ho uno dei tre assi" << std::endl;
break;
}
std::cout << "i " << node.tris.size() << " triangoli del padre sono stati divisi così\n";
std::cout << node.rightNode->tris.size() << " nel nodo di destra\n";
std::cout << node.leftNode->tris.size() << " nel nodo di sinistra\n" << std::endl;
node.rightNode->depth = node.depth + 1;
node.leftNode->depth = node.depth + 1;
std::cout << "sto processando figlio di destra del nodo di profondità: " << node.depth << std::endl;
buildkdtree(*(node.rightNode));
std::cout << "sto processando figlio di sinistra del nodo di profondità: " << node.depth << std::endl;
buildkdtree(*(node.leftNode));}
有人可以帮助我吗?
PS:这是我得到的图像:
【问题讨论】:
-
有什么问题?
-
如果你看左上角猴子的嘴附近,一些多边形不会变红,但如果我将相机设置更改为前视图,则没有问题
-
你能贴一张更清晰/更大/更清晰的图片来说明问题吗?
标签: c++ raytracing tree-traversal kdtree