add dielectric material
This commit is contained in:
parent
ca769c56b2
commit
088263b344
@ -1,5 +1,6 @@
|
||||
package eu.jonahbauer.raytracing;
|
||||
|
||||
import eu.jonahbauer.raytracing.material.DielectricMaterial;
|
||||
import eu.jonahbauer.raytracing.material.LambertianMaterial;
|
||||
import eu.jonahbauer.raytracing.material.MetallicMaterial;
|
||||
import eu.jonahbauer.raytracing.render.Camera;
|
||||
@ -16,7 +17,7 @@ public class Main {
|
||||
var scene = new Scene(
|
||||
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(-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))
|
||||
);
|
||||
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)));
|
||||
}
|
||||
|
||||
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) {
|
||||
return new Vec3(this.x + b.x, this.y + b.y, this.z + b.z);
|
||||
}
|
||||
|
@ -10,7 +10,8 @@ public record HitResult(
|
||||
double t,
|
||||
@NotNull Vec3 position,
|
||||
@NotNull Vec3 normal,
|
||||
@NotNull Material material
|
||||
@NotNull Material material,
|
||||
boolean frontFace
|
||||
) implements Comparable<HitResult> {
|
||||
public HitResult {
|
||||
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();
|
||||
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user