skip unnecessary UV calculations

main
jbb01 6 months ago
parent 18c179f8e3
commit 1b02f8a96d

@ -3,6 +3,7 @@ package eu.jonahbauer.raytracing.render.material;
import eu.jonahbauer.raytracing.math.Ray; import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.math.Vec3; import eu.jonahbauer.raytracing.math.Vec3;
import eu.jonahbauer.raytracing.render.texture.Color; import eu.jonahbauer.raytracing.render.texture.Color;
import eu.jonahbauer.raytracing.render.texture.Texture;
import eu.jonahbauer.raytracing.scene.HitResult; import eu.jonahbauer.raytracing.scene.HitResult;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -14,4 +15,9 @@ public record IsotropicMaterial(@NotNull Color albedo) implements Material {
public @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit, @NotNull RandomGenerator random) { public @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit, @NotNull RandomGenerator random) {
return Optional.of(new ScatterResult(new Ray(hit.position(), Vec3.random(random, true)), albedo())); return Optional.of(new ScatterResult(new Ray(hit.position(), Vec3.random(random, true)), albedo()));
} }
@Override
public @NotNull Texture texture() {
return albedo();
}
} }

@ -2,6 +2,7 @@ package eu.jonahbauer.raytracing.render.material;
import eu.jonahbauer.raytracing.math.Ray; import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.render.texture.Color; import eu.jonahbauer.raytracing.render.texture.Color;
import eu.jonahbauer.raytracing.render.texture.Texture;
import eu.jonahbauer.raytracing.scene.HitResult; import eu.jonahbauer.raytracing.scene.HitResult;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -11,6 +12,8 @@ import java.util.random.RandomGenerator;
public interface Material { public interface Material {
@NotNull Texture texture();
@NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit, @NotNull RandomGenerator random); @NotNull Optional<ScatterResult> scatter(@NotNull Ray ray, @NotNull HitResult hit, @NotNull RandomGenerator random);
default @NotNull Color emitted(@NotNull HitResult hit) { default @NotNull Color emitted(@NotNull HitResult hit) {

@ -14,4 +14,9 @@ public record CheckerTexture(double scale, @NotNull Texture even, @NotNull Textu
var even = (x + y + z) % 2 == 0; var even = (x + y + z) % 2 == 0;
return even ? even().get(u, v, p) : odd().get(u, v, p); return even ? even().get(u, v, p) : odd().get(u, v, p);
} }
@Override
public boolean isUVRequired() {
return even.isUVRequired() || odd.isUVRequired();
}
} }

@ -94,6 +94,11 @@ public record Color(double r, double g, double b) implements Texture {
return this; return this;
} }
@Override
public boolean isUVRequired() {
return false;
}
private static int toInt(double value) { private static int toInt(double value) {
return Math.clamp((int) (255.99 * value), 0, 255); return Math.clamp((int) (255.99 * value), 0, 255);
} }

@ -144,4 +144,9 @@ public final class PerlinTexture implements Texture {
} }
return accum; return accum;
} }
@Override
public boolean isUVRequired() {
return false;
}
} }

@ -10,4 +10,8 @@ public interface Texture {
} }
@NotNull Color get(double u, double v, @NotNull Vec3 p); @NotNull Color get(double u, double v, @NotNull Vec3 p);
default boolean isUVRequired() {
return true;
}
} }

@ -82,8 +82,9 @@ public record Box(@NotNull AABB box, @NotNull Material material) implements Hitt
var side = frontFace ? entry : exit; var side = frontFace ? entry : exit;
var normal = frontFace ? side.normal : side.normal.neg(); var normal = frontFace ? side.normal : side.normal.neg();
var position = ray.at(t); var position = ray.at(t);
var u = side.getTextureU(box, position); var uv = material().texture().isUVRequired();
var v = side.getTextureV(box, position); 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)); return Optional.of(new HitResult(t, position, normal, material, u, v, frontFace));
} }

@ -52,11 +52,17 @@ public final class Sphere implements Hittable {
var normal = position.minus(center).div(radius); var normal = position.minus(center).div(radius);
var frontFace = normal.times(ray.direction()) < 0; var frontFace = normal.times(ray.direction()) < 0;
var theta = Math.acos(- normal.y()); double u;
var phi = Math.atan2(- normal.z(), normal.x()) + Math.PI; double v;
if (material.texture().isUVRequired()) {
var u = phi / (2 * Math.PI); var theta = Math.acos(-normal.y());
var v = theta / Math.PI; var phi = Math.atan2(-normal.z(), normal.x()) + Math.PI;
u = phi / (2 * Math.PI);
v = theta / Math.PI;
} else {
u = Double.NaN;
v = Double.NaN;
}
return Optional.of(new HitResult( return Optional.of(new HitResult(
t, position, frontFace ? normal : normal.neg(), t, position, frontFace ? normal : normal.neg(),

Loading…
Cancel
Save