diff --git a/src/main/java/eu/jonahbauer/raytracing/Examples.java b/src/main/java/eu/jonahbauer/raytracing/Examples.java index 5c044af..1c06fb5 100644 --- a/src/main/java/eu/jonahbauer/raytracing/Examples.java +++ b/src/main/java/eu/jonahbauer/raytracing/Examples.java @@ -5,6 +5,7 @@ import eu.jonahbauer.raytracing.render.texture.CheckerTexture; import eu.jonahbauer.raytracing.render.texture.Color; import eu.jonahbauer.raytracing.render.camera.SimpleCamera; import eu.jonahbauer.raytracing.render.material.*; +import eu.jonahbauer.raytracing.render.texture.ImageTexture; import eu.jonahbauer.raytracing.scene.Hittable; import eu.jonahbauer.raytracing.scene.Scene; import eu.jonahbauer.raytracing.scene.SkyBox; @@ -32,6 +33,7 @@ public class Examples { register("CORNELL", Examples::getCornellBox); register("CORNELL_SMOKE", Examples::getCornellBoxSmoke); register("DIAGRAMM", Examples::getDiagramm); + register("EARTH", Examples::getEarth); } public static @NotNull IntFunction getByName(@NotNull String name) { @@ -255,6 +257,23 @@ public class Examples { ); } + public static @NotNull Example getEarth(int height) { + if (height <= 0) height = 450; + + return new Example( + new Scene( + getSkyBox(), + new Sphere(Vec3.ZERO, 2, new LambertianMaterial(new ImageTexture("/earthmap.jpg"))) + ), + SimpleCamera.builder() + .withImage(height * 16 / 9, height) + .withFieldOfView(Math.toRadians(20)) + .withPosition(new Vec3(12, 0, 0)) + .withTarget(Vec3.ZERO) + .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/render/canvas/Image.java b/src/main/java/eu/jonahbauer/raytracing/render/canvas/Image.java index 4ee3ee9..b8157f7 100644 --- a/src/main/java/eu/jonahbauer/raytracing/render/canvas/Image.java +++ b/src/main/java/eu/jonahbauer/raytracing/render/canvas/Image.java @@ -3,6 +3,7 @@ package eu.jonahbauer.raytracing.render.canvas; import eu.jonahbauer.raytracing.render.texture.Color; import org.jetbrains.annotations.NotNull; +import java.awt.image.BufferedImage; import java.util.Objects; public final class Image implements Canvas { @@ -21,6 +22,16 @@ public final class Image implements Canvas { this.data = new Color[height][width]; } + public Image(@NotNull BufferedImage image) { + this(image.getWidth(), image.getHeight()); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + this.data[y][x] = new Color(image.getRGB(x, y)); + } + } + } + @Override public int getWidth() { return width; diff --git a/src/main/java/eu/jonahbauer/raytracing/render/texture/ImageTexture.java b/src/main/java/eu/jonahbauer/raytracing/render/texture/ImageTexture.java new file mode 100644 index 0000000..35e54e6 --- /dev/null +++ b/src/main/java/eu/jonahbauer/raytracing/render/texture/ImageTexture.java @@ -0,0 +1,43 @@ +package eu.jonahbauer.raytracing.render.texture; + +import eu.jonahbauer.raytracing.math.Vec3; +import eu.jonahbauer.raytracing.render.canvas.Image; +import org.jetbrains.annotations.NotNull; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Objects; + +public record ImageTexture(@NotNull Image image) implements Texture { + + public ImageTexture { + Objects.requireNonNull(image, "image"); + } + + public ImageTexture(@NotNull BufferedImage image) { + this(new Image(image)); + } + + public ImageTexture(@NotNull String path) { + this(read(path)); + } + + private static @NotNull BufferedImage read(@NotNull String path) { + try (var in = Objects.requireNonNull(ImageTexture.class.getResourceAsStream(path))) { + return ImageIO.read(in); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + + @Override + public @NotNull Color get(double u, double v, @NotNull Vec3 p) { + u = Math.clamp(u, 0, 1); + v = 1 - Math.clamp(v, 0, 1); + int x = (int) (u * (image.getWidth() - 1)); + int y = (int) (v * (image.getHeight() - 1)); + return image.get(x, y); + } +} diff --git a/src/main/resources/earthmap.jpg b/src/main/resources/earthmap.jpg new file mode 100644 index 0000000..908c160 Binary files /dev/null and b/src/main/resources/earthmap.jpg differ