diff --git a/index.html b/index.html index d2a125a6c4a6830a12284dd3fbc28d067f07a5a9..d31a42c2c9dbfaaefa8b5155e0b44d722c8c6f39 100644 --- a/index.html +++ b/index.html @@ -15,6 +15,6 @@ <script type="module" src="/src/cg/perspectiveDivide.ts"></script> <script type="module" src="/src/cg/walkToVec.ts"></script> <script type="module" src="/src/cg/basis.ts"></script--> - <script type="module" src="/src/cg/raytracing2.ts"></script> + <script type="module" src="/src/cg/raytracing2animation.ts"></script> </body> </html> diff --git a/src/cg/raytracing2.ts b/src/cg/raytracing2.ts index 4fec61b39b6946645072af844d217227607852df..475ec1c8f23a11facf34e692ec7810090b7364d8 100644 --- a/src/cg/raytracing2.ts +++ b/src/cg/raytracing2.ts @@ -4,7 +4,7 @@ import { ISphere, Vec3, raySphereIntersect } from "./utils"; const width = 200 const height = 200 const framebuffer = new Framebuffer(width, height); -const imagePlaneDist = -1 +const imagePlaneDist = -0.5 const tNear = 1; const tFar = 1000; @@ -12,14 +12,19 @@ const tFar = 1000; const spheres = [ { position: [0, 0, -3],// <--- - radius: 2,// <--- + radius: 1,// <--- color: [255,0,0]// <--- }, { position: [3,2,-3],// <--- - radius: 2,// <--- + radius: 0.5,// <--- color: [0,255,0]// <--- }, + { + position: [-2, -2, -4], + radius: 1, + color: [0,0,255] + } //... add more spheres if you like ] diff --git a/src/cg/raytracing2animation frames/render.spheres.1.png b/src/cg/raytracing2animation frames/render.spheres.1.png new file mode 100644 index 0000000000000000000000000000000000000000..99e5178a669525e38d730702d80ef979db95cc9e Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.1.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.10.png b/src/cg/raytracing2animation frames/render.spheres.10.png new file mode 100644 index 0000000000000000000000000000000000000000..807475fa31af0b4aff8d2277adfa2a7c897cda2d Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.10.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.11.png b/src/cg/raytracing2animation frames/render.spheres.11.png new file mode 100644 index 0000000000000000000000000000000000000000..4a4030e4ffe0d9f33175953a37cb76839f4ae8bc Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.11.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.2.png b/src/cg/raytracing2animation frames/render.spheres.2.png new file mode 100644 index 0000000000000000000000000000000000000000..390880d5272c8f53faec88857ec4400a4a5d1770 Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.2.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.3.png b/src/cg/raytracing2animation frames/render.spheres.3.png new file mode 100644 index 0000000000000000000000000000000000000000..5255f85565a517ea56130c79492961616fe59b02 Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.3.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.5.png b/src/cg/raytracing2animation frames/render.spheres.5.png new file mode 100644 index 0000000000000000000000000000000000000000..ef64d1405296089a52e0367d33386a6b79247a4d Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.5.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.6.png b/src/cg/raytracing2animation frames/render.spheres.6.png new file mode 100644 index 0000000000000000000000000000000000000000..5e56bda15c4d3d502e4031b0687c054df4bea10f Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.6.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.7.png b/src/cg/raytracing2animation frames/render.spheres.7.png new file mode 100644 index 0000000000000000000000000000000000000000..7b972a8d57ea6ce17a05a800fcfe4f94aa7bbb71 Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.7.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.8.png b/src/cg/raytracing2animation frames/render.spheres.8.png new file mode 100644 index 0000000000000000000000000000000000000000..a003471af1daeb790582b9fd5342bf55a1830a59 Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.8.png differ diff --git a/src/cg/raytracing2animation frames/render.spheres.9.png b/src/cg/raytracing2animation frames/render.spheres.9.png new file mode 100644 index 0000000000000000000000000000000000000000..5bbe0f02f1eda97774dfc131d3c85226645960ad Binary files /dev/null and b/src/cg/raytracing2animation frames/render.spheres.9.png differ diff --git a/src/cg/raytracing2animation.ts b/src/cg/raytracing2animation.ts new file mode 100644 index 0000000000000000000000000000000000000000..d1b060067710ab9e278b2461bad5c7ede969f8ac --- /dev/null +++ b/src/cg/raytracing2animation.ts @@ -0,0 +1,97 @@ +import Framebuffer from "./framebuffer"; +import { Vec3, Matrix4, Matrix3, matrix3ToMatrix4, matrix4Product, raySphereIntersect, ISphere, rotX, rotY, multVec3Matrix4 } from "./utils"; + +const width = 600 +const height = 600 +const framebuffer = new Framebuffer(width, height); +const imagePlaneDist = -0.5 + +const tNear = 1; +const tFar = 1000; + +const spheres = [ + { + "position": [-2.5, 0, 0], + "radius": 1, + "color": [128, 0, 0] + }, + { + "position": [0, 0, 0], + "radius": 1, + "color": [0, 128, 0] + }, + { + "position": [2.5, 0, 0], + "radius": 1, + "color": [0, 0, 128] + }, +] + +const o: Vec3 = [0, 0, 0] + + +const camT: Matrix4 = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 3, 1 // <--- 4x4 matrix that moves the camera in Z +] + +const camRx = matrix3ToMatrix4(rotX(-30))// <--- rotation matrix around X. Convert it to 4x4. + +const camInitialTransform = matrix4Product(camT, camRx)// <--- combine camT and camRX into a new matrix + +let currentFrame = 0 + +for (let i = 0; i <= 1; i += .1) { + framebuffer.clear() + + + const camRot = rotY(360*i)// <--- rotation matrix around Y using 360 * i in each frame + + + const combinedCameraTransform = matrix4Product(camInitialTransform, matrix3ToMatrix4(camRot)) // <--- Combine transformations: + // initial transform then rotate + + + // Loop over framebuffer pixels + for (let x = 0; x <= width; x++) { + for (let y = 0; y <= height; y++) { + + // Convert to screen space + const v = framebuffer.rasterToScreen(x, y, width, height, imagePlaneDist)// <--- convert raster to screen space + const vTransformed = multVec3Matrix4(v, combinedCameraTransform)// <--- apply camera transform + const oTransformed = multVec3Matrix4(o, combinedCameraTransform)// <--- apply camera transform + + // ... + // ... same as in previous task but using transformed camera vectors + let closestSphere = null; + let closestIntersection = 9999; + + for (let i = 0; i < spheres.length; i++) { + + const [t1, t2] = raySphereIntersect(vTransformed, oTransformed, spheres[i] as ISphere)// <--- Calculate intersections + + if (t1 < closestIntersection && tNear < t1 && t1 < tFar) { + closestIntersection = t1; + closestSphere = spheres[i] + } + + if (t2 < closestIntersection && tNear < t2 && t2 < tFar) { + closestIntersection = t2; + closestSphere = spheres[i]; + } + } + if (!closestSphere) { + framebuffer.draw(x,y,[0,0,50]) // <--- Draw a background color + } else { + framebuffer.draw(x,y,closestSphere.color) // <--- Draw color of closest sphere + } + + } + + } + framebuffer.update(); + framebuffer.save("spheres." + ++currentFrame); + +} \ No newline at end of file diff --git a/src/cg/utils.ts b/src/cg/utils.ts index 1a4beb8a8ab71bc9f2674b95c9b9f9c0b9f372f6..7e334667721bf82501a41fd854fd7b9521c841bb 100644 --- a/src/cg/utils.ts +++ b/src/cg/utils.ts @@ -124,7 +124,7 @@ export function multVecMatrix(v: Array<number>, m: Array<number>){ ] } -export function rotX(degrees: number){ +export function rotX(degrees: number): Matrix3{ const radian = degrees * Math.PI / 180 return [ 1, 0, 0, @@ -133,7 +133,7 @@ export function rotX(degrees: number){ ] } -export function rotY(degrees: number){ +export function rotY(degrees: number): Matrix3{ const radian = degrees * Math.PI / 180 return [ Math.cos(radian), 0, -1*Math.sin(radian), @@ -142,7 +142,7 @@ export function rotY(degrees: number){ ] } -export function rotZ(degrees: number){ +export function rotZ(degrees: number): Matrix3{ const radian = degrees * Math.PI / 180 return [ Math.cos(radian), Math.sin(radian), 0,