From 9175377ac434930200e6f4ab15fbe36b8251d62e Mon Sep 17 00:00:00 2001 From: jbb01 <32650546+jbb01@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:15:56 +0200 Subject: [PATCH] move examples to their own file --- .../eu/jonahbauer/raytracing/Example.java | 8 + .../eu/jonahbauer/raytracing/Examples.java | 208 +++++++++++++++++ .../java/eu/jonahbauer/raytracing/Main.java | 212 ++---------------- 3 files changed, 229 insertions(+), 199 deletions(-) create mode 100644 src/main/java/eu/jonahbauer/raytracing/Example.java create mode 100644 src/main/java/eu/jonahbauer/raytracing/Examples.java diff --git a/src/main/java/eu/jonahbauer/raytracing/Example.java b/src/main/java/eu/jonahbauer/raytracing/Example.java new file mode 100644 index 0000000..dac1fd1 --- /dev/null +++ b/src/main/java/eu/jonahbauer/raytracing/Example.java @@ -0,0 +1,8 @@ +package eu.jonahbauer.raytracing; + +import eu.jonahbauer.raytracing.render.camera.Camera; +import eu.jonahbauer.raytracing.scene.Scene; +import org.jetbrains.annotations.NotNull; + +public record Example(@NotNull Scene scene, @NotNull Camera camera) { +} diff --git a/src/main/java/eu/jonahbauer/raytracing/Examples.java b/src/main/java/eu/jonahbauer/raytracing/Examples.java new file mode 100644 index 0000000..58f58c9 --- /dev/null +++ b/src/main/java/eu/jonahbauer/raytracing/Examples.java @@ -0,0 +1,208 @@ +package eu.jonahbauer.raytracing; + +import eu.jonahbauer.raytracing.math.Vec3; +import eu.jonahbauer.raytracing.render.Color; +import eu.jonahbauer.raytracing.render.camera.SimpleCamera; +import eu.jonahbauer.raytracing.render.material.*; +import eu.jonahbauer.raytracing.scene.Hittable; +import eu.jonahbauer.raytracing.scene.Scene; +import eu.jonahbauer.raytracing.scene.SkyBox; +import eu.jonahbauer.raytracing.scene.hittable2d.Parallelogram; +import eu.jonahbauer.raytracing.scene.hittable3d.ConstantMedium; +import eu.jonahbauer.raytracing.scene.hittable3d.Sphere; +import eu.jonahbauer.raytracing.scene.util.Hittables; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.IntFunction; + +public class Examples { + private static final Map> REGISTRY = new HashMap<>(); + + private static void register(@NotNull String name, @NotNull IntFunction example) { + REGISTRY.put(name, example); + } + + static { + register("SIMPLE", Examples::getSimpleScene); + register("SPHERES", Examples::getSpheres); + register("SQUARES", Examples::getSquares); + register("LIGHT", Examples::getLight); + register("CORNELL", Examples::getCornellBox); + register("CORNELL_SMOKE", Examples::getCornellBoxSmoke); + } + + public static @NotNull IntFunction getByName(@NotNull String name) { + var out = REGISTRY.get(name); + if (out == null) throw new IllegalArgumentException("unknown example " + name + ", expected one of " + REGISTRY.keySet()); + return out; + } + + public static @NotNull Example getSimpleScene(int height) { + if (height <= 0) height = 675; + return new Example( + new Scene( + getSkyBox(), + new Sphere(new Vec3(0, -100.5, -1.0), 100.0, new LambertianMaterial(new Color(0.8, 0.8, 0.0))), + new Sphere(new Vec3(0, 0, -1.2), 0.5, new LambertianMaterial(new Color(0.1, 0.2, 0.5))), + new Sphere(new Vec3(-1.0, 0, -1.2), 0.5, new DielectricMaterial(1.5)), + new Sphere(new Vec3(-1.0, 0, -1.2), 0.4, new DielectricMaterial(1 / 1.5)), + new Sphere(new Vec3(1.0, 0, -1.2), 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2), 0.0)) + ), + SimpleCamera.builder() + .withImage(height * 16 / 9, height) + .build() + ); + } + + public static @NotNull Example getSpheres(int height) { + if (height <= 0) height = 675; + + var rng = new Random(1); + var objects = new ArrayList(); + objects.add(new Sphere(new Vec3(0, -1000, 0), 1000, new LambertianMaterial(new Color(0.5, 0.5, 0.5)))); + + for (int a = -11; a < 11; a++) { + for (int b = -11; b < 11; b++) { + var center = new Vec3(a + 0.9 * rng.nextDouble(), 0.2, b + 0.9 * rng.nextDouble()); + if (Vec3.distance(center, new Vec3(4, 0.2, 0)) <= 0.9) continue; + + Material material; + var rnd = rng.nextDouble(); + if (rnd < 0.8) { + // diffuse + var albedo = Color.multiply(Color.random(rng), Color.random(rng)); + material = new LambertianMaterial(albedo); + } else if (rnd < 0.95) { + // metal + var albedo = Color.random(rng, 0.5, 1.0); + var fuzz = rng.nextDouble() * 0.5; + material = new MetallicMaterial(albedo, fuzz); + } else { + // glass + material = new DielectricMaterial(1.5); + } + + objects.add(new Sphere(center, 0.2, material)); + } + } + + objects.add(new Sphere(new Vec3(0, 1, 0), 1.0, new DielectricMaterial(1.5))); + objects.add(new Sphere(new Vec3(-4, 1, 0), 1.0, new LambertianMaterial(new Color(0.4, 0.2, 0.1)))); + objects.add(new Sphere(new Vec3(4, 1, 0), 1.0, new MetallicMaterial(new Color(0.7, 0.6, 0.5)))); + + var camera = SimpleCamera.builder() + .withImage(height * 16 / 9, height) + .withPosition(new Vec3(13, 2, 3)) + .withTarget(new Vec3(0, 0, 0)) + .withFieldOfView(Math.toRadians(20)) + .withFocusDistance(10.0) + .withBlurAngle(Math.toRadians(0.6)) + .build(); + + return new Example(new Scene(getSkyBox(), objects), camera); + } + + public static @NotNull Example getSquares(int height) { + if (height <= 0) height = 600; + return new Example( + new Scene( + getSkyBox(), + new Parallelogram(new Vec3(-3, -2, 5), new Vec3(0, 0, -4), new Vec3(0, 4, 0), new LambertianMaterial(new Color(1.0, 0.2, 0.2))), + new Parallelogram(new Vec3(-2, -2, 0), new Vec3(4, 0, 0), new Vec3(0, 4, 0), new LambertianMaterial(new Color(0.2, 1.0, 0.2))), + new Parallelogram(new Vec3(3, -2, 1), new Vec3(0, 0, 4), new Vec3(0, 4, 0), new LambertianMaterial(new Color(0.2, 0.2, 1.0))), + new Parallelogram(new Vec3(-2, 3, 1), new Vec3(4, 0, 0), new Vec3(0, 0, 4), new LambertianMaterial(new Color(1.0, 0.5, 0.0))), + new Parallelogram(new Vec3(-2, -3, 5), new Vec3(4, 0, 0), new Vec3(0, 0, -4), new LambertianMaterial(new Color(0.2, 0.8, 0.8))) + ), + SimpleCamera.builder() + .withImage(height, height) + .withFieldOfView(Math.toRadians(80)) + .withPosition(new Vec3(0, 0, 9)) + .withTarget(new Vec3(0, 0, 0)) + .build() + ); + } + + public static @NotNull Example getLight(int height) { + if (height <= 0) height = 225; + 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(height * 16 / 9, height) + .withFieldOfView(Math.toRadians(20)) + .withPosition(new Vec3(26, 3, 6)) + .withTarget(new Vec3(0, 2, 0)) + .build() + ); + } + + public static @NotNull Example getCornellBox(int height) { + if (height <= 0) height = 600; + + var red = new LambertianMaterial(new Color(.65, .05, .05)); + var white = new LambertianMaterial(new Color(.73, .73, .73)); + var green = new LambertianMaterial(new Color(.12, .45, .15)); + var light = new DiffuseLight(new Color(15.0, 15.0, 15.0)); + + return new Example( + new Scene( + new Parallelogram(new Vec3(555, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), green), + new Parallelogram(new Vec3(0, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), red), + new Parallelogram(new Vec3(343, 554, 332), new Vec3(-130, 0, 0), new Vec3(0, 0, -105), light), + new Parallelogram(new Vec3(0, 0, 0), new Vec3(555, 0, 0), new Vec3(0, 0, 555), white), + new Parallelogram(new Vec3(555, 555, 555), new Vec3(-555, 0, 0), new Vec3(0, 0, -555), white), + new Parallelogram(new Vec3(0, 0, 555), new Vec3(555, 0, 0), new Vec3(0, 555, 0), white), + Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 330, 165), white).rotateY(Math.toRadians(15)).translate(new Vec3(265, 0, 295)), + Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 165, 165), white).rotateY(Math.toRadians(-18)).translate(new Vec3(130, 0, 65)) + ), + SimpleCamera.builder() + .withImage(height, height) + .withFieldOfView(Math.toRadians(40)) + .withPosition(new Vec3(278, 278, -800)) + .withTarget(new Vec3(278, 278, 0)) + .build() + ); + } + + public static @NotNull Example getCornellBoxSmoke(int height) { + if (height <= 0) height = 600; + var red = new LambertianMaterial(new Color(.65, .05, .05)); + var white = new LambertianMaterial(new Color(.73, .73, .73)); + var green = new LambertianMaterial(new Color(.12, .45, .15)); + var light = new DiffuseLight(new Color(7.0, 7.0, 7.0)); + + return new Example( + new Scene( + new Parallelogram(new Vec3(555, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), green), + new Parallelogram(new Vec3(0, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), red), + new Parallelogram(new Vec3(113, 554, 127), new Vec3(330, 0, 0), new Vec3(0, 0, 305), light), + new Parallelogram(new Vec3(0, 0, 0), new Vec3(555, 0, 0), new Vec3(0, 0, 555), white), + new Parallelogram(new Vec3(555, 555, 555), new Vec3(-555, 0, 0), new Vec3(0, 0, -555), white), + new Parallelogram(new Vec3(0, 0, 555), new Vec3(555, 0, 0), new Vec3(0, 555, 0), white), + new ConstantMedium( + Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 330, 165), white).rotateY(Math.toRadians(15)).translate(new Vec3(265, 0, 295)), + 0.01, new IsotropicMaterial(Color.BLACK) + ), + new ConstantMedium( + Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 165, 165), white).rotateY(Math.toRadians(-18)).translate(new Vec3(130, 0, 65)), + 0.01, new IsotropicMaterial(Color.WHITE) + ) + ), + SimpleCamera.builder() + .withImage(height, height) + .withFieldOfView(Math.toRadians(40)) + .withPosition(new Vec3(278, 278, -800)) + .withTarget(new Vec3(278, 278, 0)) + .build() + ); + } + + private static @NotNull SkyBox getSkyBox() { + return SkyBox.gradient(new Color(0.5, 0.7, 1.0), Color.WHITE); + } +} diff --git a/src/main/java/eu/jonahbauer/raytracing/Main.java b/src/main/java/eu/jonahbauer/raytracing/Main.java index 5de8a45..8111102 100644 --- a/src/main/java/eu/jonahbauer/raytracing/Main.java +++ b/src/main/java/eu/jonahbauer/raytracing/Main.java @@ -1,29 +1,15 @@ package eu.jonahbauer.raytracing; -import eu.jonahbauer.raytracing.math.Vec3; -import eu.jonahbauer.raytracing.render.Color; import eu.jonahbauer.raytracing.render.ImageFormat; -import eu.jonahbauer.raytracing.render.camera.Camera; -import eu.jonahbauer.raytracing.render.camera.SimpleCamera; import eu.jonahbauer.raytracing.render.canvas.Canvas; import eu.jonahbauer.raytracing.render.canvas.Image; import eu.jonahbauer.raytracing.render.canvas.LiveCanvas; -import eu.jonahbauer.raytracing.render.material.*; import eu.jonahbauer.raytracing.render.renderer.SimpleRenderer; -import eu.jonahbauer.raytracing.scene.Hittable; -import eu.jonahbauer.raytracing.scene.Scene; -import eu.jonahbauer.raytracing.scene.SkyBox; -import eu.jonahbauer.raytracing.scene.hittable2d.Parallelogram; -import eu.jonahbauer.raytracing.scene.hittable3d.ConstantMedium; -import eu.jonahbauer.raytracing.scene.hittable3d.Sphere; -import eu.jonahbauer.raytracing.scene.util.Hittables; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Random; import java.util.function.IntFunction; public class Main { @@ -37,6 +23,7 @@ public class Main { .withSamplesPerPixel(config.samples) .withMaxDepth(config.depth) .withIterative(config.iterative) + .withParallel(config.parallel) .build(); Canvas canvas; @@ -55,13 +42,13 @@ public class Main { ImageFormat.PNG.write(canvas, config.path); } - private record Config(@NotNull Example example, @NotNull Path path, boolean preview, boolean iterative, int samples, int depth) { - + private record Config(@NotNull Example example, @NotNull Path path, boolean preview, boolean iterative, boolean parallel, int samples, int depth) { public static @NotNull Config parse(@NotNull String @NotNull[] args) { IntFunction example = null; Path path = null; boolean preview = true; boolean iterative = false; + boolean parallel = false; int samples = 1000; int depth = 50; int height = -1; @@ -80,6 +67,8 @@ public class Main { case "--no-preview" -> preview = false; case "--iterative" -> iterative = true; case "--no-iterative" -> iterative = false; + case "--parallel" -> parallel = true; + case "--no-parallel" -> parallel = false; case "--samples" -> { if (i + 1 == args.length) throw fail("missing value for parameter --samples"); try { @@ -107,22 +96,20 @@ public class Main { throw fail("value " + args[i] + " is not a valid integer"); } } - case String str when !str.startsWith("-") -> example = switch (str) { - case "SIMPLE" -> Examples::getSimpleScene; - case "SPHERES" -> Examples::getSpheres; - case "SQUARES" -> Examples::getSquares; - case "LIGHT" -> Examples::getLight; - case "CORNELL" -> Examples::getCornellBox; - case "CORNELL_SMOKE" -> Examples::getCornellBoxSmoke; - default -> throw fail("unknown example " + str + ", expected one of SIMPLE, SPHERES, SQUARES, LIGHT, CORNELL or CORNELL_SMOKE"); - }; + case String str when !str.startsWith("-") -> { + try { + example = Examples.getByName(str); + } catch (IllegalArgumentException ex) { + throw fail(ex.getMessage()); + } + } default -> throw fail("unknown option " + args[i]); } } if (example == null) example = Examples::getCornellBoxSmoke; if (path == null) path = Path.of("scene-" + System.currentTimeMillis() + ".png"); - return new Config(example.apply(height), path, preview, iterative, samples, depth); + return new Config(example.apply(height), path, preview, iterative, parallel, samples, depth); } private static @NotNull RuntimeException fail(@NotNull String message) { @@ -130,178 +117,5 @@ public class Main { System.exit(1); return new RuntimeException(); } - - } - - private static class Examples { - public static @NotNull Example getSimpleScene(int height) { - if (height <= 0) height = 675; - return new Example( - new Scene( - getSkyBox(), - new Sphere(new Vec3(0, -100.5, -1.0), 100.0, new LambertianMaterial(new Color(0.8, 0.8, 0.0))), - new Sphere(new Vec3(0, 0, -1.2), 0.5, new LambertianMaterial(new Color(0.1, 0.2, 0.5))), - new Sphere(new Vec3(-1.0, 0, -1.2), 0.5, new DielectricMaterial(1.5)), - new Sphere(new Vec3(-1.0, 0, -1.2), 0.4, new DielectricMaterial(1 / 1.5)), - new Sphere(new Vec3(1.0, 0, -1.2), 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2), 0.0)) - ), - SimpleCamera.builder() - .withImage(height * 16 / 9, height) - .build() - ); - } - - public static @NotNull Example getSpheres(int height) { - if (height <= 0) height = 675; - - var rng = new Random(1); - var objects = new ArrayList(); - objects.add(new Sphere(new Vec3(0, -1000, 0), 1000, new LambertianMaterial(new Color(0.5, 0.5, 0.5)))); - - for (int a = -11; a < 11; a++) { - for (int b = -11; b < 11; b++) { - var center = new Vec3(a + 0.9 * rng.nextDouble(), 0.2, b + 0.9 * rng.nextDouble()); - if (Vec3.distance(center, new Vec3(4, 0.2, 0)) <= 0.9) continue; - - Material material; - var rnd = rng.nextDouble(); - if (rnd < 0.8) { - // diffuse - var albedo = Color.multiply(Color.random(rng), Color.random(rng)); - material = new LambertianMaterial(albedo); - } else if (rnd < 0.95) { - // metal - var albedo = Color.random(rng, 0.5, 1.0); - var fuzz = rng.nextDouble() * 0.5; - material = new MetallicMaterial(albedo, fuzz); - } else { - // glass - material = new DielectricMaterial(1.5); - } - - objects.add(new Sphere(center, 0.2, material)); - } - } - - objects.add(new Sphere(new Vec3(0, 1, 0), 1.0, new DielectricMaterial(1.5))); - objects.add(new Sphere(new Vec3(-4, 1, 0), 1.0, new LambertianMaterial(new Color(0.4, 0.2, 0.1)))); - objects.add(new Sphere(new Vec3(4, 1, 0), 1.0, new MetallicMaterial(new Color(0.7, 0.6, 0.5)))); - - var camera = SimpleCamera.builder() - .withImage(height * 16 / 9, height) - .withPosition(new Vec3(13, 2, 3)) - .withTarget(new Vec3(0, 0, 0)) - .withFieldOfView(Math.toRadians(20)) - .withFocusDistance(10.0) - .withBlurAngle(Math.toRadians(0.6)) - .build(); - - return new Example(new Scene(getSkyBox(), objects), camera); - } - - public static @NotNull Example getSquares(int height) { - if (height <= 0) height = 600; - return new Example( - new Scene( - getSkyBox(), - new Parallelogram(new Vec3(-3, -2, 5), new Vec3(0, 0, -4), new Vec3(0, 4, 0), new LambertianMaterial(new Color(1.0, 0.2, 0.2))), - new Parallelogram(new Vec3(-2, -2, 0), new Vec3(4, 0, 0), new Vec3(0, 4, 0), new LambertianMaterial(new Color(0.2, 1.0, 0.2))), - new Parallelogram(new Vec3(3, -2, 1), new Vec3(0, 0, 4), new Vec3(0, 4, 0), new LambertianMaterial(new Color(0.2, 0.2, 1.0))), - new Parallelogram(new Vec3(-2, 3, 1), new Vec3(4, 0, 0), new Vec3(0, 0, 4), new LambertianMaterial(new Color(1.0, 0.5, 0.0))), - new Parallelogram(new Vec3(-2, -3, 5), new Vec3(4, 0, 0), new Vec3(0, 0, -4), new LambertianMaterial(new Color(0.2, 0.8, 0.8))) - ), - SimpleCamera.builder() - .withImage(height, height) - .withFieldOfView(Math.toRadians(80)) - .withPosition(new Vec3(0, 0, 9)) - .withTarget(new Vec3(0, 0, 0)) - .build() - ); - } - - public static @NotNull Example getLight(int height) { - if (height <= 0) height = 225; - 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(height * 16 / 9, height) - .withFieldOfView(Math.toRadians(20)) - .withPosition(new Vec3(26, 3, 6)) - .withTarget(new Vec3(0, 2, 0)) - .build() - ); - } - - public static @NotNull Example getCornellBox(int height) { - if (height <= 0) height = 600; - - var red = new LambertianMaterial(new Color(.65, .05, .05)); - var white = new LambertianMaterial(new Color(.73, .73, .73)); - var green = new LambertianMaterial(new Color(.12, .45, .15)); - var light = new DiffuseLight(new Color(15.0, 15.0, 15.0)); - - return new Example( - new Scene( - new Parallelogram(new Vec3(555, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), green), - new Parallelogram(new Vec3(0, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), red), - new Parallelogram(new Vec3(343, 554, 332), new Vec3(-130, 0, 0), new Vec3(0, 0, -105), light), - new Parallelogram(new Vec3(0, 0, 0), new Vec3(555, 0 ,0), new Vec3(0, 0, 555), white), - new Parallelogram(new Vec3(555, 555, 555), new Vec3(-555, 0 ,0), new Vec3(0, 0, -555), white), - new Parallelogram(new Vec3(0, 0, 555), new Vec3(555, 0 ,0), new Vec3(0, 555, 0), white), - Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 330, 165), white).rotateY(Math.toRadians(15)).translate(new Vec3(265, 0, 295)), - Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 165, 165), white).rotateY(Math.toRadians(-18)).translate(new Vec3(130, 0, 65)) - ), - SimpleCamera.builder() - .withImage(height, height) - .withFieldOfView(Math.toRadians(40)) - .withPosition(new Vec3(278, 278, -800)) - .withTarget(new Vec3(278, 278, 0)) - .build() - ); - } - - public static @NotNull Example getCornellBoxSmoke(int height) { - if (height <= 0) height = 600; - var red = new LambertianMaterial(new Color(.65, .05, .05)); - var white = new LambertianMaterial(new Color(.73, .73, .73)); - var green = new LambertianMaterial(new Color(.12, .45, .15)); - var light = new DiffuseLight(new Color(7.0, 7.0, 7.0)); - - return new Example( - new Scene( - new Parallelogram(new Vec3(555, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), green), - new Parallelogram(new Vec3(0, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), red), - new Parallelogram(new Vec3(113, 554, 127), new Vec3(330, 0, 0), new Vec3(0, 0, 305), light), - new Parallelogram(new Vec3(0, 0, 0), new Vec3(555, 0 ,0), new Vec3(0, 0, 555), white), - new Parallelogram(new Vec3(555, 555, 555), new Vec3(-555, 0 ,0), new Vec3(0, 0, -555), white), - new Parallelogram(new Vec3(0, 0, 555), new Vec3(555, 0 ,0), new Vec3(0, 555, 0), white), - new ConstantMedium( - Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 330, 165), white).rotateY(Math.toRadians(15)).translate(new Vec3(265, 0, 295)), - 0.01, new IsotropicMaterial(Color.BLACK) - ), - new ConstantMedium( - Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 165, 165), white).rotateY(Math.toRadians(-18)).translate(new Vec3(130, 0, 65)), - 0.01, new IsotropicMaterial(Color.WHITE) - ) - ), - SimpleCamera.builder() - .withImage(height, height) - .withFieldOfView(Math.toRadians(40)) - .withPosition(new Vec3(278, 278, -800)) - .withTarget(new Vec3(278, 278, 0)) - .build() - ); - } - - private static @NotNull SkyBox getSkyBox() { - return SkyBox.gradient(new Color(0.5, 0.7, 1.0), Color.WHITE); - } } - - private record Example(@NotNull Scene scene, @NotNull Camera camera) {} } \ No newline at end of file