《Ray Tracing in One Weekend》全内反射光线追踪问题求助
《Ray Tracing in One Weekend》11.3节全内反射实现问题
我正在跟随《Ray Tracing in One Weekend》一书学习,在11.3节全内反射(Total internal reflection)部分遇到问题。生成的图像如下:

以下是球体相交检测代码,返回std::optional<Intersection>实例或std::nullopt:
std::optional<Intersection> Sphere::intersect(const Ray& r, double tMin, double tMax) const { vec o_c = this->center - r.origin(); auto a = r.direction().length_squared() () auto b = dot(r.direction(), o_c); auto c = o_c.length_squared() - radius * radius; auto d = b * b - a * c; // at^2 + tb + c = 0 not real solution if (d < 0) { return std::nullopt; } // Verify root in [tMin, tMax] double dSqrt = std::sqrt(d); double root = (b - dSqrt) / a; if (root < tMin || root > tMax) { root = (b + dSqrt) / a; if (root < tMin || root > tMax) return std::nullopt; } Intersection i; i.t = root; i.point = r(i.t); i.normal = unit_vector(i.point - center); i.material = material; return i; };
以下是折射计算代码:
inline vec refraction(const vec& v, const vec& normal, double refraction_index) { vec rparal{ .0, .0, .0 }; vec rperp{ .0, .0, .0 }; bool front_face = (dot(v, normal) < 0); double ri = front_face ? 1.0 / refraction_index : refraction_index; vec outward_normal = front_face ? normal : -normal; double cos_tita = fmin(dot(-v, outward_normal ), 1.0); double sen_tita = sqrt(1 - cos_tita * cos_tita); if (ri * sen_tita > 1) { return reflect(v, outward_normal); } rperp = ri * (v + (dot(-v, outward_normal) * outward_normal)); rparal = (-sqrt(abs(1 - rperp.length_squared()))) * outward_normal; return rparal + rperp; };
以下是color_ray代码:
color color_ray(const Ray& r, int deep, const Geometry& g) { if (deep <= 0) return color(0, 0, 0); auto i = g.intersect(r, 0.001, infinity); if (i) { color intensity; // Check if the material is reflective if (i->material->reflective) { vec reflectedVector = reflect(unit_vector(r.direction()), i->normal) + (i->material->coef_Reflective * vec::random_Unit_vector()); Ray reflected_Ray = Ray(i->point, reflectedVector); intensity = i->material->DifuseColor * color_ray(reflected_Ray, deep - 1, g); // Check if the material is refractive } else if (i->material->refractive) { vec refractedVector = refraction(unit_vector(r.direction()), i->normal, i->material>refraction_index); Ray refracted_Ray = Ray(i->point, refractedVector); intensity = color_ray(refracted_Ray , deep - 1, g); } else { intensity = i->material->DifuseColor * color_ray(Ray(i->point, i->normal + vec::randomUnitVector()), deep - 1, g); } return intensity; } vec unit_direction = unit_vector(r.direction()); auto a = 0.5 * (unit_direction .y() + 1); return (1.0 - a) * color(1.0, 1.0, 1.0) + a * color(0.5, 0.7, 1.0); };
预期得到的图像如下:

如需更多信息请告知,感谢帮助 :)
内容的提问来源于stack exchange,提问作者Lautaro10263
相关产品推荐
相关产品推荐

