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.render.renderer.SimpleRenderer;
|
||||||
import eu.jonahbauer.raytracing.scene.*;
|
import eu.jonahbauer.raytracing.scene.*;
|
||||||
import eu.jonahbauer.raytracing.scene.hittable2d.Parallelogram;
|
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.hittable3d.Sphere;
|
||||||
import eu.jonahbauer.raytracing.scene.util.Hittables;
|
import eu.jonahbauer.raytracing.scene.util.Hittables;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -22,7 +23,7 @@ import java.util.Random;
|
|||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
var example = getCornellBox();
|
var example = getCornellBoxSmoke();
|
||||||
var scene = example.scene();
|
var scene = example.scene();
|
||||||
var camera = example.camera();
|
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() {
|
private static @NotNull Scene getSimpleScene() {
|
||||||
return new Scene(
|
return new Scene(
|
||||||
getSkyBox(),
|
getSkyBox(),
|
||||||
|
@ -11,7 +11,6 @@ public record Ray(@NotNull Vec3 origin, @NotNull Vec3 direction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull Vec3 at(double t) {
|
public @NotNull Vec3 at(double t) {
|
||||||
if (t < 0) throw new IllegalArgumentException("t must not be negative");
|
|
||||||
return new Vec3(
|
return new Vec3(
|
||||||
origin().x() + t * direction.x(),
|
origin().x() + t * direction.x(),
|
||||||
origin().y() + t * direction.y(),
|
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
|
boolean frontFace
|
||||||
) implements Comparable<HitResult> {
|
) implements Comparable<HitResult> {
|
||||||
public HitResult {
|
public HitResult {
|
||||||
if (t < 0 || !Double.isFinite(t)) throw new IllegalArgumentException("t must be non-negative");
|
|
||||||
Objects.requireNonNull(position, "position");
|
Objects.requireNonNull(position, "position");
|
||||||
normal = normal.unit();
|
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