├── README.md ├── demos ├── README.md ├── ball.html ├── terrain.html └── tetrahedron.html └── zengine.js /README.md: -------------------------------------------------------------------------------- 1 | zengine.js 2 | ========== 3 | 4 | #### A JavaScript 3D Rendering Engine 5 | 6 | There are many JavaScript 3D libraries out there, such as [THREE.js](https://threejs.org/), but I wanted to challenge myself to write the neatest, most simple code that accomplishes rendering objects in 3D to a 2D screen. Ignoring comments, all the code that was necessary to build this to its current functionality is under 100 lines! 7 | 8 | --- 9 | 10 | ### Installation 11 | 12 | Simply include the source in your application's HTML, no downloading required: 13 | 14 | ```html 15 | 16 | ``` 17 | 18 | or you can use the shorter `git.io` redirect: 19 | 20 | ```html 21 | 22 | ``` 23 | 24 | --- 25 | 26 | ### Usage 27 | 28 | The main use of this library is obviously the rendering capabilities. This is covered below. However functions that are required to render are also available for use as part of the library. Some examples of these include: a dot product function, transformation matricies and distance functions. Feel free to use these but at the time of writing, no documentation has been made for them. 29 | 30 | **Prerequisites:** 31 | 32 | - All angles are in **degrees**. 33 | - All distances are in arbitary units - relative to each other. 34 | - The coordinate system has the `y-axis` going straight ahead, `x-axis` to the right and `z-axis` going straight up. 35 | 36 | The main function - `zengine.render()` - renders a world from the perspective of a camera to a HTML5 Canvas Element. 37 | 38 | It has the format: 39 | 40 | ```javascript 41 | zengine.render(world, cam, canvas, wireframe, horizon, light); 42 | ``` 43 | 44 | *Note that `wireframe`, `horizon` and `light` can be set to their default values of: `false`, `Infinity` (not actually because the filtering step is skipped for efficiency) and the camera's point of view's vector by not passing them or through `undefined`*. 45 | 46 | The `world` is described by an array of faces. 47 | 48 | Each face is itself an object with attributes: 49 | 50 | Attribute | Meaning 51 | ---------- | ------------------------------------- 52 | `verts` | array of vertexes as objecs (e.g. `{x: 0, y: 0, z: 0}`) 53 | `vect` | the face's unit vector (e.g. `{x: 0, y: 1, z: 0}`) 54 | `col` | color - if using shading, an object with attributes `h, s, l` else any CSS string 55 | 56 | This can be summarised by the following general-case format. 57 | 58 | ```javascript 59 | world = [{verts: [{x: ,y: ,z: }, {x: ,y: ,z: }, ...], vect: {x: ,y: ,z: }, col: }, ...] 60 | ``` 61 | 62 | The `cam` parameter is an object with attributes: 63 | 64 | Attribute | Meaning 65 | ------------- | ------------------------------------------ 66 | `x`, `y`, `z` | cooridinate in 3D Cartesian Geometry 67 | `yaw` | rotation left to right 68 | `pitch` | rotation up and down 69 | `roll` | rotation about the "forward" axis 70 | `fov` | the, horizontal, field of view, in degrees 71 | 72 | This can be seen in the following general-case format. 73 | 74 | ```javascript 75 | cam = {x: ,y: ,z: ,yaw: ,pitch: ,roll: ,fov: } 76 | ``` 77 | 78 | The `canvas` parameter should be a HTML Canvas Element Object. 79 | 80 | *Calling this function will blank the canvas before drawing to it.* 81 | 82 | The `wireframe` parameter takes a boolean indicating whether or not to draw just the outlines of each face. This also speeds up the rendering as face ordering is no longer required, and drawing to the Canvas is marginally faster. 83 | 84 | The `horizon` parameter takes a distance, in units relative to the world, for how far you can see. The purpose of this is to speed up rendering. If left `undefined`, defaults to infinity. 85 | 86 | The `light` parameter is an object with attributes: 87 | 88 | Attribute | Meaning 89 | -----------------|------------------------------------------- 90 | `yaw`, `pitch` | components of a spherical direction vector 91 | `min_saturation` | minimum saturation percent 92 | `min_lightness` | minimum lightness percent 93 | 94 | Where the `min_*` attributes are to be given as decimals in the range `0` to `1`. 95 | 96 | --- 97 | 98 | ### Examples 99 | 100 | The [demo folder](https://github.com/joeiddon/zengine/tree/master/demos) contains example code. You can view the code either by cloning this whole repository with 101 | 102 | ```shell 103 | git clone https://github.com/joeiddon/zengine.git 104 | ``` 105 | or just use the GitHub web app. 106 | 107 | To actually view each example, host locally, or view in GitHub Pages [here](https://joeiddon.github.io/zengine/demos). 108 | 109 | --- 110 | 111 | ### Known Bugs 112 | 113 | Some bugs that need fixing, but I haven't got around to: 114 | 115 | - Proper face ordering - currently done by distance to face centroids; should be done by casting a ray through the two faces. Or could use a more low level canvas rendering context, like WebGL, in order to implement a simple z-buffer. 116 | - Rotation around the x-axis is not right-hand for some reason - probably a dodgy rotation matrix calculation. Can't easily be flipped as now lots of code relies on it being wrong! Ha! 117 | 118 | --- 119 | 120 | ### Uses 121 | 122 | These are some applications of this library: 123 | 124 | - [the demos](https://joeiddon.github.io/zengine/demos) 125 | - [maze game](https://joeiddon.github.io/3d_maze_game) 126 | - [apocalombie](https://joeiddon.github.io/apocalombie) 127 | - [blocks](https://joeiddon.github.io/blocks) 128 | 129 | If you would like to read about these projects more, I have posts on each of them [here on my website](https://joeiddon.github.io/projects/javascript). 130 | -------------------------------------------------------------------------------- /demos/README.md: -------------------------------------------------------------------------------- 1 | demos 2 | ===== 3 | 4 | View the result of the above code by following their respective links: 5 | 6 | - [ball.html](https://joeiddon.github.io/zengine/demos/ball) 7 | - [terrain.html](https://joeiddon.github.io/zengine/demos/terrain) 8 | - [tetrahedron.html](https://joeiddon.github.io/zengine/demos/tetrahedron) 9 | -------------------------------------------------------------------------------- /demos/ball.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 16 | 17 | 18 | 19 | 176 | 177 | -------------------------------------------------------------------------------- /demos/terrain.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 48 | 49 |hills: 2
52 | 53 |width: 32
54 | 55 |length: 32
56 | 57 |hill height: 8
58 | 59 |speed: 256
60 | 61 |light yaw speed: 0
62 | 63 |light pitch speed: 0
64 | 65 |