1 | Axis3D
|
2 | ======
|
3 |
|
4 | *Axis3D* is a lightweight functional graphics library built on top of
|
5 | [regl][regl]. It aims to be compatible with many components within the
|
6 | [stack.gl](http://stack.gl) ecosystem. It provides a set of components
|
7 | with sane defaults. It is not intended to replace existing libraries,
|
8 | but instead provide an alternative way for rendering graphics.
|
9 |
|
10 | This library is heavily inspired by the underlying mechanics of [regl][regl]
|
11 | and the functional/reactive component patterns introduced in
|
12 | [react](https://github.com/facebook/react). The scene graph and transform
|
13 | state is implied by the declarative structure of the components.
|
14 |
|
15 | Everything is a function that injects a [regl context][regl-context].
|
16 | Vectors and matrices are plain arrays that are compatible with
|
17 | [gl-matrix](https://github.com/toji/gl-matrix) and
|
18 | [the like](https://www.npmjs.com/search?q=gl-matrix). Axis3D should
|
19 | feel familiar to [three.js](https://github.com/mrdoob/three.js), but
|
20 | with less features.
|
21 |
|
22 | ## Status
|
23 |
|
24 | ***Stable*** - *This project is in active development towards _1.0.0_*
|
25 |
|
26 | ## Installation
|
27 |
|
28 | ```js
|
29 | $ npm install axis3d
|
30 | ```
|
31 |
|
32 | ## Features
|
33 |
|
34 | * Everything is a function with predictable output based on some input
|
35 | * Large focus on shaders with a [standard GLSL library](src/core/glsl)
|
36 | * Reusable components
|
37 | * Geometry with support for [simplicial-complex][simplicial-complex] modules (see: [bunny][bunny])
|
38 | * Declarative scene
|
39 | * Implicit [TRS transform matrix][transformation-matrix]
|
40 | * [regl][regl] compatibility
|
41 | * Command based (see: [regl-commands][regl-commands])
|
42 | * Context injection
|
43 |
|
44 | ## Example
|
45 |
|
46 | ```js
|
47 | import { Geometry, Material, Context, Frame, Mesh } from 'axis3d'
|
48 | import { PerspectiveCamera } from 'axis3d/camera'
|
49 | import Bunny from 'bunny'
|
50 | import quat from 'gl-quat'
|
51 |
|
52 | // scale vertices along the `y-axis` down a bit
|
53 | for (const p of Bunny.positions) { p[1] = p[1] - 4 }
|
54 |
|
55 | const ctx = new Context()
|
56 | const rotation = quat.identity([])
|
57 | const material = new Material(ctx)
|
58 | const camera = new PerspectiveCamera(ctx)
|
59 | const frame = new Frame(ctx)
|
60 | const bunny = new Mesh(ctx, {geometry: new Geometry({complex: Bunny})})
|
61 |
|
62 | // requestAnimationFrame loop helper with context injection
|
63 | frame(scene)
|
64 |
|
65 | // the scene drawn every frame
|
66 | function scene({time}) {
|
67 | quat.setAxisAngle(angle, [0, 1, 0], 0.5*time)
|
68 | camera({rotation, position: [0, 0, 5]}() => {
|
69 | material(() => {
|
70 | bunny()
|
71 | })
|
72 | })
|
73 | }
|
74 | ```
|
75 |
|
76 | ## Comparisons
|
77 |
|
78 | The following are comparisons for effectively doing the same thing in Axis3D
|
79 | below.
|
80 |
|
81 | ### Axis3D
|
82 |
|
83 | ```js
|
84 | import { PerspectiveCamera, Context, Material, Frame, Mesh, } from 'axis3d'
|
85 | import { BoxGeometry } from 'axis3d-geometry'
|
86 | import quat from 'gl-quat'
|
87 |
|
88 | const ctx = new Context()
|
89 |
|
90 | const rotation = quat.identity([])
|
91 | const geometry = new BoxGeometry({x: 10, y: 10, z: 10})
|
92 | const material = new Material(ctx)
|
93 | const camera = new PerspectiveCamera(ctx, {fov: 60, near: 0.1, far: 1000})
|
94 | const frame = new Frame(ctx)
|
95 | const mesh = new Mesh(ctx, {geometry})
|
96 |
|
97 | frame(({time}) => {
|
98 | quat.setAxisAngle(rotation, [0, 1, 0], 0.5*time)
|
99 | camera({position: [0, 0, 5]}, () => {
|
100 | material({color: [0, 0, 1]}, () => {
|
101 | mesh({rotation})
|
102 | })
|
103 | })
|
104 | })
|
105 | ```
|
106 |
|
107 | ### THREE
|
108 |
|
109 | ```js
|
110 | const aspect = window.innerWidth/window.innerHeight
|
111 | const near = 0.1
|
112 | const far = 1000
|
113 | const fov = 60
|
114 |
|
115 | const renderer = new THREE.WebGLRenderer()
|
116 | const geometry = new THREE.BoxGeometry(10, 10, 10)
|
117 | const material = new THREE.MeshBasicMaterial({color: 0x0000ff, wireframe: true})
|
118 | const camera = new THREE.PerspectiveCamera(fov, aspect, near, faar)
|
119 | const scene = new THREE.Scene()
|
120 | const mesh = new THREE.Mesh(geometry, material)
|
121 |
|
122 | camera.position.z = 5
|
123 | renderer.setSize(window.innerWidth, window.innerHeight)
|
124 | scene.add(mesh)
|
125 | document.body.appendChild(renderer.domElement)
|
126 |
|
127 | frame()
|
128 | function frame() {
|
129 | requestAnimationFrame(frame)
|
130 | mesh.rotation.y = 0.5*Date.now()
|
131 | renderer.render(scene, camera)
|
132 | }
|
133 | ```
|
134 |
|
135 | ## Contributors
|
136 |
|
137 | * [Joseph Werle](https://github.com/jwerle)
|
138 | * [Vanessa Pyne](https://github.com/vipyne)
|
139 |
|
140 | ## Docs
|
141 |
|
142 | TBD
|
143 |
|
144 | ## See Also
|
145 |
|
146 | * [regl][regl] - Functional WebGL
|
147 | * [glslify][glslify] - A node.js-style module system for GLSL
|
148 | * [stackgl][stackgl] - Modular WebGL components
|
149 | * [simplicial-complex](simplicial-complex)
|
150 |
|
151 | ## License
|
152 |
|
153 | MIT
|
154 |
|
155 | [regl]: https://github.com/regl-project/regl
|
156 | [bunny]: https://github.com/mikolalysenko/bunny
|
157 | [stackgl]: https://github.com/stackgl
|
158 | [glslify]: https://github.com/stackgl/glslify
|
159 | [regl-context]: https://github.com/regl-project/regl/blob/gh-pages/API.md#context
|
160 | [regl-commands]: https://github.com/regl-project/regl/blob/gh-pages/API.md#commands
|
161 | [simplicial-complex]: https://github.com/mikolalysenko/simplicial-complex
|
162 | [transformation-matrix]: https://en.wikipedia.org/wiki/Transformation_matrix
|