private Color getNaturalColor(Thing thing, Vector pos, Vector norm, Vector rd, Scene scene) { this.thing = thing; this.pos = pos; this.norm = norm; this.rd = rd; this.scene = scene; return Reduce(scene.lights, Color.defaultColor); }
public void render(Scene scene, CanvasRenderingContext2D ctx, double screenWidth, double screenHeight) { this.screenWidth = screenWidth; this.screenHeight = screenHeight; for (var y = 0; y < screenHeight; y++) { for (var x = 0; x < screenWidth; x++) { var color = this.traceRay( new Ray(scene.camera.pos, getPoint(x, y, scene.camera)), scene, 0); var c = Color.toDrawingColor(color); ctx.fillStyle = "rgb(" + c.r + ", " + c.g + ", " + c.b + ")"; ctx.fillRect(x, y, x + 1, y + 1); } } }
private Color getReflectionColor(Thing thing, Vector pos, Vector normal, Vector rd, Scene scene, double depth) { return Color.scale(thing.surface.reflect(pos), this.traceRay(new Ray (pos, rd), scene, depth + 1)); }
private Color shade(Intersection isect, Scene scene, double depth) { var d = isect.ray.dir; var pos = Vector.plus(Vector.times(isect.dist, d), isect.ray.start); var normal = isect.thing.normal(pos); var reflectDir = Vector.minus(d, Vector.times(2, Vector.times(Vector.dot(normal, d), normal))); var naturalColor = Color.plus(Color.background, this.getNaturalColor(isect.thing, pos, normal, reflectDir, scene)); var reflectedColor = (depth >= this.maxDepth) ? Color.grey : this.getReflectionColor(isect.thing, pos, normal, reflectDir, scene, depth); return Color.plus(naturalColor, reflectedColor); }
private Color traceRay(Ray ray, Scene scene, double depth) { var isect = this.intersections(ray, scene); if (isect == null) { return Color.background; } else { return this.shade(isect, scene, depth); } }
private double? testRay(Ray ray, Scene scene) { var isect = this.intersections(ray, scene); if (isect != null) { return isect.dist; } else { return null; } }
private Intersection intersections(Ray ray, Scene scene) { var closest = double.PositiveInfinity; Intersection closestInter = null; foreach (var i in scene.things) { var inter = i.intersect(ray); if (inter != null && inter.dist < closest) { closestInter = inter; closest = inter.dist; } } return closestInter; }