1

我正在使用 Phong 照明模型编写一个带有照明的简单光线追踪器。但问题是有一部分球体显示完全不同的颜色。例如,球体在this中应该只有绿色。

这个

我试图降低光强度,然后它以某种方式正确显示为这样

像这样

这是主射线的代码

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            Ray ray(gCamera);
            float x = iX + j * pSize;
            float y = iY - i * pSize;
            ray.v = vec3(x * scale, y * scale, 0) - gCamera;
            gPixels[i][j] = trace(ray);
        }
    }

这是交集的代码(在原点用球体进行测试,没有任何转换)

    double findIntersection(const Ray& ray) {
        dvec3 u = mXfmInverse * dvec4(ray.u, 1.0);
        dvec3 v = mXfmInverse * dvec4(ray.v, 0.0);

        double a = glm::dot(v, v);
        double b = 2 * glm::dot(u, v);
        double c = glm::dot(u, u) - 1;
        double delta = b * b - 4 * a * c;

        if (delta < 0) return -1;
        double root = sqrt(delta);
        double t0 = 0.5 * (-b - root) / a;
        if (t0 >= 0) return t0;
        double t1 = 0.5 * (-b + root) / a;
        return t1 >= 0 ? t1 : -1;
    }

并计算 Phong 照明

    Material material = ray.sphere->getMaterial();

    // diffuse
    dvec3 center = ray.sphere->getXfm() * vec4(0, 0, 0, 1);
    dvec3 normal = glm::normalize(hitPoint - center);
    dvec3 lightDir = glm::normalize(light.position - hitPoint);
    double lambertian = max(glm::dot(normal, lightDir), 0.0);

    // specular
    double specular = 0;
    if (lambertian > 0) {
        dvec3 viewDir = glm::normalize(-ray.v);
        dvec3 reflectDir = glm::reflect(-lightDir, normal);
        specular = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    }

    dvec3 color = lambertian * material.diffuse + specular * material.specular;
    return color * light.color;
}
4

0 回答 0