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