我正在使用 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;
}