From 9d745a4fd6fb4312d487681ad81ab5aab151b262 Mon Sep 17 00:00:00 2001 From: Servostar Date: Wed, 22 Feb 2023 13:19:13 +0100 Subject: [PATCH] fixed point light --- src/main/java/basics/math/algebra/Vector.java | 4 ++++ src/main/java/geometry/scene/Scene.java | 2 +- src/main/java/optics/light/Color.java | 6 ++++++ src/main/java/optics/light/Directional.java | 5 +++++ src/main/java/optics/light/LightSource.java | 2 ++ src/main/java/optics/light/Point.java | 5 +++++ src/main/java/raytracing/Raytracer.java | 15 ++++++++------- .../java/renderer/canvas/ContributionBuffer.java | 13 ++++++++++--- 8 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/basics/math/algebra/Vector.java b/src/main/java/basics/math/algebra/Vector.java index bc87e11..f71e133 100644 --- a/src/main/java/basics/math/algebra/Vector.java +++ b/src/main/java/basics/math/algebra/Vector.java @@ -104,6 +104,10 @@ public class Vector { return this.scale(k).add(other.scale(1.0 - k)); } + public double distance(Vector vector) { + return this.sub(vector).length(); + } + public enum SwizzleMask { XYZ, YXZ, diff --git a/src/main/java/geometry/scene/Scene.java b/src/main/java/geometry/scene/Scene.java index 656b215..f192c4a 100644 --- a/src/main/java/geometry/scene/Scene.java +++ b/src/main/java/geometry/scene/Scene.java @@ -35,7 +35,7 @@ public class Scene { scene.addMesh(new BasicMesh(new BasicMaterial(new Color(1, 1, 1), 0.2, new Color(1.0)), new Plane(new Vector(1, 0, 0), 1.0))); scene.addMesh(new BasicMesh(new BasicMaterial(new Color(1, 1, 1), 0.0, new Color(1.0)), new Plane(new Vector(0, 1, 0), 1.0))); - //scene.addLight(new Point(new Color(0.9, 0, 0), new Vector(8,3,-2))); + scene.addLight(new Point(new Color(0.9, 0, 0), new Vector(8,3,-2))); scene.addLight(new Point(new Color(0,0.8,0), new Vector(4,3,2))); //scene.addLight(new Directional(new Color(1), new Vector(1, 1, 0).normalize())); diff --git a/src/main/java/optics/light/Color.java b/src/main/java/optics/light/Color.java index c708b66..cf8f764 100644 --- a/src/main/java/optics/light/Color.java +++ b/src/main/java/optics/light/Color.java @@ -1,5 +1,7 @@ package optics.light; +import basics.math.algebra.Vector; + public class Color { public static final Color BLACK = new Color(0,0,0); @@ -24,6 +26,10 @@ public class Color { return new Color(k, k, k); } + public static Color fromVector(Vector vector) { + return new Color(vector.x, vector.y, vector.z); + } + public Color add(Color other) { return new Color(this.r + other.r, this.g + other.g, this.b + other.b); } diff --git a/src/main/java/optics/light/Directional.java b/src/main/java/optics/light/Directional.java index 977ba2c..bb4059e 100644 --- a/src/main/java/optics/light/Directional.java +++ b/src/main/java/optics/light/Directional.java @@ -19,4 +19,9 @@ public class Directional extends LightSource { public Vector getDirection(Vector point) { return orientation; } + + @Override + public double getDistance(Vector point) { + return Double.POSITIVE_INFINITY; + } } diff --git a/src/main/java/optics/light/LightSource.java b/src/main/java/optics/light/LightSource.java index 23cdfb5..a5261f1 100644 --- a/src/main/java/optics/light/LightSource.java +++ b/src/main/java/optics/light/LightSource.java @@ -19,4 +19,6 @@ public abstract class LightSource { } public abstract Vector getDirection(Vector point); + + public abstract double getDistance(Vector point); } diff --git a/src/main/java/optics/light/Point.java b/src/main/java/optics/light/Point.java index 9f1fcae..8538628 100644 --- a/src/main/java/optics/light/Point.java +++ b/src/main/java/optics/light/Point.java @@ -14,4 +14,9 @@ public class Point extends LightSource { public Vector getDirection(Vector point) { return position.sub(point).normalize(); } + + @Override + public double getDistance(Vector point) { + return this.position.distance(point); + } } diff --git a/src/main/java/raytracing/Raytracer.java b/src/main/java/raytracing/Raytracer.java index 1653662..e4ff27f 100644 --- a/src/main/java/raytracing/Raytracer.java +++ b/src/main/java/raytracing/Raytracer.java @@ -17,8 +17,8 @@ public class Raytracer implements Renderer { private Camera camera = new PinholeCamera(new Vector(0,0,-4), Vector.origin(), 90, 1e-3, 1e3); private Scene scene = Scene.generateExampleScene(); - private double traceShadow(Vector point, Vector sun) { - Ray shadowRay = new Ray(point, sun, 1e-3, 1e3); + private double traceShadow(Vector point, Vector direction, double distance) { + Ray shadowRay = new Ray(point, direction, 1e-3, distance); Optional result = scene.intersect(shadowRay); @@ -49,17 +49,17 @@ public class Raytracer implements Renderer { // indirect light sum Color incoming = new Color(0,0,0); + Color reflectedLight = reflectedLight(directRay, material, normal, intersection, depth); + for (LightSource light : scene.getLights()) { double directInfluence = castShadow(light, intersection, normal); Color directLight = material.getDiffuse().scale(directInfluence).mul(light.getColor()); - Color reflectedLight = reflectedLight(directRay, material, normal, intersection, depth); - - incoming = incoming.add(directLight); + incoming = incoming.add(directLight).add(reflectedLight); } - return incoming; + return incoming.add(reflectedLight); } private Color reflectedLight(Ray incomingRay, BasicMaterial material, Vector normal, Vector point, int depth) { @@ -74,7 +74,8 @@ public class Raytracer implements Renderer { private double castShadow(LightSource target, Vector point, Vector surfaceNormal) { Vector lightDirection = target.getDirection(point); - double shadow = traceShadow(point, lightDirection); + double distance = target.getDistance(point); + double shadow = traceShadow(point.add(surfaceNormal.scale(1e-3)), lightDirection, distance); return Math.max(surfaceNormal.dot(lightDirection), 0.0) * shadow; } diff --git a/src/main/java/renderer/canvas/ContributionBuffer.java b/src/main/java/renderer/canvas/ContributionBuffer.java index ac6ff80..e360104 100644 --- a/src/main/java/renderer/canvas/ContributionBuffer.java +++ b/src/main/java/renderer/canvas/ContributionBuffer.java @@ -48,12 +48,19 @@ public class ContributionBuffer { } } + private double tonemap(double x) { + final double g = 5; + final double k = 4; + + return x < g ? 1 - 1 / Math.pow(g, k) * Math.pow(x - g, k) : 1.0; + } + private int getRGB(int x, int y) { Color linearRGB = buffer[x][y].scale(1.0 / samples[x][y]); - int red = (int) (linearRGB.r * 255.0); - int green = (int) (linearRGB.g * 255.0); - int blue = (int) (linearRGB.b * 255.0); + int red = (int) (tonemap(linearRGB.r) * 255.0); + int green = (int) (tonemap(linearRGB.g) * 255.0); + int blue = (int) (tonemap(linearRGB.b) * 255.0); red = Math.max(Math.min(red, 255), 0); green = Math.max(Math.min(green, 255), 0);