add constant density mediums

main
jbb01 6 months ago
parent c002b8215a
commit 360fb2c990

@ -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(),

@ -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(),

@ -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()));
}
}

@ -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();
}

@ -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();
}
}
Loading…
Cancel
Save