Skip to content
Snippets Groups Projects
Commit bf18756a authored by Yoel's avatar Yoel
Browse files

Sphere intersection optimized

parent 17552fdc
No related branches found
No related tags found
No related merge requests found
...@@ -19,21 +19,17 @@ std::optional<cam::Hit> Sphere::intersect(const cam::Ray& r) const { ...@@ -19,21 +19,17 @@ std::optional<cam::Hit> Sphere::intersect(const cam::Ray& r) const {
float discrim = b * b - 4 * a * c; float discrim = b * b - 4 * a * c;
if (discrim >= 0) { if (discrim >= 0) {
float t1 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a); float t1 = (-b - sqrt(discrim)) / (2 * a);
if (r.in_range(t1)) { if (r.in_range(t1)) {
util::Vec3 t1HitPoint = r(t1); util::Vec3 t1HitPoint = r(t1);
float theta = acos(t1HitPoint.y() / radius);
float phi = M_PI + atan2(t1HitPoint.x(), t1HitPoint.z());
return std::optional<cam::Hit>({t1HitPoint, t1HitPoint, return std::optional<cam::Hit>({t1HitPoint, t1HitPoint,
texture_coordinates(t1HitPoint), t1, texture_coordinates(t1HitPoint), t1,
material}); material});
} else { } else {
float t2 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a); float t2 = (-b + sqrt(discrim)) / (2 * a);
if (r.in_range(t2)) { if (r.in_range(t2)) {
util::Vec3 t2HitPoint = r(t2); util::Vec3 t2HitPoint = r(t2);
float theta = acos(t2HitPoint.y() / radius);
float phi = M_PI + atan2(t2HitPoint.x(), t2HitPoint.z());
return std::optional<cam::Hit>({t2HitPoint, t2HitPoint, return std::optional<cam::Hit>({t2HitPoint, t2HitPoint,
texture_coordinates(t2HitPoint), texture_coordinates(t2HitPoint),
t2, material}); t2, material});
...@@ -74,10 +70,12 @@ util::Vec3 Sphere::calculateLightEmission(const util::SurfacePoint& p, ...@@ -74,10 +70,12 @@ util::Vec3 Sphere::calculateLightEmission(const util::SurfacePoint& p,
// the light in regard to the angle. // the light in regard to the angle.
// Uniform pdf of shape is 1/area, converting to pdf over solid angle is // Uniform pdf of shape is 1/area, converting to pdf over solid angle is
// pdf/(dot/length^2). // pdf/(dot/length^2).
// This is wrong. We just need the normal pdf, per area, as we do not sample
// with regard to a direction.
auto emission = p.emission(); auto emission = p.emission();
auto dot = std::max<float>(util::dot(p.normal(), d.normalize()), 0); auto dot = std::max<float>(util::dot(p.normal(), d.normalize()), 0);
auto area = 4 * M_PI * std::pow(radius, 2); auto area = 4 * M_PI * std::pow(radius, 2);
auto pdf = std::pow(d.length(), 2) / (dot * area); auto pdf = 1 / area;
return emission / pdf; return emission / pdf;
} }
} // namespace shapes } // namespace shapes
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment