allow boxes to have different materials on each side
This commit is contained in:
parent
c91baf9e0c
commit
a22b1cb238
@ -1,5 +1,6 @@
|
||||
package eu.jonahbauer.raytracing;
|
||||
|
||||
import eu.jonahbauer.raytracing.math.AABB;
|
||||
import eu.jonahbauer.raytracing.math.Vec3;
|
||||
import eu.jonahbauer.raytracing.render.texture.CheckerTexture;
|
||||
import eu.jonahbauer.raytracing.render.texture.Color;
|
||||
@ -162,12 +163,11 @@ public class Examples {
|
||||
|
||||
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 Box(
|
||||
new AABB(new Vec3(0, 0, 0), new Vec3(555, 555, 555)),
|
||||
white, white, red, green, white, null
|
||||
),
|
||||
new Parallelogram(new Vec3(343, 554, 332), new Vec3(-130, 0, 0), new Vec3(0, 0, -105), 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 Box(new Vec3(0, 0, 0), new Vec3(165, 330, 165), white).rotateY(Math.toRadians(15)).translate(new Vec3(265, 0, 295)),
|
||||
new Box(new Vec3(0, 0, 0), new Vec3(165, 165, 165), white).rotateY(Math.toRadians(-18)).translate(new Vec3(130, 0, 65))
|
||||
),
|
||||
@ -189,12 +189,11 @@ public class Examples {
|
||||
|
||||
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 Box(
|
||||
new AABB(new Vec3(0, 0, 0), new Vec3(555, 555, 555)),
|
||||
white, white, red, green, white, null
|
||||
),
|
||||
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(
|
||||
new 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)
|
||||
|
@ -8,21 +8,33 @@ import eu.jonahbauer.raytracing.render.material.Material;
|
||||
import eu.jonahbauer.raytracing.scene.HitResult;
|
||||
import eu.jonahbauer.raytracing.scene.Hittable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public record Box(@NotNull AABB box, @NotNull Material material) implements Hittable {
|
||||
|
||||
public Box {
|
||||
Objects.requireNonNull(box, "box");
|
||||
Objects.requireNonNull(material, "material");
|
||||
}
|
||||
public final class Box implements Hittable {
|
||||
private final @NotNull AABB box;
|
||||
private final @Nullable Material @NotNull[] materials;
|
||||
|
||||
public Box(@NotNull Vec3 a, @NotNull Vec3 b, @NotNull Material material) {
|
||||
this(new AABB(a, b), material);
|
||||
}
|
||||
|
||||
public Box(@NotNull AABB box, @NotNull Material material) {
|
||||
this(box, Objects.requireNonNull(material, "material"), material, material, material, material, material);
|
||||
}
|
||||
|
||||
public Box(
|
||||
@NotNull AABB box,
|
||||
@Nullable Material top, @Nullable Material bottom,
|
||||
@Nullable Material left, @Nullable Material right,
|
||||
@Nullable Material front, @Nullable Material back
|
||||
) {
|
||||
this.box = Objects.requireNonNull(box, "box");
|
||||
this.materials = new Material[] { left, bottom, back, right, top, front };
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<HitResult> hit(@NotNull Ray ray, @NotNull Range range) {
|
||||
// based on AABB#hit with additional detection of the side hit
|
||||
@ -70,22 +82,29 @@ public record Box(@NotNull AABB box, @NotNull Material material) implements Hitt
|
||||
}
|
||||
|
||||
private @NotNull Optional<HitResult> hit0(double tmin, double tmax, @NotNull Side entry, @NotNull Side exit, @NotNull Ray ray, @NotNull Range range) {
|
||||
boolean frontFace;
|
||||
double t;
|
||||
if (range.surrounds(tmin)) {
|
||||
frontFace = true;
|
||||
Side side;
|
||||
boolean frontFace;
|
||||
Material material;
|
||||
Vec3 normal;
|
||||
if (range.surrounds(tmin) && materials[entry.ordinal()] != null) {
|
||||
t = tmin;
|
||||
} else if (range.surrounds(tmax)) {
|
||||
frontFace = false;
|
||||
side = entry;
|
||||
frontFace = true;
|
||||
material = materials[side.ordinal()];
|
||||
normal = side.normal;
|
||||
} else if (range.surrounds(tmax) && materials[exit.ordinal()] != null) {
|
||||
t = tmax;
|
||||
side = exit;
|
||||
frontFace = false;
|
||||
material = materials[side.ordinal()];
|
||||
normal = side.normal.neg();
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
var side = frontFace ? entry : exit;
|
||||
var normal = frontFace ? side.normal : side.normal.neg();
|
||||
var position = ray.at(t);
|
||||
var uv = material().texture().isUVRequired();
|
||||
var uv = material.texture().isUVRequired();
|
||||
var u = uv ? side.getTextureU(box, position) : Double.NaN;
|
||||
var v = uv ? side.getTextureV(box, position) : Double.NaN;
|
||||
return Optional.of(new HitResult(t, position, normal, material, u, v, frontFace));
|
||||
|
Loading…
x
Reference in New Issue
Block a user