add a material that looks different on both sides
parent
a22b1cb238
commit
f7d9153ad8
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue