Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/java/labs/introtoprogramming/lab5/object/Sphere.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public Sphere(Transform transform, double radius) {
this.radius = radius;
}

@SuppressWarnings("Duplicates")
@Override
public boolean intersect(Ray ray) {
Vector3 originToCenter = transform.position().subtract(ray.getOrigin());
Expand Down Expand Up @@ -55,4 +56,8 @@ public Box getBoundary() {
Vector3 size = Vector3.ONE.multiply(radius);
return new Box(new Transform(), pos.subtract(size), pos.add(size));
}

public Vector3 getNormal(Vector3 hitPoint) {
return hitPoint.subtract(transform.position()).normalize();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
import java.awt.Color;

public class BasicRaytracingRender implements SceneRender {

private static final boolean DEFAULT_APPLY_SHADING = true;

private Raster raster;
private boolean applyShading = DEFAULT_APPLY_SHADING;

public BasicRaytracingRender(Scene scene) {
this(scene.getCamera().orElseThrow(NoCameraException::new));
Expand Down Expand Up @@ -52,12 +56,40 @@ public void render(Scene scene) {

Color getColor(Ray primaryRay, Scene scene) {
SceneObject obj = findInteraction(primaryRay, scene);
return obj != null ? obj.getMesh().color() : scene.getBackgroundColor();

if (obj == null) {
return scene.getBackgroundColor();
}

if (!applyShading) {
return obj.getMesh().color();
}

double c = 0;

for (Light light : scene.getLights()) {
Vector3 hitNormal = obj.getNormal(primaryRay.getPoint());
double bias = 0.001;
Ray nRay = new Ray(primaryRay.getPoint().add(hitNormal.multiply(bias)), light.getTransform().rotation().multiply(-1));
boolean visible = findInteraction(nRay, scene, light.getMaxDist(primaryRay.getPoint())) == null;
if (visible) {
c += obj.albedo() / Math.PI * light.illuminate(hitNormal, light.getTransform().position().distance(obj.getTransform().position()));
}
}

if (c > 1) {
c = 1;
}

return new Color((int) (obj.getMesh().color().getRed() * c), (int) (obj.getMesh().color().getGreen() * c), (int) (obj.getMesh().color().getBlue() * c));
}

SceneObject findInteraction(Ray primaryRay, Scene scene) {
return findInteraction(primaryRay, scene, Double.POSITIVE_INFINITY);
}

SceneObject findInteraction(Ray primaryRay, Scene scene, double minDistance) {
SceneObject intersection = null;
double minDistance = Double.POSITIVE_INFINITY;
for (SceneObject obj : scene.getSceneObjects()) {
if (obj.intersect(primaryRay)) {
double distance = primaryRay.getScale();
Expand All @@ -67,6 +99,9 @@ SceneObject findInteraction(Ray primaryRay, Scene scene) {
}
}
}
if (intersection != null) {
primaryRay.setScale(minDistance);
}
return intersection;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public List<SceneObject> getSceneObjects() {
}

@Override
public List<PointLight> getLights() {
public List<Light> getLights() {
return entities.stream()
.filter(obj -> obj instanceof PointLight)
.map(obj -> (PointLight) obj)
.filter(obj -> obj instanceof Light)
.map(obj -> (Light) obj)
.collect(Collectors.toList());
}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/labs/introtoprogramming/lab5/scene/DistantLight.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package labs.introtoprogramming.lab5.scene;

import java.awt.Color;
import labs.introtoprogramming.lab5.geometry.Vector3;

public class DistantLight extends Light {

Vector3 direction;

public DistantLight(Transform transform, double intensity) {
super(transform, intensity);
}

@Override
public double illuminate(Vector3 normal, double distance) {
return Math.max(intensity() * normal.dotProduct(getTransform().rotation().multiply(-1)), 0);
}

public double getMaxDist(Vector3 point) {
return Double.POSITIVE_INFINITY;
}
}
21 changes: 21 additions & 0 deletions src/main/java/labs/introtoprogramming/lab5/scene/Light.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package labs.introtoprogramming.lab5.scene;

import labs.introtoprogramming.lab5.geometry.Vector3;

public abstract class Light extends SceneObject {

private double intensity;

public Light(Transform transform, double intensity) {
super(transform);
this.intensity = intensity;
}

public double intensity() {
return intensity;
}

public abstract double illuminate(Vector3 normal, double distance);

public abstract double getMaxDist(Vector3 point);
}
17 changes: 16 additions & 1 deletion src/main/java/labs/introtoprogramming/lab5/scene/PointLight.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
package labs.introtoprogramming.lab5.scene;

public abstract class PointLight extends SceneObject {
import labs.introtoprogramming.lab5.geometry.Vector3;

public class PointLight extends Light {
public PointLight(Transform transform, double intensity) {
super(transform, intensity);
}

@Override
public double illuminate(Vector3 normal, double distance) {
return Math.max((intensity() * normal.dotProduct(getTransform().rotation().multiply(-1))) / (4 * Math.PI * Math.pow(distance, 2)), 0);
}

@Override
public double getMaxDist(Vector3 point) {
return point.distance(transform.position());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public abstract class Scene {

public abstract List<SceneObject> getSceneObjects();

public abstract List<PointLight> getLights();
public abstract List<Light> getLights();

public abstract List<Controller> getControllers();

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/labs/introtoprogramming/lab5/scene/SceneObject.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package labs.introtoprogramming.lab5.scene;

import java.awt.Color;
import labs.introtoprogramming.lab5.geometry.Ray;
import labs.introtoprogramming.lab5.geometry.Vector3;
import labs.introtoprogramming.lab5.object.Box;

public class SceneObject {

private static double DEFAULT_ALBEDO = 0.18;

protected Transform transform;
protected Mesh mesh;
protected double albedo = DEFAULT_ALBEDO;

/**
* Base class of scene objects.
Expand Down Expand Up @@ -39,7 +44,13 @@ public boolean intersect(Ray ray) {
return false;
}

public Vector3 getNormal(Vector3 hitPoint) { return Vector3.ZERO; }

public Box getBoundary() {
return null;
}

public double albedo() {
return albedo;
}
}
14 changes: 11 additions & 3 deletions src/main/java/labs/introtoprogramming/lab5/scenes/DemoScene.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package labs.introtoprogramming.lab5.scenes;

import java.awt.Color;
import labs.introtoprogramming.lab5.geometry.Vector3;
import labs.introtoprogramming.lab5.object.Box;
import labs.introtoprogramming.lab5.object.Sphere;
import labs.introtoprogramming.lab5.scene.BasicScene;
import labs.introtoprogramming.lab5.scene.DistantLight;
import labs.introtoprogramming.lab5.scene.PointLight;
import labs.introtoprogramming.lab5.scene.Transform;

public class DemoScene extends BasicScene {

public DemoScene() {
Box other = new Box(new Transform(new Vector3(0, -6, 0)), 10);
Sphere sphere = new Sphere(new Transform(Vector3.FORWARD.multiply(-3)), 1);
sphere.getMesh().setColor(Color.RED);
addSceneObjects(
new Sphere(new Transform(Vector3.FORWARD.multiply(-3)), 1),
new Box(new Transform(Vector3.FORWARD.multiply(-10)), 1),
new Box(new Transform(Vector3.RIGHT.multiply(5)), 1)
sphere,
new Box(new Transform(new Vector3(2, 2, -3)), 1),
other,
new DistantLight(new Transform(Vector3.ZERO, new Vector3(0, -1, 0)), 10)
//new PointLight(new Transform(new Vector3(0, 0, -1), new Vector3(0, -1, 0)), 1000)
);
}
}