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