0

我正在使用 Phong 照明模型编写光线跟踪器和着色。在此示例中,我的材料没有任何环境术语。当我渲染时,我得到以下图像:

漫反射和高光渲染

如您所见,镜面反射周围似乎有一个较轻的环。如果我完全禁用镜面反射并且只渲染漫反射,我会得到以下结果:

仅漫反射渲染

所以,这只有在我引入镜面反射时才会发生。我已经做过多次着色,我以前从未见过这种情况。整个着色代码如下(我规范化了一些比我需要的向量更多的向量,以确保这不是问题):

    glm::vec3 shading(std::shared_ptr<scene::scene> scene, std::shared_ptr<hit> hit, uint16_t level)
    {
        glm::vec3 normal = glm::normalize(hit->normal);
        glm::vec3 result = hit->mat->ka; // Initialize ambient lighting with unit (global) intensity.
        glm::vec3 point = hit->r.origin + (glm::normalize(hit->r.direction) * hit->t); // Surface vertex.
        glm::vec3 viewing = glm::normalize(scene->camera_pos - point); // Direction vector to the camera.
        // Iterate through every light source in the scene, as this contributes to the overall lighting.
        for (auto& light_source : scene->lights)
        {
            glm::vec3 light = glm::normalize(light_source.position - point); // Direction vector to the light.
            // Calculate diffuse.
            float diffuse_dot = glm::dot(normal, light); // N . L
            if (diffuse_dot > 0.0f)
            {
                glm::vec3 diffuse = light_source.intensity * (diffuse_dot * hit->mat->kd); // Compute diffuse component.
                result += diffuse; // Add diffuse component to result.
            }
            // Calculate specularity.
            glm::vec3 reflected = glm::reflect(-light, normal); // GLM takes opposite light vector.
            float specularity_dot = glm::dot(viewing, reflected); // R . V
            if (specularity_dot > 0.0f)
            {
                float specularity_coefficient = glm::pow(specularity_dot, hit->mat->ns); // Add specularity component to result.
                glm::vec3 specularity = light_source.intensity * (specularity_coefficient * hit->mat->ks);
                result += specularity; // Add specularity.
            }
        }
        return glm::clamp(result, 0.0f, 1.0f);
    }

颜色写入 PPM 文件,每个像素都这样写入:

   // Writes the color; currently not thread safe.
    void write_color(std::ostream& out, glm::vec3& color)
    {
        out << static_cast<int>(255.999 * color.x) << ' '
            << static_cast<int>(255.999 * color.y) << ' '
            << static_cast<int>(255.999 * color.z) << '\n';
    }

最后,材质定义如下:

    static std::shared_ptr<rt::material> material_blue = std::make_shared<rt::material>(
        glm::vec3{ 0.0f }, // Ka
        glm::vec3{ 0.0f, 0.0f, 1.0f }, // Kd
        glm::vec3{ 1.0f, 1.0f, 1.0f }, // Ks
        10.0f, // Ns/Shininess/the power the specularity is raised to
        // -snip-
    );

我怀疑这可能与glm::clamp. 如果我最后将我的代码更改为下面的代码,我会得到如下所示的调试渲染。

        if (result.x > 1.0f || result.y > 1.0f || result.z > 1.0f)
        {
            return glm::vec3{ 1.0f, 0.0f, 0.0f };
        }
        return glm::clamp(result, 0.0f, 1.0f);

调试渲染

这个形状看起来非常熟悉这枚戒指的轮廓。因此我怀疑这可能是与钳位有关的问题,但无数小时的调试并没有让我走得更远。

TL;DR 我的镜面反射有一个奇怪的“环”(见第一张图片),我想知道如何摆脱它。

4

0 回答 0