From 3be855cffd9630fd3f68976e4234858c098bdd7a Mon Sep 17 00:00:00 2001 From: jbb01 <32650546+jbb01@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:11:32 +0200 Subject: [PATCH] add light sources --- .../java/eu/jonahbauer/raytracing/Main.java | 22 +++++++++++++++++-- .../jonahbauer/raytracing/render/Color.java | 4 ++++ .../render/material/DiffuseLight.java | 20 +++++++++++++++++ .../raytracing/render/material/Material.java | 4 ++++ .../render/renderer/SimpleRenderer.java | 4 +++- 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/main/java/eu/jonahbauer/raytracing/render/material/DiffuseLight.java diff --git a/src/main/java/eu/jonahbauer/raytracing/Main.java b/src/main/java/eu/jonahbauer/raytracing/Main.java index a13b6dd..19bea34 100644 --- a/src/main/java/eu/jonahbauer/raytracing/Main.java +++ b/src/main/java/eu/jonahbauer/raytracing/Main.java @@ -12,6 +12,7 @@ import eu.jonahbauer.raytracing.render.renderer.SimpleRenderer; import eu.jonahbauer.raytracing.scene.*; import eu.jonahbauer.raytracing.scene.hittable2d.Parallelogram; import eu.jonahbauer.raytracing.scene.hittable3d.Sphere; +import eu.jonahbauer.raytracing.scene.util.Hittables; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -22,12 +23,12 @@ import java.util.Random; public class Main { public static void main(String[] args) throws IOException { - var example = getSquares(); + var example = getLight(); var scene = example.scene(); var camera = example.camera(); var renderer = SimpleRenderer.builder() - .withSamplesPerPixel(500) + .withSamplesPerPixel(1000) .withMaxDepth(50) .withIterative(true) .build(); @@ -107,6 +108,23 @@ public class Main { ); } + private static @NotNull Example getLight() { + return new Example( + new Scene( + new Sphere(new Vec3(0, -1000, 0), 1000, new LambertianMaterial(new Color(0.2, 0.2, 0.2))), + new Sphere(new Vec3(0, 2, 0), 2, new LambertianMaterial(new Color(0.2, 0.2, 0.2))), + new Parallelogram(new Vec3(3, 1, -2), new Vec3(2, 0, 0), new Vec3(0, 2, 0), new DiffuseLight(new Color(4.0, 4.0, 4.0))), + new Sphere(new Vec3(0, 7, 0), 2, new DiffuseLight(new Color(4.0, 4.0, 4.0))) + ), + SimpleCamera.builder() + .withImage(400, 225) + .withFieldOfView(Math.toRadians(20)) + .withPosition(new Vec3(26, 3, 6)) + .withTarget(new Vec3(0, 2, 0)) + .build() + ); + } + private static @NotNull Scene getSimpleScene() { return new Scene( getSkyBox(), diff --git a/src/main/java/eu/jonahbauer/raytracing/render/Color.java b/src/main/java/eu/jonahbauer/raytracing/render/Color.java index af9311a..b33388b 100644 --- a/src/main/java/eu/jonahbauer/raytracing/render/Color.java +++ b/src/main/java/eu/jonahbauer/raytracing/render/Color.java @@ -25,6 +25,10 @@ public record Color(double r, double g, double b) { return new Color(a.r() * b.r(), a.g() * b.g(), a.b() * b.b()); } + public static @NotNull Color add(@NotNull Color a, @NotNull Color b) { + return new Color(a.r() + b.r(), a.g() + b.g(), a.b() + b.b()); + } + public static @NotNull Color random(@NotNull Random random) { return new Color(random.nextDouble(), random.nextDouble(), random.nextDouble()); } diff --git a/src/main/java/eu/jonahbauer/raytracing/render/material/DiffuseLight.java b/src/main/java/eu/jonahbauer/raytracing/render/material/DiffuseLight.java new file mode 100644 index 0000000..74ae62e --- /dev/null +++ b/src/main/java/eu/jonahbauer/raytracing/render/material/DiffuseLight.java @@ -0,0 +1,20 @@ +package eu.jonahbauer.raytracing.render.material; + +import eu.jonahbauer.raytracing.math.Ray; +import eu.jonahbauer.raytracing.render.Color; +import eu.jonahbauer.raytracing.scene.HitResult; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public record DiffuseLight(@NotNull Color emit) implements Material { + @Override + public @NotNull Optional scatter(@NotNull Ray ray, @NotNull HitResult hit) { + return Optional.empty(); + } + + @Override + public @NotNull Color emitted(@NotNull HitResult hit) { + return emit; + } +} diff --git a/src/main/java/eu/jonahbauer/raytracing/render/material/Material.java b/src/main/java/eu/jonahbauer/raytracing/render/material/Material.java index d3c18e1..955e5b1 100644 --- a/src/main/java/eu/jonahbauer/raytracing/render/material/Material.java +++ b/src/main/java/eu/jonahbauer/raytracing/render/material/Material.java @@ -12,6 +12,10 @@ public interface Material { @NotNull Optional scatter(@NotNull Ray ray, @NotNull HitResult hit); + default @NotNull Color emitted(@NotNull HitResult hit) { + return Color.BLACK; + } + record ScatterResult(@NotNull Ray ray, @NotNull Color attenuation) { public ScatterResult { Objects.requireNonNull(ray, "ray"); diff --git a/src/main/java/eu/jonahbauer/raytracing/render/renderer/SimpleRenderer.java b/src/main/java/eu/jonahbauer/raytracing/render/renderer/SimpleRenderer.java index 97ba91d..634a94d 100644 --- a/src/main/java/eu/jonahbauer/raytracing/render/renderer/SimpleRenderer.java +++ b/src/main/java/eu/jonahbauer/raytracing/render/renderer/SimpleRenderer.java @@ -92,9 +92,11 @@ public final class SimpleRenderer implements Renderer { if (optional.isPresent()) { var hit = optional.get(); var material = hit.material(); + var emitted = material.emitted(hit); return material.scatter(ray, hit) .map(scatter -> Color.multiply(scatter.attenuation(), getColor0(scene, scatter.ray(), depth - 1))) - .orElse(Color.BLACK); + .map(color -> Color.add(color, emitted)) + .orElse(emitted); } else { return scene.getBackgroundColor(ray); }