add constant density mediums

This commit is contained in:
jbb01 2024-08-05 18:35:10 +02:00
parent c002b8215a
commit 360fb2c990
5 changed files with 92 additions and 3 deletions

View File

@ -11,6 +11,7 @@ import eu.jonahbauer.raytracing.render.material.*;
import eu.jonahbauer.raytracing.render.renderer.SimpleRenderer;
import eu.jonahbauer.raytracing.scene.*;
import eu.jonahbauer.raytracing.scene.hittable2d.Parallelogram;
import eu.jonahbauer.raytracing.scene.hittable3d.ConstantMedium;
import eu.jonahbauer.raytracing.scene.hittable3d.Sphere;
import eu.jonahbauer.raytracing.scene.util.Hittables;
import org.jetbrains.annotations.NotNull;
@ -22,7 +23,7 @@ import java.util.Random;
public class Main {
public static void main(String[] args) throws IOException {
var example = getCornellBox();
var example = getCornellBoxSmoke();
var scene = example.scene();
var camera = example.camera();
@ -150,6 +151,38 @@ public class Main {
);
}
private static @NotNull Example getCornellBoxSmoke() {
var red = new LambertianMaterial(new Color(.65, .05, .05));
var white = new LambertianMaterial(new Color(.73, .73, .73));
var green = new LambertianMaterial(new Color(.12, .45, .15));
var light = new DiffuseLight(new Color(7.0, 7.0, 7.0));
return new Example(
new Scene(
new Parallelogram(new Vec3(555, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), green),
new Parallelogram(new Vec3(0, 0, 0), new Vec3(0, 555, 0), new Vec3(0, 0, 555), red),
new Parallelogram(new Vec3(113, 554, 127), new Vec3(330, 0, 0), new Vec3(0, 0, 305), light),
new Parallelogram(new Vec3(0, 0, 0), new Vec3(555, 0 ,0), new Vec3(0, 0, 555), white),
new Parallelogram(new Vec3(555, 555, 555), new Vec3(-555, 0 ,0), new Vec3(0, 0, -555), white),
new Parallelogram(new Vec3(0, 0, 555), new Vec3(555, 0 ,0), new Vec3(0, 555, 0), white),
new ConstantMedium(
Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 330, 165), white).rotateY(Math.toRadians(15)).translate(new Vec3(265, 0, 295)),
0.01, new IsotropicMaterial(Color.BLACK)
),
new ConstantMedium(
Hittables.box(new Vec3(0, 0, 0), new Vec3(165, 165, 165), white).rotateY(Math.toRadians(-18)).translate(new Vec3(130, 0, 65)),
0.01, new IsotropicMaterial(Color.WHITE)
)
),
SimpleCamera.builder()
.withImage(600, 600)
.withFieldOfView(Math.toRadians(40))
.withPosition(new Vec3(278, 278, -800))
.withTarget(new Vec3(278, 278, 0))
.build()
);
}
private static @NotNull Scene getSimpleScene() {
return new Scene(
getSkyBox(),

View File

@ -11,7 +11,6 @@ public record Ray(@NotNull Vec3 origin, @NotNull Vec3 direction) {
}
public @NotNull Vec3 at(double t) {
if (t < 0) throw new IllegalArgumentException("t must not be negative");
return new Vec3(
origin().x() + t * direction.x(),
origin().y() + t * direction.y(),

View File

@ -0,0 +1,16 @@
package eu.jonahbauer.raytracing.render.material;
import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.math.Vec3;
import eu.jonahbauer.raytracing.render.Color;
import eu.jonahbauer.raytracing.scene.HitResult;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public record IsotropicMaterial(@NotNull Color albedo) implements Material{
@Override
public @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit) {
return Optional.of(new ScatterResult(new Ray(hit.position(), Vec3.random(true)), albedo()));
}
}

View File

@ -14,7 +14,6 @@ public record HitResult(
boolean frontFace
) 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();
}

View File

@ -0,0 +1,42 @@
package eu.jonahbauer.raytracing.scene.hittable3d;
import eu.jonahbauer.raytracing.math.BoundingBox;
import eu.jonahbauer.raytracing.math.Range;
import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.math.Vec3;
import eu.jonahbauer.raytracing.render.material.IsotropicMaterial;
import eu.jonahbauer.raytracing.scene.HitResult;
import eu.jonahbauer.raytracing.scene.Hittable;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public record ConstantMedium(@NotNull Hittable boundary, double density, @NotNull IsotropicMaterial material) implements Hittable {
@Override
public @NotNull Optional<HitResult> hit(@NotNull Ray ray, @NotNull Range range) {
var hit1 = boundary.hit(ray, Range.UNIVERSE);
if (hit1.isEmpty()) return Optional.empty();
var hit2 = boundary.hit(ray, new Range(hit1.get().t() + 0.0001, Double.POSITIVE_INFINITY));
if (hit2.isEmpty()) return Optional.empty();
var tmin = Math.max(range.min(), hit1.get().t());
var tmax = Math.min(range.max(), hit2.get().t());
if (tmin >= tmax) return Optional.empty();
if (tmin < 0) tmin = 0;
var length = ray.direction().length();
var distance = length * (tmax - tmin);
var hitDistance = - Math.log(Math.random()) / density;
if (hitDistance > distance) return Optional.empty();
var t = tmin + hitDistance / length;
return Optional.of(new HitResult(t, ray.at(t), Vec3.UNIT_X, material, true)); // arbitrary normal and frontFace
}
@Override
public @NotNull Optional<BoundingBox> getBoundingBox() {
return boundary().getBoundingBox();
}
}