add "final" scene

main
jbb01 6 months ago
parent bb326e82a6
commit c17b9aedf5

@ -2,6 +2,7 @@ package eu.jonahbauer.raytracing;
import eu.jonahbauer.raytracing.material.DielectricMaterial; import eu.jonahbauer.raytracing.material.DielectricMaterial;
import eu.jonahbauer.raytracing.material.LambertianMaterial; import eu.jonahbauer.raytracing.material.LambertianMaterial;
import eu.jonahbauer.raytracing.material.Material;
import eu.jonahbauer.raytracing.material.MetallicMaterial; import eu.jonahbauer.raytracing.material.MetallicMaterial;
import eu.jonahbauer.raytracing.math.Vec3; import eu.jonahbauer.raytracing.math.Vec3;
import eu.jonahbauer.raytracing.render.Camera; import eu.jonahbauer.raytracing.render.Camera;
@ -9,29 +10,28 @@ import eu.jonahbauer.raytracing.render.Color;
import eu.jonahbauer.raytracing.render.ImageFormat; import eu.jonahbauer.raytracing.render.ImageFormat;
import eu.jonahbauer.raytracing.render.canvas.LiveCanvas; import eu.jonahbauer.raytracing.render.canvas.LiveCanvas;
import eu.jonahbauer.raytracing.render.canvas.Image; import eu.jonahbauer.raytracing.render.canvas.Image;
import eu.jonahbauer.raytracing.scene.Hittable;
import eu.jonahbauer.raytracing.scene.Scene; import eu.jonahbauer.raytracing.scene.Scene;
import eu.jonahbauer.raytracing.scene.Sphere; import eu.jonahbauer.raytracing.scene.Sphere;
import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
public class Main { public class Main {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
var scene = new Scene( var scene = getScene();
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 DielectricMaterial(1.5)),
new Sphere(-1, 0, - 1, 0.4, new DielectricMaterial(1 / 1.5)),
new Sphere(1, 0, - 1, 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2), 1.0))
);
var camera = Camera.builder() var camera = Camera.builder()
.withImage(800, 450) .withImage(1200, 675)
.withPosition(new Vec3(-2, 2, 1)) .withPosition(new Vec3(13, 2, 3))
.withTarget(new Vec3(0, 0, -1)) .withTarget(new Vec3(0, 0, 0))
.withFieldOfView(Math.toRadians(20)) .withFieldOfView(Math.toRadians(20))
.withFocusDistance(3.4) .withFocusDistance(10.0)
.withBlurAngle(Math.toRadians(10)) .withBlurAngle(Math.toRadians(0.6))
.withSamplesPerPixel(500)
.withMaxDepth(50)
.build(); .build();
var image = new LiveCanvas(new Image(camera.getWidth(), camera.getHeight())); var image = new LiveCanvas(new Image(camera.getWidth(), camera.getHeight()));
@ -40,4 +40,40 @@ public class Main {
camera.render(scene, image); camera.render(scene, image);
ImageFormat.PNG.write(image, Path.of("scene-" + System.currentTimeMillis() + ".png")); ImageFormat.PNG.write(image, Path.of("scene-" + System.currentTimeMillis() + ".png"));
} }
private static @NotNull Scene getScene() {
var objects = new ArrayList<Hittable>();
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 * Math.random(), 0.2, b + 0.9 * Math.random());
if (Vec3.distance(center, new Vec3(4, 0.2, 0)) <= 0.9) continue;
Material material;
var rnd = Math.random();
if (rnd < 0.8) {
// diffuse
var albedo = Color.multiply(Color.random(), Color.random());
material = new LambertianMaterial(albedo);
} else if (rnd < 0.95) {
// metal
var albedo = Color.random(0.5, 1.0);
var fuzz = Math.random() * 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))));
return new Scene(objects);
}
} }

@ -50,6 +50,10 @@ public record Vec3(double x, double y, double z) {
return vec.plus(vxp.times(Math.sin(angle))).plus(vxvxp.times(1 - Math.cos(angle))); return vec.plus(vxp.times(Math.sin(angle))).plus(vxvxp.times(1 - Math.cos(angle)));
} }
public static double distance(@NotNull Vec3 a, @NotNull Vec3 b) {
return a.minus(b).length();
}
public @NotNull Vec3 plus(@NotNull Vec3 b) { public @NotNull Vec3 plus(@NotNull Vec3 b) {
return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z); return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z);
} }

@ -24,6 +24,19 @@ public record Color(double r, double g, double b) {
return new Color(a.r() * b.r(), a.g() * b.g(), a.b() * b.b()); return new Color(a.r() * b.r(), a.g() * b.g(), a.b() * b.b());
} }
public static @NotNull Color random() {
return new Color(Math.random(), Math.random(), Math.random());
}
public static @NotNull Color random(double min, double max) {
var span = max - min;
return new Color(
Math.fma(Math.random(), span, min),
Math.fma(Math.random(), span, min),
Math.fma(Math.random(), span, min)
);
}
public Color { public Color {
if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1) { if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1) {
throw new IllegalArgumentException("r, g and b must be in the range 0 to 1"); throw new IllegalArgumentException("r, g and b must be in the range 0 to 1");

Loading…
Cancel
Save