add diffuse material
This commit is contained in:
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…
x
Reference in New Issue
Block a user