diff --git a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java index 7213c96..20b8c4c 100644 --- a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java +++ b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java @@ -162,6 +162,10 @@ public record Vec3(double x, double y, double z) { ); } + public static double tripleProduct(@NotNull Vec3 a, @NotNull Vec3 b, @NotNull Vec3 c) { + return a.x * b.y * c.z + a.y * b.z * c.x + a.z * b.x * c.y - c.x * b.y * a.z - c.y * b.z * a.x - c.z * b.x * a.y; + } + public @NotNull Vec3 plus(double x, double y, double z) { return new Vec3(this.x + x, this.y + y, this.z + z); } @@ -229,9 +233,9 @@ public record Vec3(double x, double y, double z) { */ public @NotNull Vec3 cross(@NotNull Vec3 other) { return new Vec3( - this.y() * other.z() - other.y() * this.z(), - this.z() * other.x() - other.z() * this.x(), - this.x() * other.y() - other.x() * this.y() + Math.fma(this.y, other.z, - other.y * this.z), + Math.fma(this.z, other.x, - other.z * this.x), + Math.fma(this.x, other.y, - other.x * this.y) ); } diff --git a/src/main/java/eu/jonahbauer/raytracing/render/renderer/pdf/TargetingProbabilityDensityFunction.java b/src/main/java/eu/jonahbauer/raytracing/render/renderer/pdf/TargetingProbabilityDensityFunction.java index 4b2ed62..b3611d5 100644 --- a/src/main/java/eu/jonahbauer/raytracing/render/renderer/pdf/TargetingProbabilityDensityFunction.java +++ b/src/main/java/eu/jonahbauer/raytracing/render/renderer/pdf/TargetingProbabilityDensityFunction.java @@ -28,7 +28,7 @@ public final class TargetingProbabilityDensityFunction implements ProbabilityDen var sum = 0.0; for (var target : targets) { - sum += weight * target.getProbabilityDensity(origin, direction); + sum = Math.fma(weight, target.getProbabilityDensity(origin, direction), sum); } return sum; diff --git a/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Hittable2D.java b/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Hittable2D.java index 9af3860..d0cb42b 100644 --- a/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Hittable2D.java +++ b/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Hittable2D.java @@ -67,13 +67,21 @@ public abstract class Hittable2D implements Hittable { var position = ray.at(t); var p = position.minus(origin); - var alpha = w.times(p.cross(v)); - var beta = w.times(u.cross(p)); + var alpha = Vec3.tripleProduct(w, p, v); + var beta = Vec3.tripleProduct(w, u, p); if (!isInterior(alpha, beta)) return Double.NaN; return t; } + protected @NotNull Vec3 get(double alpha, double beta) { + return new Vec3( + Math.fma(beta, v.x(), Math.fma(alpha, u.x(), origin.x())), + Math.fma(beta, v.y(), Math.fma(alpha, u.y(), origin.y())), + Math.fma(beta, v.z(), Math.fma(alpha, u.z(), origin.z())) + ); + } + protected abstract boolean isInterior(double alpha, double beta); @Override diff --git a/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Parallelogram.java b/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Parallelogram.java index da77727..e5b8086 100644 --- a/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Parallelogram.java +++ b/src/main/java/eu/jonahbauer/raytracing/scene/hittable2d/Parallelogram.java @@ -1,7 +1,6 @@ package eu.jonahbauer.raytracing.scene.hittable2d; import eu.jonahbauer.raytracing.math.AABB; -import eu.jonahbauer.raytracing.math.Range; import eu.jonahbauer.raytracing.math.Ray; import eu.jonahbauer.raytracing.math.Vec3; import eu.jonahbauer.raytracing.render.material.Material; @@ -33,10 +32,11 @@ public final class Parallelogram extends Hittable2D implements Target { public double getProbabilityDensity(@NotNull Vec3 origin, @NotNull Vec3 direction) { if (Double.isNaN(hit0(new Ray(origin, direction), FORWARD))) return 0; - var a = this.origin.minus(origin).unit(); - var b = this.origin.plus(u).minus(origin).unit(); - var c = this.origin.plus(v).minus(origin).unit(); - var d = this.origin.plus(u).plus(v).minus(origin).unit(); + var o = this.origin.minus(origin); + var a = o.unit(); + var b = o.plus(u).unit(); + var c = o.plus(v).unit(); + var d = o.plus(u).plus(v).unit(); var angle = PdfUtil.getSolidAngle(a, b, d) + PdfUtil.getSolidAngle(c, b, d); return 1 / angle; } @@ -45,6 +45,6 @@ public final class Parallelogram extends Hittable2D implements Target { public @NotNull Vec3 getTargetingDirection(@NotNull Vec3 origin, @NotNull RandomGenerator random) { var alpha = random.nextDouble(); var beta = random.nextDouble(); - return this.origin.plus(u.times(alpha)).plus(v.times(beta)).minus(origin); + return get(alpha, beta).minus(origin); } } diff --git a/src/main/java/eu/jonahbauer/raytracing/scene/util/PdfUtil.java b/src/main/java/eu/jonahbauer/raytracing/scene/util/PdfUtil.java index 8f7b70f..739f06a 100644 --- a/src/main/java/eu/jonahbauer/raytracing/scene/util/PdfUtil.java +++ b/src/main/java/eu/jonahbauer/raytracing/scene/util/PdfUtil.java @@ -13,7 +13,7 @@ public final class PdfUtil { * must be unit vectors. */ public static double getSolidAngle(@NotNull Vec3 a, @NotNull Vec3 b, @NotNull Vec3 c) { - var angle = 2 * Math.atan(Math.abs(a.times(b.cross(c))) / (1 + a.times(b) + b.times(c) + c.times(a))); + var angle = 2 * Math.atan(Math.abs(Vec3.tripleProduct(a, b, c)) / (1 + a.times(b) + b.times(c) + c.times(a))); return angle < 0 ? 2 * Math.PI + angle : angle; } }