diff --git a/src/xyz/marsavic/gfxlab/SplineSpectrum.java b/src/xyz/marsavic/gfxlab/SplineSpectrum.java index 6bc53fb..6365589 100644 --- a/src/xyz/marsavic/gfxlab/SplineSpectrum.java +++ b/src/xyz/marsavic/gfxlab/SplineSpectrum.java @@ -24,7 +24,7 @@ public class SplineSpectrum implements Spectrum { double h = samples[i].getKey() - samples[i - 1].getKey(); if (h <= 0.0) throw new IllegalArgumentException("Samples must have strictly increasing x coordinates."); - d[i] = (samples[i].getValue() - samples[i - 1].getValue()); + d[i - 1] = (samples[i].getValue() - samples[i - 1].getValue()); } m[0] = d[0]; @@ -56,14 +56,13 @@ public class SplineSpectrum implements Spectrum { return samples[n-1].getValue(); } - Double.valueOf(wavelength); int i = Arrays.binarySearch(samples, new Pair(Double.valueOf(wavelength), null), new DoublePairKeyComparator()); if (i >= 0) { return samples[i].getValue(); } - i = -(i+1); + i = -(i+2); // Invert negative result and get index of previous element double h = samples[i+1].getKey() - samples[i].getKey(); double t = (wavelength - samples[i].getKey()) / h; return (samples[i].getValue() * (1 + 2*t) + h*m[i]*t) * (1 - t) * (1 - t) diff --git a/src/xyz/marsavic/gfxlab/graphics3d/Light.java b/src/xyz/marsavic/gfxlab/graphics3d/Light.java index 9dca13d..1225404 100644 --- a/src/xyz/marsavic/gfxlab/graphics3d/Light.java +++ b/src/xyz/marsavic/gfxlab/graphics3d/Light.java @@ -1,6 +1,5 @@ package xyz.marsavic.gfxlab.graphics3d; -import xyz.marsavic.gfxlab.Color; import xyz.marsavic.gfxlab.Spectrum; import xyz.marsavic.gfxlab.Vec3; @@ -10,12 +9,12 @@ public record Light( Spectrum s ) { - public static Light pc(Vec3 p, Spectrum s) { + public static Light ps(Vec3 p, Spectrum s) { return new Light(p, s); } public static Light p(Vec3 p) { - return pc(p, wavelength -> 0); + return ps(p, wavelength -> 1.0); } } diff --git a/src/xyz/marsavic/gfxlab/graphics3d/Material.java b/src/xyz/marsavic/gfxlab/graphics3d/Material.java index ed00925..4dd51d7 100644 --- a/src/xyz/marsavic/gfxlab/graphics3d/Material.java +++ b/src/xyz/marsavic/gfxlab/graphics3d/Material.java @@ -30,11 +30,11 @@ public record Material( public static final Material MATTE = matte(); public static final Material MIRROR = BLACK.reflective(new SplineSpectrum(new Pair[]{ - new Pair(248.0, 92.6), - new Pair(400.0, 92.0), - new Pair(532.0, 91.6), - new Pair(633.0, 90.7), - new Pair(800.0, 86.8) + new Pair(248.0, 0.926), + new Pair(400.0, 0.920), + new Pair(532.0, 0.916), + new Pair(633.0, 0.907), + new Pair(800.0, 0.868) })); public static final Material GLASS = BLACK.refractive(w -> 1.0) .refractiveIndex(w -> 1.6 + (w-400)/(800-400) * (1.55 - 1.6)); /* Made to roughly resemble refractive index diff --git a/src/xyz/marsavic/gfxlab/graphics3d/raytracers/RayTracerSimple.java b/src/xyz/marsavic/gfxlab/graphics3d/raytracers/RayTracerSimple.java index d84d84f..2ece5b5 100644 --- a/src/xyz/marsavic/gfxlab/graphics3d/raytracers/RayTracerSimple.java +++ b/src/xyz/marsavic/gfxlab/graphics3d/raytracers/RayTracerSimple.java @@ -7,9 +7,20 @@ import xyz.marsavic.gfxlab.graphics3d.*; public class RayTracerSimple extends RayTracer { private static final int spectrumSamples = 20; - static final double minWavelength = 380; - static final double maxWavelength = 780; + private static final double minWavelength = 380; + private static final double maxWavelength = 780; private static final double EPSILON = 1e-9; + private static final double maxXYZ; + + static { + double max = 0.0; + for (int i = 0; i < spectrumSamples; i++) { + double wavelength = minWavelength + (((double) i)/spectrumSamples)*(maxWavelength - minWavelength); + max += Xyz.x[(int) wavelength] + Xyz.y[(int) wavelength] + Xyz.z[(int) wavelength]; + } + maxXYZ = max; + } + public RayTracerSimple(Scene scene, Camera camera) { super(scene, camera); } @@ -29,7 +40,10 @@ public class RayTracerSimple extends RayTracer { y += intensity * Xyz.y[(int) wavelength]; z += intensity * Xyz.z[(int) wavelength]; } - return Color.xyz(x,y,z); + + Color result = Color.xyz(x,y,z); + + return result; } protected double sample(Ray ray, int depthRemaining, double wavelength) { diff --git a/src/xyz/marsavic/gfxlab/graphics3d/scene/SpectrumTest.java b/src/xyz/marsavic/gfxlab/graphics3d/scene/SpectrumTest.java index 3e6409e..b7e509b 100644 --- a/src/xyz/marsavic/gfxlab/graphics3d/scene/SpectrumTest.java +++ b/src/xyz/marsavic/gfxlab/graphics3d/scene/SpectrumTest.java @@ -22,15 +22,18 @@ public class SpectrumTest extends Scene.Base { public SpectrumTest() { var materialUVWalls = Grid.standard(Spectrum.WHITE); - var materialUVWallsL = Grid.standard(new SplineSpectrum(new Pair[]{ + SplineSpectrum s; + var materialUVWallsL = Grid.standard(s = new SplineSpectrum(new Pair[]{ new Pair(450.0, 0.2), + new Pair(500.0, 0.27), new Pair(550.0, 0.35), - new Pair(650.0, 0.8), + new Pair(700.0, 0.8), })); var materialUVWallsR = Grid.standard(new SplineSpectrum(new Pair[]{ - new Pair(450.0, 0.3), - new Pair(550.0, 0.75), - new Pair(650.0, 0.3), + new Pair(450.0, 0.1), + new Pair(500.0, 0.25), + new Pair(550.0, 0.2), + new Pair(650.0, 0.1), })); Collection solids = new ArrayList<>(); @@ -41,23 +44,17 @@ public class SpectrumTest extends Scene.Base { HalfSpace.pn(Vec3.xyz( 0, 1, 0), Vec3.xyz( 0, -1, 0), materialUVWalls), HalfSpace.pn(Vec3.xyz( 0, 0, 1), Vec3.xyz( 0, 0, -1), materialUVWalls), - Ball.cr(Vec3.xyz(-0.3, 0.3, 0.0), 0.4, uv -> Material.GLASS.refractive(new SplineSpectrum( - new Pair[]{ - new Pair(450.0, 0.8), - new Pair(550.0, 0.35), - new Pair(650.0, 0.2), - } - ))), - Ball.cr(Vec3.xyz( 0.4, -0.4, 0.0), 0.4, uv -> Material.GLASS), - Ball.cr(Vec3.xyz(-0.3, -0.4, -0.6), 0.4, uv -> Material.GLASS.refractiveIndex(w -> 2.5)), - Ball.cr(Vec3.xyz( 0.4, 0.3, 0.6), 0.4, uv -> Material.GLASS.refractiveIndex(w -> 0.6)) + Ball.cr(Vec3.xyz(-0.3, 0.3, 0.0), 0.4, uv -> Material.GLASS.refractive(w->0.5)), + Ball.cr(Vec3.xyz( 0.4, -0.4, 0.0), 0.4, uv -> Material.GLASS) +// Ball.cr(Vec3.xyz(-0.3, -0.4, -0.6), 0.4, uv -> Material.GLASS.refractiveIndex(w -> 2.5)), +// Ball.cr(Vec3.xyz( 0.4, 0.3, 0.6), 0.4, uv -> Material.GLASS.refractiveIndex(w -> 0.6)) ); Collections.addAll(lights, - Light.pc(Vec3.xyz(-0.7, 0.7, -0.7), Spectrum.WHITE), - Light.pc(Vec3.xyz(-0.7, 0.7, 0.7), Spectrum.WHITE), - Light.pc(Vec3.xyz( 0.7, 0.7, -0.7), Spectrum.WHITE), - Light.pc(Vec3.xyz( 0.7, 0.7, 0.7), Spectrum.WHITE) + Light.ps(Vec3.xyz(-0.7, 0.7, -0.7), Spectrum.WHITE), + Light.ps(Vec3.xyz(-0.7, 0.7, 0.7), Spectrum.WHITE), + Light.ps(Vec3.xyz( 0.7, 0.7, -0.7), Spectrum.WHITE), + Light.ps(Vec3.xyz( 0.7, 0.7, 0.7), Spectrum.WHITE) ); solid = Group.of(solids);