A native (no external libraries) golang 3D ray tracing renderer, that implements Ray intersection via the Phong-Reflection Model, Recursive Shape grouping with AABB optimizations and Constructive Solid Geometry, augmented with recursively defined Patterns, Perlin/Simplex noise algorihthms (for patterns or triangulated objects).
The native renderer runs on CPU cycles, so high resolution scenes may take some time to render (5-15mins). Pre-rendering optimizations on .obj files relies on faces that are ordered by position: i.e. that the closest face to the previous face comes directly after it in the .obj definition.
It renders and writes to .ppm files which can be opened natively on MacOS with preview but require some additional software on Windows/Linux. I recommend using GIMP to open these files because it is a well-maintained open source Image Manipulation Program.
Examples rendered using this code:
Basic refraction/ reflection (1400 x 1000)
Complex(ish) refraction/reflection (1400 x 1000):
Parsed high resolution teapot.obj (1400 x 1000)
Runtime log & and details
go run main.go -p -parsefile=./pkg/parser/highResTeapot.obj -r
2021/03/03 13:59:50 ==================== Golang ray tracer V 0.1 ====================
2021/03/03 13:59:50 Opening file : ./pkg/parser/highResTeapot.obj...
2021/03/03 13:59:50 Parsing Object file...
2021/03/03 14:03:12 Done(3m21.4334392s)!
2021/03/03 14:03:12 Optimizing parsed Shapes (12560)...
2021/03/03 14:03:14 Done (2.2241431s)!
2021/03/03 14:03:14 Rendering scene...
2021/03/03 14:40:37 Done (37m22.6883237s)!
2021/03/03 15:42:09 Writing results to file ./pkg/examples/example.ppm...
2021/03/03 15:42:15 Wrote 8924757 bytes
2021/03/03 15:42:15 Done (5.7900586s)!`
Whith this camera defined in CreateCustomScene() in pkg/examples/examples.go:
cam, err := camera2.NewCamera(1400, 1000, math.Pi/3,
algebra.ViewTransform(
0, 30, -50,
0, 1, 0,
0, 1, 0))
Some notable improvements to be made:
- making a fast algebra library that binds algebraic manipulations and their data structures to the gpu.
- replace
getBounds()
method for Groups when Adding aShape
to aGroup
to a function that finds a fast AABB union for theBounds
struct
To use this repository, you must first fork it and the clone it to your desktop.
You can then open a terminal window and cd to its root directory and use the following CLI commands to run it on some preconfigured actions:
You can run this command to parse a .obj file and render/write it to a .ppm file in pkg/examples/ directory
:
go run main.go -p -parsefile=<string:filepath/filename> -name=<string>
- The parsefile flag accepts a filepath from the root directory and a filename to open and parse.
- The name flag accepts a string that specificies the name of the file saved to
./pkg/examples/<string:name>.ppm
- An optional -r flag can be used to rotate the scene so that y represents depth and z represents height, by default it considers y to be height and z to be depth
The native renderer is structured in such a way that each package handle one aspect of a 3D renderer or its own class of algorithms.
The algebra package covers all the data structures, functions and methods used for algebraic manipulation of 64bit floating point numbers. It should only be used in the implementation of other packages and never in a standalone way.
The canvas package covers all the data structures, functions and methods relating to representing pixels, exporting pixels to files, colors, patterns, Point lights and materials.
The geometry package covers all the data structures, functions and methods relating to the World Space and the Shape interface (and by extension all the basic shapes provided in the package)
The Camera package covers the camera data structure, and its functions and methods, to contruct a geometric pipeline that transforms the world space coordinates into their view space coordinates and pixel space coordinates.
The noise package covers Perlin/Simplex noise algorithms. Unittested using the original java implementation outputs and seeds and comparing it to the outputs of the Golang traslated algorithms using the same seed.