[Gabriel Gambetta] knows a few things about ray tracers, being the author of Tiny Raytracer, a raytracer written in just 912 bytes of JavaScript. As a long-time fellow sufferer of the UK-designed ZX Spectrum, could these two love affairs be merged? Could the Tiny Raytracer fit on the ZX Spectrum? In BASIC? The answer is an affirmative, albeit with our beloved speccy’s many limitations.
The story starts with [Gabriel]’s Computer Graphics From Scratch (CGFS) raytracer algorithms and an existing code base that was ported to the ZX Spectrum’s very limited BASIC dialect, using VSCode for editing, BAS2TAP to generate a tape image file (essentially an audio track) and executed with FUSE. With the toolchain sorted, [Gabriel] adds just enough code to deal with the ray intersection equations of a sphere, and renders a three-sphere scene to a 32×22 pixel colour image, taking a mere 15 minutes of runtime. Fellow sufferers will remember the spectrum had a 32×22 block attribute array (or colour array) with two colour values for foreground and background pixels. Each attribute block contains 8×8 pixels, each of which could be foreground (on) or background (off.) The next stage was then to expand the code to handle pixels as well as blocks, by simply expanding the raytracing to the full 256×176 resolution, and for each block simply determine the two most common colours, and run with those for the whole block. It sort of works, in a very spectrum-esq ‘attribute clash’ kind of fashion.
But now the runtime is 17 hours! Next, a spot of performance tweaking, using quite a few spectrum BASIC hacks, and some graphical approximations such as casting rays for each corner pixel of the block, and if they’re identical, colouring all the remaining 60 pixels the same and moving on. This effort reduced runtime to two hours.
Next [Gabriel] bravely ditches the flat lighting model, models a single light source and pulls out the only remaining trick in the monochrome spectrum world, that of dithering intensity values for each block, using a simple 8×8 ordered dither pattern, that doesn’t look too bad, all things considered. A quick stop on the way to completion, to add shadows and the run time is back to 17 hours, but it’s worth it. Clearly, this is optimised for a single scene type, one where spheres feature predominantly, but the principles are there, and cubes are just a few more lines of code away. Any takers?
Raytracing is one of those fun, but complex tasks that people just love to wedge into inappropriate hardware, like this TI-84Plus CE graphing calculator, and if that’s a bit hard to access, here’s something equally mad running in plain old Excel.
0 Commentaires