光线跟踪obj文件漫反射着色问题

时间:2017-03-23 21:57:59

标签: c++ graphics 3d rendering raytracing

The repository (GitHub)

我的模型的漫反射阴影存在问题(渲染图元时不会出现这种情况。

这里有什么值得注意的是我认为当你看左侧反射球时,阴影看起来是正常的(基于观察,我可能错了)。

Low poly bunny and a triangle

Low poly bunny and 2 reflective spheres

Cube and 2 reflective spheres

我不确定我做错了什么,因为每次在构造函数中创建三角形时都会计算法线。我使用tinyobjloader加载我的模型,这里是the TriangleMesh intersection algorithm

FPType TriangleMesh::GetIntersection(const Ray &ray)
{
    for(auto &shape : shapes)
    {
        size_t index_offset = 0;
        for(size_t f = 0; f < shape.mesh.num_face_vertices.size(); ++f) // faces (triangles)
        {
            int fv = shape.mesh.num_face_vertices[f];
            tinyobj::index_t &idx0 = shape.mesh.indices[index_offset + 0]; // v0
            tinyobj::index_t &idx1 = shape.mesh.indices[index_offset + 1]; // v1
            tinyobj::index_t &idx2 = shape.mesh.indices[index_offset + 2]; // v2

            Vec3d &v0 = Vec3d(attrib.vertices[3 * idx0.vertex_index + 0], attrib.vertices[3 * idx0.vertex_index + 1], attrib.vertices[3 * idx0.vertex_index + 2]);
            Vec3d &v1 = Vec3d(attrib.vertices[3 * idx1.vertex_index + 0], attrib.vertices[3 * idx1.vertex_index + 1], attrib.vertices[3 * idx1.vertex_index + 2]);
            Vec3d &v2 = Vec3d(attrib.vertices[3 * idx2.vertex_index + 0], attrib.vertices[3 * idx2.vertex_index + 1], attrib.vertices[3 * idx2.vertex_index + 2]);
            Triangle tri(v0, v1, v2);
            if(tri.GetIntersection(ray))
                return tri.GetIntersection(ray);
            index_offset += fv;
        }
    }
}

The Triangle Intersection algorithm

FPType Triangle::GetIntersection(const Ray &ray)
{
    Vector3d v0v1 = v1 - v0;
    Vector3d v0v2 = v2 - v0;
    Vector3d pvec = ray.GetDirection().Cross(v0v2);
    FPType det = v0v1.Dot(pvec);

    // ray and triangle are parallel if det is close to 0
    if(abs(det) < BIAS)
        return false;

    FPType invDet = 1 / det;
    FPType u, v;
    Vector3d tvec = ray.GetOrigin() - v0;
    u = tvec.Dot(pvec) * invDet;
    if(u < 0 || u > 1)
        return false;

    Vector3d qvec = tvec.Cross(v0v1);
    v = ray.GetDirection().Dot(qvec) * invDet;
    if(v < 0 || u + v > 1)
        return false;

    FPType t = v0v2.Dot(qvec) * invDet;

    if(t < BIAS)
        return false;

    return t;
}

我认为这是因为当我处理所有物体交叉点时,三角形网格仅被视为1个对象,因此当我试图获取对象法线时,它只返回1个法线:{{3} }

Color Trace(const Vector3d &origin, const Vector3d &direction, const std::vector<std::shared_ptr<Object>> &sceneObjects, const int indexOfClosestObject,
                 const std::vector<std::shared_ptr<Light>> &lightSources, const int &depth = 0)
{
    if(indexOfClosestObject != -1 && depth <= DEPTH) // not checking depth for infinite mirror effect (not a lot of overhead)
    {
        std::shared_ptr<Object> sceneObject = sceneObjects[indexOfClosestObject];
        Vector3d normal = sceneObject->GetNormalAt(origin);

code

编辑:我已经解决了这个问题,现在着色工作正常:screenshot of debug

1 个答案:

答案 0 :(得分:1)

如果你迭代所有的脸并返回你击中的第一张脸,你可能会碰到其他脸后面的脸,因此不是你要击中的脸,所以你必须测量它的长度。您的光线并返回最短光线的交点。