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, -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);
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");
}
}
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) {
return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z);
}

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

@ -3,9 +3,12 @@ package eu.jonahbauer.raytracing.scene;
import eu.jonahbauer.raytracing.math.Vec3;
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 {
if (t < 0 || !Double.isFinite(t)) throw new IllegalArgumentException("t must be non-negative");
Objects.requireNonNull(position, "position");
normal = normal.unit();
}

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

Loading…
Cancel
Save