diff --git a/src/main/java/eu/jonahbauer/raytracing/Main.java b/src/main/java/eu/jonahbauer/raytracing/Main.java index 32d72ba..861a988 100644 --- a/src/main/java/eu/jonahbauer/raytracing/Main.java +++ b/src/main/java/eu/jonahbauer/raytracing/Main.java @@ -16,8 +16,8 @@ public class Main { var scene = new Scene( new Sphere(0, -100.5, 1, 100, new LambertianMaterial(new Color(0.8, 0.8, 0.0))), new Sphere(0, 0, 1.2, 0.5, new LambertianMaterial(new Color(0.1, 0.2, 0.5))), - new Sphere(-1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.8, 0.8))), - new Sphere(1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2))) + new Sphere(-1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.8, 0.8), 0.3)), + new Sphere(1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2), 1.0)) ); var camera = new Camera(512, 2, 16 / 9d); diff --git a/src/main/java/eu/jonahbauer/raytracing/material/MetallicMaterial.java b/src/main/java/eu/jonahbauer/raytracing/material/MetallicMaterial.java index f2fd97c..1ddcf72 100644 --- a/src/main/java/eu/jonahbauer/raytracing/material/MetallicMaterial.java +++ b/src/main/java/eu/jonahbauer/raytracing/material/MetallicMaterial.java @@ -1,6 +1,7 @@ package eu.jonahbauer.raytracing.material; import eu.jonahbauer.raytracing.math.Ray; +import eu.jonahbauer.raytracing.math.Vec3; import eu.jonahbauer.raytracing.render.Color; import eu.jonahbauer.raytracing.scene.HitResult; import org.jetbrains.annotations.NotNull; @@ -8,16 +9,23 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; import java.util.Optional; -public record MetallicMaterial(@NotNull Color albedo) implements Material { +public record MetallicMaterial(@NotNull Color albedo, double fuzz) implements Material { + + public MetallicMaterial(@NotNull Color albedo) { + this(albedo, 0); + } + public MetallicMaterial { Objects.requireNonNull(albedo, "albedo"); + if (fuzz < 0 || !Double.isFinite(fuzz)) throw new IllegalArgumentException("fuzz must be non-negative"); } @Override public @NotNull Optional scatter(@NotNull Ray ray, @NotNull HitResult hit) { - var direction = ray.direction(); - var normal = hit.normal(); - var newDirection = direction.minus(normal.times(2 * normal.times(direction))); + var newDirection = Vec3.reflect(ray.direction(), hit.normal()); + if (fuzz > 0) { + newDirection = newDirection.unit().plus(Vec3.random(true).times(fuzz)); + } return Optional.of(new ScatterResult(new Ray(hit.position(), newDirection), albedo)); } } diff --git a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java index fbd1713..0439bb3 100644 --- a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java +++ b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java @@ -27,6 +27,10 @@ public record Vec3(double x, double y, double z) { return unit ? random.unit() : random; } + public static @NotNull Vec3 reflect(@NotNull Vec3 vec, @NotNull Vec3 normal) { + return vec.minus(normal.times(2 * normal.times(vec))); + } + public @NotNull Vec3 plus(@NotNull Vec3 b) { return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z); }