避免在基于构造函数输入的类成员函数中使用 if 语句?

问题描述 投票:0回答:1

我正在寻找优化我拥有的一些光线追踪代码的方法。假设我有以下

Triangle
类,如下所示(为简洁起见,进行了简化):

class Triangle {
public:
    Triangle(Vertex v0, Vertex v1, Vertex v2, bool smoothShading);

    void intersect(Ray& ray)
    {
        if (smoothShading) {
            ray.hit.n = normalize(ray.hit.uv[0] * v1.normal + ray.hit.uv[1] * v2.normal + w * v0.normal);
        }
        else {
            ray.hit.n = -n;
        };
    };

private:
    bool smoothShading;
    Vertex<Tp> v0{};
    Vertex<Tp> v1{};
    Vertex<Tp> v2{};

    vec3<Tp> n;
}

intersect()
成员函数需要被调用数十亿次,因此我认为每次都评估
if (smoothShading)
是完全没有必要的,因为在构造
Triangle
时就知道值是
true
还是
false
。最简单的解决方案是拥有单独的
SmoothTriangle
FlatTriangle
类,这样我就可以做到:

void SmoothTriangle::intersect(Ray& ray)
{
    ray.hit.n = normalize(ray.hit.uv[0] * v1.normal + ray.hit.uv[1] * v2.normal + w * v0.normal);
};

void FlatTriangle::intersect(Ray& ray)
{
    ray.hit.n = -n;
};

问题是我需要处理引用/指针才能使其工作,但我的许多函数都需要诸如

std::vector<Triangle>
之类的输入。我可以把它变成
std::vector<shared_ptr<Triangle>>
或类似的东西,但随后我会引入另一个指针间接,不是吗?

在所有这些情况下,各个类实际包含的成员数据都是相同的。我只是希望

intersect()
函数根据其构造方式进行更改,以避免在渲染时检查内容,因为渲染时许多函数被调用数十亿次。

c++ class if-statement polymorphism
1个回答
0
投票

您可以将行为隔离到单独的类成员函数中,然后使用指向所需函数的指针,例如:

class Triangle {
public:
    Triangle(Vertex v0, Vertex v1, Vertex v2, bool smoothShading)
    {
        ...
        if (smoothShading)
            m_intersect = &Triangle::interceptSmooth;
        else
            m_intersect = &Triangle::intersectFlat;
    }

    void intersect(Ray& ray)
    {
        (this->*m_intersect)(ray);
    }

private:

    void (Triangle::*m_intersect)(Ray&);

    Vertex<Tp> v0{};
    Vertex<Tp> v1{};
    Vertex<Tp> v2{};

    vec3<Tp> n;

    void intersectSmooth(Ray& ray)
    {
        ray.hit.n = normalize(ray.hit.uv[0] * v1.normal + ray.hit.uv[1] * v2.normal + w * v0.normal);
    }

    void intersectFlat(Ray& ray)
    {
        ray.hit.n = -n;
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.