fixed point light
This commit is contained in:
parent
a3db520517
commit
9d745a4fd6
|
@ -104,6 +104,10 @@ public class Vector {
|
||||||
return this.scale(k).add(other.scale(1.0 - k));
|
return this.scale(k).add(other.scale(1.0 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double distance(Vector vector) {
|
||||||
|
return this.sub(vector).length();
|
||||||
|
}
|
||||||
|
|
||||||
public enum SwizzleMask {
|
public enum SwizzleMask {
|
||||||
XYZ,
|
XYZ,
|
||||||
YXZ,
|
YXZ,
|
||||||
|
|
|
@ -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.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.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 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()));
|
//scene.addLight(new Directional(new Color(1), new Vector(1, 1, 0).normalize()));
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package optics.light;
|
package optics.light;
|
||||||
|
|
||||||
|
import basics.math.algebra.Vector;
|
||||||
|
|
||||||
public class Color {
|
public class Color {
|
||||||
|
|
||||||
public static final Color BLACK = new Color(0,0,0);
|
public static final Color BLACK = new Color(0,0,0);
|
||||||
|
@ -24,6 +26,10 @@ public class Color {
|
||||||
return new Color(k, k, k);
|
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) {
|
public Color add(Color other) {
|
||||||
return new Color(this.r + other.r, this.g + other.g, this.b + other.b);
|
return new Color(this.r + other.r, this.g + other.g, this.b + other.b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,9 @@ public class Directional extends LightSource {
|
||||||
public Vector getDirection(Vector point) {
|
public Vector getDirection(Vector point) {
|
||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDistance(Vector point) {
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,6 @@ public abstract class LightSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Vector getDirection(Vector point);
|
public abstract Vector getDirection(Vector point);
|
||||||
|
|
||||||
|
public abstract double getDistance(Vector point);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,9 @@ public class Point extends LightSource {
|
||||||
public Vector getDirection(Vector point) {
|
public Vector getDirection(Vector point) {
|
||||||
return position.sub(point).normalize();
|
return position.sub(point).normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDistance(Vector point) {
|
||||||
|
return this.position.distance(point);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 Camera camera = new PinholeCamera(new Vector(0,0,-4), Vector.origin(), 90, 1e-3, 1e3);
|
||||||
private Scene scene = Scene.generateExampleScene();
|
private Scene scene = Scene.generateExampleScene();
|
||||||
|
|
||||||
private double traceShadow(Vector point, Vector sun) {
|
private double traceShadow(Vector point, Vector direction, double distance) {
|
||||||
Ray shadowRay = new Ray(point, sun, 1e-3, 1e3);
|
Ray shadowRay = new Ray(point, direction, 1e-3, distance);
|
||||||
|
|
||||||
Optional<Hit> result = scene.intersect(shadowRay);
|
Optional<Hit> result = scene.intersect(shadowRay);
|
||||||
|
|
||||||
|
@ -49,17 +49,17 @@ public class Raytracer implements Renderer {
|
||||||
// indirect light sum
|
// indirect light sum
|
||||||
Color incoming = new Color(0,0,0);
|
Color incoming = new Color(0,0,0);
|
||||||
|
|
||||||
|
Color reflectedLight = reflectedLight(directRay, material, normal, intersection, depth);
|
||||||
|
|
||||||
for (LightSource light : scene.getLights()) {
|
for (LightSource light : scene.getLights()) {
|
||||||
double directInfluence = castShadow(light, intersection, normal);
|
double directInfluence = castShadow(light, intersection, normal);
|
||||||
|
|
||||||
Color directLight = material.getDiffuse().scale(directInfluence).mul(light.getColor());
|
Color directLight = material.getDiffuse().scale(directInfluence).mul(light.getColor());
|
||||||
|
|
||||||
Color reflectedLight = reflectedLight(directRay, material, normal, intersection, depth);
|
incoming = incoming.add(directLight).add(reflectedLight);
|
||||||
|
|
||||||
incoming = incoming.add(directLight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return incoming;
|
return incoming.add(reflectedLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color reflectedLight(Ray incomingRay, BasicMaterial material, Vector normal, Vector point, int depth) {
|
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) {
|
private double castShadow(LightSource target, Vector point, Vector surfaceNormal) {
|
||||||
Vector lightDirection = target.getDirection(point);
|
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;
|
return Math.max(surfaceNormal.dot(lightDirection), 0.0) * shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
private int getRGB(int x, int y) {
|
||||||
Color linearRGB = buffer[x][y].scale(1.0 / samples[x][y]);
|
Color linearRGB = buffer[x][y].scale(1.0 / samples[x][y]);
|
||||||
|
|
||||||
int red = (int) (linearRGB.r * 255.0);
|
int red = (int) (tonemap(linearRGB.r) * 255.0);
|
||||||
int green = (int) (linearRGB.g * 255.0);
|
int green = (int) (tonemap(linearRGB.g) * 255.0);
|
||||||
int blue = (int) (linearRGB.b * 255.0);
|
int blue = (int) (tonemap(linearRGB.b) * 255.0);
|
||||||
|
|
||||||
red = Math.max(Math.min(red, 255), 0);
|
red = Math.max(Math.min(red, 255), 0);
|
||||||
green = Math.max(Math.min(green, 255), 0);
|
green = Math.max(Math.min(green, 255), 0);
|
||||||
|
|
Reference in New Issue