Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- self.addEventListener('message', function (e) {
- var canvas = e.data[0];
- var ctx = canvas.getContext('2d');
- var imgData = ctx.createImageData(canvas.width, canvas.height);
- var maxdepth = e.data[2];
- var lights = e.data[3];
- function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
- var a1, a2, b1, b2, c1, c2;
- var r1, r2, r3, r4;
- var denom, offset, num;
- a1 = y2 - y1;
- b1 = x1 - x2;
- c1 = (x2 * y1) - (x1 * y2);
- r3 = ((a1 * x3) + (b1 * y3) + c1);
- r4 = ((a1 * x4) + (b1 * y4) + c1);
- a2 = y4 - y3;
- b2 = x3 - x4;
- c2 = (x4 * y3) - (x3 * y4);
- r1 = (a2 * x1) + (b2 * y1) + c2;
- r2 = (a2 * x2) + (b2 * y2) + c2;
- denom = (r1 * r2) - (r3 * r4);
- if (denom == 0) {
- return false;
- }
- offset = Math.abs(denom / 2);
- num = (r1 * r4) - (r2 * r3);
- var x = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);
- num = (a1 * r4) - (a2 * r3);
- var y = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);
- var point = new Point(x, y);
- if (r1 == 0 || r2 == 0 || r3 == 0 || r4 == 0) {
- return true;
- } else {
- return (r1 > 0 && r2 > 0 && r3 > 0 && r4 > 0) ||
- (r1 < 0 && r2 < 0 && r3 < 0 && r4 < 0);
- }
- }
- function typedArrayToURL(typedArray, mimeType) {
- return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType}))
- }
- function trace(scene, ray, lights, depth) {
- // check if the ray hits an object
- // if so, calculate the color
- // if not, return the background color
- // check if the ray hits an object
- var closest = findIntersection(scene.objects, ray);
- if (closest) {
- var point = ray.origin.add(ray.direction.multiply(closest.distance));
- var normal = closest.object.normalAt(point);
- var lambertAmount = 0;
- for (var i = 0; i < lights.length; i++) {
- var lightDirection = lights[i].position.subtract(point).normalize();
- var shadowOrigin = lightDirection.dot(normal) < 0 ? point.subtract(normal.multiply(1e-3)) : point.add(normal.multiply(1e-3));
- var shadowRay = new Ray(shadowOrigin, lightDirection);
- var inShadow = findIntersection(scene.objects, shadowRay);
- if (inShadow && inShadow.distance < lights[i].position.subtract(shadowOrigin).magnitude()) {
- lambertAmount = 0;
- }
- else {
- lambertAmount += lights[i].intensity * Math.max(0, lightDirection.dot(normal));
- }
- }
- var color = closest.object.color;
- var finalColor = color.multiply(scene.ambientLight).add(color.multiply(lambertAmount));
- var specularAmount = 0;
- var reflectDirection = ray.direction.subtract(normal.multiply(2 * ray.direction.dot(normal))).normalize();
- var reflectRay = new Ray(point.add(reflectDirection.multiply(1e-3)), reflectDirection);
- var reflectColor = trace(scene, reflectRay, lights, depth + 1);
- if (reflectColor && depth <= maxDepth) {
- specularAmount = Math.pow(Math.max(0, -reflectDirection.dot(ray.direction)), closest.object.specularExponent);
- }
- finalColor = finalColor.add(reflectColor.multiply(closest.object.reflectivity).multiply(specularAmount));
- return finalColor;
- }
- else {
- return null;
- }
- }
- function findIntersection(objects, ray) {
- var closest = Infinity;
- var closestInter = null;
- for (var i = 0; i < objects.length; i++) {
- var inter = objects[i].intersect(ray);
- if (inter != null && inter.distance < closest) {
- closestInter = inter;
- closest = inter.distance;
- }
- }
- return closestInter;
- }
- for (var i = 0; i < e.data[4].length; i++) {
- var ray = e.data[4][i];
- var color = trace(e.data[1], ray, lights, maxdepth);
- if (color) {
- imgData.data[i * 4] = color[0];
- imgData.data[i * 4 + 1] = color[1];
- imgData.data[i * 4 + 2] = color[2];
- }
- }
- ctx.putImageData(imgData, 0, 0);
- postMessage("Finished");
- }, false);
Advertisement
Add Comment
Please, Sign In to add comment