add dielectric material

main
jbb01 6 months ago
parent ca769c56b2
commit 088263b344

@ -1,5 +1,6 @@
package eu.jonahbauer.raytracing; package eu.jonahbauer.raytracing;
import eu.jonahbauer.raytracing.material.DielectricMaterial;
import eu.jonahbauer.raytracing.material.LambertianMaterial; import eu.jonahbauer.raytracing.material.LambertianMaterial;
import eu.jonahbauer.raytracing.material.MetallicMaterial; import eu.jonahbauer.raytracing.material.MetallicMaterial;
import eu.jonahbauer.raytracing.render.Camera; import eu.jonahbauer.raytracing.render.Camera;
@ -16,7 +17,7 @@ public class Main {
var scene = new Scene( var scene = new Scene(
new Sphere(0, -100.5, 1, 100, new LambertianMaterial(new Color(0.8, 0.8, 0.0))), new Sphere(0, -100.5, 1, 100, new LambertianMaterial(new Color(0.8, 0.8, 0.0))),
new Sphere(0, 0, 1.2, 0.5, new LambertianMaterial(new Color(0.1, 0.2, 0.5))), new Sphere(0, 0, 1.2, 0.5, new LambertianMaterial(new Color(0.1, 0.2, 0.5))),
new Sphere(-1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.8, 0.8), 0.3)), new Sphere(-1, 0, 1, 0.5, new DielectricMaterial(1.5)),
new Sphere(1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2), 1.0)) new Sphere(1, 0, 1, 0.5, new MetallicMaterial(new Color(0.8, 0.6, 0.2), 1.0))
); );
var camera = new Camera(512, 2, 16 / 9d); var camera = new Camera(512, 2, 16 / 9d);

@ -0,0 +1,18 @@
package eu.jonahbauer.raytracing.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 DielectricMaterial(double refractionIndex) implements Material {
@Override
public @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit) {
var ri = hit.frontFace() ? (1 / refractionIndex) : refractionIndex;
var refracted = Vec3.refract(ray.direction(), hit.normal(), ri);
return Optional.of(new ScatterResult(new Ray(hit.position(), refracted), Color.WHITE));
}
}

@ -31,6 +31,14 @@ public record Vec3(double x, double y, double z) {
return vec.minus(normal.times(2 * normal.times(vec))); return vec.minus(normal.times(2 * normal.times(vec)));
} }
public static @NotNull Vec3 refract(@NotNull Vec3 vec, @NotNull Vec3 normal, double index) {
vec = vec.unit();
var cosTheta = Math.min(- vec.times(normal), 1.0);
var rOutPerp = vec.plus(normal.times(cosTheta)).times(index);
var rOutParallel = normal.times(- Math.sqrt(Math.abs(1 - rOutPerp.squared())));
return rOutPerp.plus(rOutParallel);
}
public @NotNull Vec3 plus(@NotNull Vec3 b) { public @NotNull Vec3 plus(@NotNull Vec3 b) {
return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z); return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z);
} }

@ -10,7 +10,8 @@ public record HitResult(
double t, double t,
@NotNull Vec3 position, @NotNull Vec3 position,
@NotNull Vec3 normal, @NotNull Vec3 normal,
@NotNull Material material @NotNull Material material,
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"); if (t < 0 || !Double.isFinite(t)) throw new IllegalArgumentException("t must be non-negative");

@ -39,7 +39,9 @@ public record Sphere(@NotNull Vec3 center, double radius, @NotNull Material mate
if (!range.surrounds(t)) return Optional.empty(); if (!range.surrounds(t)) return Optional.empty();
var position = ray.at(t); var position = ray.at(t);
return Optional.of(new HitResult(t, position, position.minus(center), material)); var normal = position.minus(center);
var frontFace = normal.times(ray.direction()) < 0;
return Optional.of(new HitResult(t, position, frontFace ? normal : normal.times(-1), material, frontFace));
} }
public @NotNull Sphere withCenter(@NotNull Vec3 center) { public @NotNull Sphere withCenter(@NotNull Vec3 center) {

Loading…
Cancel
Save