From d2ca6922ef67752e6d9cd7a354331d8071be6c49 Mon Sep 17 00:00:00 2001 From: jbb01 <32650546+jbb01@users.noreply.github.com> Date: Sat, 3 Aug 2024 02:52:07 +0200 Subject: [PATCH] add diffuse material --- .../java/eu/jonahbauer/raytracing/Main.java | 2 +- .../eu/jonahbauer/raytracing/math/Vec3.java | 15 ++++++++++++- .../jonahbauer/raytracing/render/Camera.java | 22 +++++++++++++++---- .../raytracing/scene/HitResult.java | 5 ++++- .../jonahbauer/raytracing/scene/Sphere.java | 4 +++- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/jonahbauer/raytracing/Main.java b/src/main/java/eu/jonahbauer/raytracing/Main.java index b95a834..a9f3fbd 100644 --- a/src/main/java/eu/jonahbauer/raytracing/Main.java +++ b/src/main/java/eu/jonahbauer/raytracing/Main.java @@ -14,7 +14,7 @@ public class Main { new Sphere(0, 0, 1, 0.5), new Sphere(0, -100.5, 1, 100) ); - var camera = new Camera(256, 2, 16 / 9d); + var camera = new Camera(512, 2, 16 / 9d); var image = camera.render(scene); ImageIO.write(image, Path.of("scene-" + System.currentTimeMillis() + ".ppm")); diff --git a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java index 60f8ae4..580bd76 100644 --- a/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java +++ b/src/main/java/eu/jonahbauer/raytracing/math/Vec3.java @@ -13,7 +13,20 @@ public record Vec3(double x, double y, double z) { throw new IllegalArgumentException("x, y and z must be finite"); } } - + + public static @NotNull Vec3 random() { + return random(false); + } + + public static @NotNull Vec3 random(boolean unit) { + var random = new Vec3( + 2 * Math.random() - 1, + 2 * Math.random() - 1, + 2 * Math.random() - 1 + ); + return unit ? random.unit() : random; + } + public @NotNull Vec3 plus(@NotNull Vec3 b) { return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z); } diff --git a/src/main/java/eu/jonahbauer/raytracing/render/Camera.java b/src/main/java/eu/jonahbauer/raytracing/render/Camera.java index 775a972..71070f7 100644 --- a/src/main/java/eu/jonahbauer/raytracing/render/Camera.java +++ b/src/main/java/eu/jonahbauer/raytracing/render/Camera.java @@ -23,6 +23,7 @@ public final class Camera { // antialiasing private final int samplesPerPixel = 100; + private final int maxDepth = 10; // internal properties private final @NotNull Vec3 pixelU; @@ -123,10 +124,23 @@ public final class Camera { } private @NotNull Color getColor(@NotNull Scene scene, @NotNull Ray ray) { - var result = scene.hit(ray, Range.NON_NEGATIVE); - if (result.isPresent()) { - var normal = result.get().normal(); - return getNormalColor(normal); + return getColor(scene, ray, maxDepth); + } + + private @NotNull Color getColor(@NotNull Scene scene, @NotNull Ray ray, int depth) { + if (depth <= 0) return Color.BLACK; + + var optional = scene.hit(ray, Range.NON_NEGATIVE); + if (optional.isPresent()) { + var result = optional.get(); + + var newDirection = Vec3.random(true); + if (result.normal().times(newDirection) < 0) { + newDirection = newDirection.times(-1); + } + var scattered = new Ray(result.position(), newDirection); + + return Color.lerp(Color.BLACK, getColor(scene, scattered, depth - 1), 0.5); } else { return getSkyboxColor(ray); } diff --git a/src/main/java/eu/jonahbauer/raytracing/scene/HitResult.java b/src/main/java/eu/jonahbauer/raytracing/scene/HitResult.java index 4d23584..ef6d281 100644 --- a/src/main/java/eu/jonahbauer/raytracing/scene/HitResult.java +++ b/src/main/java/eu/jonahbauer/raytracing/scene/HitResult.java @@ -3,9 +3,12 @@ package eu.jonahbauer.raytracing.scene; import eu.jonahbauer.raytracing.math.Vec3; import org.jetbrains.annotations.NotNull; -public record HitResult(double t, @NotNull Vec3 normal) implements Comparable { +import java.util.Objects; + +public record HitResult(double t, @NotNull Vec3 position, @NotNull Vec3 normal) implements Comparable { public HitResult { if (t < 0 || !Double.isFinite(t)) throw new IllegalArgumentException("t must be non-negative"); + Objects.requireNonNull(position, "position"); normal = normal.unit(); } diff --git a/src/main/java/eu/jonahbauer/raytracing/scene/Sphere.java b/src/main/java/eu/jonahbauer/raytracing/scene/Sphere.java index a52d9bc..e136bb1 100644 --- a/src/main/java/eu/jonahbauer/raytracing/scene/Sphere.java +++ b/src/main/java/eu/jonahbauer/raytracing/scene/Sphere.java @@ -36,7 +36,9 @@ public record Sphere(@NotNull Vec3 center, double radius) implements Hittable { double t = (- h - sd) / a; if (!range.surrounds(t)) t = (- h + sd) / a; if (!range.surrounds(t)) return Optional.empty(); - return Optional.of(new HitResult(t, ray.at(t).minus(center))); + + var position = ray.at(t); + return Optional.of(new HitResult(t, position, position.minus(center))); } public @NotNull Sphere withCenter(@NotNull Vec3 center) {