add constant density mediums
parent
c002b8215a
commit
360fb2c990
@ -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()));
|
||||
}
|
||||
}
|
@ -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…
Reference in New Issue