add diffuse material

main
jbb01 6 months ago
parent 9d204f6aa4
commit d2ca6922ef

@ -14,7 +14,7 @@ public class Main {
new Sphere(0, 0, 1, 0.5), new Sphere(0, 0, 1, 0.5),
new Sphere(0, -100.5, 1, 100) 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); var image = camera.render(scene);
ImageIO.write(image, Path.of("scene-" + System.currentTimeMillis() + ".ppm")); ImageIO.write(image, Path.of("scene-" + System.currentTimeMillis() + ".ppm"));

@ -13,7 +13,20 @@ public record Vec3(double x, double y, double z) {
throw new IllegalArgumentException("x, y and z must be finite"); 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) { 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);
} }

@ -23,6 +23,7 @@ public final class Camera {
// antialiasing // antialiasing
private final int samplesPerPixel = 100; private final int samplesPerPixel = 100;
private final int maxDepth = 10;
// internal properties // internal properties
private final @NotNull Vec3 pixelU; private final @NotNull Vec3 pixelU;
@ -123,10 +124,23 @@ public final class Camera {
} }
private @NotNull Color getColor(@NotNull Scene scene, @NotNull Ray ray) { private @NotNull Color getColor(@NotNull Scene scene, @NotNull Ray ray) {
var result = scene.hit(ray, Range.NON_NEGATIVE); return getColor(scene, ray, maxDepth);
if (result.isPresent()) { }
var normal = result.get().normal();
return getNormalColor(normal); 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 { } else {
return getSkyboxColor(ray); return getSkyboxColor(ray);
} }

@ -3,9 +3,12 @@ package eu.jonahbauer.raytracing.scene;
import eu.jonahbauer.raytracing.math.Vec3; import eu.jonahbauer.raytracing.math.Vec3;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public record HitResult(double t, @NotNull Vec3 normal) implements Comparable<HitResult> { import java.util.Objects;
public record HitResult(double t, @NotNull Vec3 position, @NotNull Vec3 normal) implements Comparable<HitResult> {
public HitResult { public HitResult {
if (t < 0 || !Double.isFinite(t)) throw new IllegalArgumentException("t must be non-negative"); if (t < 0 || !Double.isFinite(t)) throw new IllegalArgumentException("t must be non-negative");
Objects.requireNonNull(position, "position");
normal = normal.unit(); normal = normal.unit();
} }

@ -36,7 +36,9 @@ public record Sphere(@NotNull Vec3 center, double radius) implements Hittable {
double t = (- h - sd) / a; double t = (- h - sd) / a;
if (!range.surrounds(t)) t = (- h + sd) / a; if (!range.surrounds(t)) t = (- h + sd) / a;
if (!range.surrounds(t)) return Optional.empty(); 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) { public @NotNull Sphere withCenter(@NotNull Vec3 center) {

Loading…
Cancel
Save