【问题标题】:KDTree 3D by splitting using mid point : Bounding Box Intersection gives me artifactsKDTree 3D by split using mid point : Bounding Box Intersection 给了我伪影
【发布时间】:2015-10-29 15:03:53
【问题描述】:

您好,我正在编写我的光线追踪代码。我大部分时间都完成了我的实验,现在正在尝试优化它以获得最佳速度。所以我正在实现 KDTree 并使用中点分割三角形。没有 KDTree 我的结果很好,但是使用 KDtree 我在输出中得到了一些工件。我不知道哪里出了问题。

KDTree 之前

KDTree 之后

我的 KDTree 代码在这里:

#include "sgrender.h"

#ifndef KDNODE_H_
#define KDNODE_H_

using namespace std;

struct KDNode {
    BoundingBox bbox;
    KDNode* left;
    KDNode* right;
    vector<Shape*> objects;

    KDNode() {
        bbox = BoundingBox();
    }

    void addObject(Shape*& obj) {
        objects.push_back(obj);
        bbox.expand(obj->bbox);
    }

    void build() {
        printf("Building\n");
        if(objects.size() <= 1)
            return;

        left = new KDNode();
        right = new KDNode();

        Vec midpt = Vec(0, 0, 0);
        for(int i = 0; i < objects.size(); i++)
            midpt = midpt + objects[i]->midpt;

        midpt = midpt * (1.0/ objects.size());

        int axis = bbox.longestAxis();

        for(int i = 0; i < objects.size(); i++) {
            switch(axis) {
                case 0:
                    if(midpt.x > objects[i]->midpt.x)
                        right->addObject(objects[i]);
                    else
                        left->addObject(objects[i]);
                    break;
                case 1:
                    if(midpt.y > objects[i]->midpt.y)
                        right->addObject(objects[i]);
                    else
                        left->addObject(objects[i]);
                    break;
                case 2:
                    if(midpt.z > objects[i]->midpt.z)
                        right->addObject(objects[i]);
                    else
                        left->addObject(objects[i]);
                    break;
            }
        }

        if(left->objects.size() && right->objects.size()) {
            left->build();
            right->build();
        }
    }

    Shape* intersect(Ray r, double &depth) {
        Shape *shape = NULL;

        if(DISABLE_KDTREE) {
            for(int i = 0; i < objects.size(); i++) {
                double d = objects[i]->intersect(r);
                if(d > 0 && d < depth) {
                    depth = d;
                    shape = objects[i];
                }
            }
        } else if(bbox.intersect(r)) {
            if((left && left->objects.size() > 0) || (right && right->objects.size() > 0)) {
                double d = depth;
                if(right && right->objects.size() > 0) {
                    Shape *rshape = right->intersect(r, d);
                    if(rshape && d > 0 && d < depth) {
                        shape = rshape;
                        depth = d;
                    }
                }
                if(left && left->objects.size() > 0) {
                    Shape *lshape = left->intersect(r, d);
                    if(lshape && d > 0 && d < depth) {
                        shape = lshape;
                        depth = d;
                    }
                }
            } else {
                for(int i = 0; i < objects.size(); i++) {
                    double d = objects[i]->intersect(r);
                    if(d > 0 && d < depth) {
                        depth = d;
                        shape = objects[i];
                    }
                }
            }
        }
        return shape;
    }
};

#endif

【问题讨论】:

  • 我建议你使用智能指针,比如 shared_ptr。 (我不是说这可以来自那里,但它更好)
  • @sop 感谢您的建议。我今天试试。
  • @sop 我已将代码更新为智能指针 (shared_ptr)。该更改并没有解决工件问题,但使许多其他方式受益。递归中不再出现分段错误。感谢您的宝贵建议。

标签: c++ raytracing bounding-box kdtree


【解决方案1】:

终于在我的代码中发现了问题。

1) 基于最长轴的分割导致慢速遍历。 KDTree 构建实际上并没有有效地发生,或者在某些情况下根本没有发生。

2) 边界框计算给了我工件。从论文和书籍中尝试了许多不同的代码后,找到了Most efficient and best Ray-boundingbox intersection 测试算法。

【讨论】:

    猜你喜欢
    • 2014-01-16
    • 1970-01-01
    • 2022-12-02
    • 2021-12-05
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    相关资源
    最近更新 更多