add a material that looks different on both sides

main
jbb01 6 months ago
parent a22b1cb238
commit f7d9153ad8

@ -22,7 +22,7 @@ public record DielectricMaterial(double refractionIndex, @NotNull Texture textur
@Override
public @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit, @NotNull RandomGenerator random) {
var ri = hit.frontFace() ? (1 / refractionIndex) : refractionIndex;
var ri = hit.isFrontFace() ? (1 / refractionIndex) : refractionIndex;
var cosTheta = Math.min(- ray.direction().unit().times(hit.normal()), 1.0);
var reflectance = reflectance(cosTheta);

@ -0,0 +1,67 @@
package eu.jonahbauer.raytracing.render.material;
import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.math.Vec3;
import eu.jonahbauer.raytracing.render.texture.Color;
import eu.jonahbauer.raytracing.render.texture.Texture;
import eu.jonahbauer.raytracing.scene.HitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.random.RandomGenerator;
public final class DirectionalMaterial implements Material {
private final @Nullable Material front;
private final @Nullable Material back;
private final @NotNull Texture texture;
public DirectionalMaterial(@Nullable Material front, @Nullable Material back) {
this.front = front;
this.back = back;
this.texture = new DirectionalTexture(
front != null ? front.texture() : null,
back != null ? back.texture() : null
);
}
@Override
public @NotNull Texture texture() {
return texture;
}
@Override
public @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit, @NotNull RandomGenerator random) {
if (hit.isFrontFace()) {
if (front != null) return front.scatter(ray, hit, random);
} else {
if (back != null) return back.scatter(ray, hit, random);
}
// let the ray pass through without obstruction
return Optional.of(new ScatterResult(new Ray(ray.at(hit.t()), ray.direction()), Color.WHITE));
}
@Override
public @NotNull Color emitted(@NotNull HitResult hit) {
if (hit.isFrontFace()) {
if (front != null) return front.emitted(hit);
} else {
if (back != null) return back.emitted(hit);
}
return Color.BLACK;
}
private record DirectionalTexture(@Nullable Texture front, @Nullable Texture back) implements Texture {
@Override
public @NotNull Color get(double u, double v, @NotNull Vec3 p) {
throw new UnsupportedOperationException();
}
@Override
public boolean isUVRequired() {
return front() != null && front().isUVRequired() || back() != null && back().isUVRequired();
}
}
}

@ -8,7 +8,7 @@ import java.util.Objects;
public record HitResult(
double t, @NotNull Vec3 position, @NotNull Vec3 normal,
@NotNull Material material, double u, double v, boolean frontFace
@NotNull Material material, double u, double v, boolean isFrontFace
) implements Comparable<HitResult> {
public HitResult {
Objects.requireNonNull(position, "position");
@ -16,7 +16,7 @@ public record HitResult(
}
public @NotNull HitResult withPositionAndNormal(@NotNull Vec3 position, @NotNull Vec3 normal) {
return new HitResult(t, position, normal, material, u, v, frontFace);
return new HitResult(t, position, normal, material, u, v, isFrontFace);
}
@Override

@ -32,7 +32,7 @@ public record ConstantMedium(@NotNull Hittable boundary, double density, @NotNul
if (hitDistance > distance) return Optional.empty();
var t = tmin + hitDistance / length;
return Optional.of(new HitResult(t, ray.at(t), Vec3.UNIT_X, material, 0, 0, true)); // arbitrary normal and frontFace
return Optional.of(new HitResult(t, ray.at(t), Vec3.UNIT_X, material, 0, 0, true)); // arbitrary normal, u, v and isFrontFace
}
@Override

Loading…
Cancel
Save