1 | <p>
|
2 | <a aria-label="sponsored by expo" href="http://expo.io">
|
3 | <img src="https://img.shields.io/badge/SPONSORED%20BY%20EXPO-4630EB.svg?style=for-the-badge" target="_blank" />
|
4 | </a>
|
5 |
|
6 | <a aria-label="Expo is free to use" href="https://github.com/expo/expo/blob/master/LICENSE" target="_blank">
|
7 | <img align="right" alt="License: MIT" src="https://img.shields.io/badge/License-MIT-success.svg?style=for-the-badge&color=33CC12" target="_blank" />
|
8 | </a>
|
9 | </p>
|
10 |
|
11 | <h1 align="center">Welcome to Expo & Three.JS 👋</h1>
|
12 |
|
13 | <p align="center">
|
14 | <b>Tools for using three.js to create universal 3D experiences</b>
|
15 | |
|
16 | <a aria-label="Try Expo THREE in the browser with Expo Snack" href="https://snack.expo.io/@bacon/three">
|
17 | <b>Try it in the browser!</b>
|
18 | </a>
|
19 | </p>
|
20 |
|
21 | <p align="center">
|
22 | <a aria-label="Well tested THREE.js Library" href="https://github.com/expo/expo-three/actions">
|
23 | <img align="center" alt="GitHub Actions status" src="https://github.com/expo/expo-three/workflows/Check%20Universal%20Module/badge.svg">
|
24 | </a>
|
25 | </p>
|
26 |
|
27 | <p>
|
28 | <a aria-label="Follow @expo on Twitter" href="https://twitter.com/intent/follow?screen_name=expo" target="_blank">
|
29 | <img alt="Twitter: expo" src="https://img.shields.io/twitter/follow/expo.svg?style=flat-square&label=Follow%20%40expo&logo=TWITTER&logoColor=FFFFFF&labelColor=00aced&logoWidth=15&color=lightgray" target="_blank" />
|
30 | </a>
|
31 |
|
32 | <a aria-label="Follow Expo on Medium" href="https://blog.expo.io">
|
33 | <img align="right" alt="Medium: exposition" src="https://img.shields.io/badge/Learn%20more%20on%20our%20blog-lightgray.svg?style=flat-square" target="_blank" />
|
34 | </a>
|
35 | </p>
|
36 |
|
37 | AR was moved to `expo-three-ar` in `expo-three@5.0.0`
|
38 |
|
39 |
|
40 | ### Installation
|
41 |
|
42 | [![NPM](https://nodei.co/npm/expo-three.png)](https://nodei.co/npm/expo-three/)
|
43 |
|
44 | > In `expo-three@5.0.0` Three.js is a **peer dependency**
|
45 |
|
46 | ```bash
|
47 | yarn add three expo-three
|
48 | ```
|
49 |
|
50 | ### Usage
|
51 |
|
52 | Import the library into your JavaScript file:
|
53 |
|
54 | ```js
|
55 | import ExpoTHREE from 'expo-three';
|
56 | ```
|
57 |
|
58 | Get a global instance of `three.js` from `expo-three`:
|
59 |
|
60 | ```js
|
61 | import { THREE } from 'expo-three';
|
62 | ```
|
63 |
|
64 | Due to some issues with the **Metro bundler** you may need to manually define the global instance of Three.js. This is important because three.js doesn't fully use ECMAScript but rather mutates a single global instance of `THREE` with side-effects.
|
65 |
|
66 | ```js
|
67 | global.THREE = global.THREE || THREE;
|
68 | ```
|
69 |
|
70 | ## Creating a Renderer
|
71 |
|
72 | ### `ExpoTHREE.Renderer({ gl: WebGLRenderingContext, width: number, height: number, pixelRatio: number, ...extras })`
|
73 |
|
74 | Given a `gl` from an
|
75 | [`Expo.GLView`](https://docs.expo.io/versions/latest/sdk/gl-view.html), return a
|
76 | [`THREE.WebGLRenderer`](https://threejs.org/docs/#api/renderers/WebGLRenderer)
|
77 | that draws into it.
|
78 |
|
79 | ```js
|
80 | const renderer = new ExpoTHREE.Renderer(props);
|
81 | or;
|
82 | /// A legacy alias for the extended renderer
|
83 | const renderer = ExpoTHREE.createRenderer(props);
|
84 | // Now just code some three.js stuff and add it to this! :D
|
85 | ```
|
86 |
|
87 | ### `ExpoTHREE.loadAsync()`
|
88 |
|
89 | A function that will asynchronously load files based on their extension.
|
90 |
|
91 | > **Notice**: Remember to update your `app.json` to bundle obscure file types!
|
92 |
|
93 | `app.json`
|
94 |
|
95 | ```diff
|
96 | {
|
97 | "expo": {
|
98 | "packagerOpts": {
|
99 | + "config": "metro.config.js"
|
100 | },
|
101 | }
|
102 | }
|
103 | ```
|
104 |
|
105 | `metro.config.js`
|
106 |
|
107 | ```js
|
108 | module.exports = {
|
109 | resolver: {
|
110 | assetExts: ['db', 'mp3', 'ttf', 'obj', 'png', 'jpg'],
|
111 | },
|
112 | };
|
113 | ```
|
114 |
|
115 | #### Props
|
116 |
|
117 | | Property | Type | Description |
|
118 | | ------------- | :-----------------------: | ---------------------------------------------------------------- |
|
119 | | resource | PossibleAsset | The asset that will be parsed asynchornously |
|
120 | | onProgress | (xhr) => void | A function that is called with an xhr event |
|
121 | | assetProvider | () => Promise<Expo.Asset> | A function that is called whenever an unknown asset is requested |
|
122 |
|
123 | ##### PossibleAsset Format
|
124 |
|
125 | export type PossibleAsset = Expo.Asset | number | string | AssetFormat;
|
126 |
|
127 | ```js
|
128 | type PossibleAsset = number | string | Expo.Asset;
|
129 | ```
|
130 |
|
131 | - `number`: Static file reference `require('./model.*')`
|
132 | - `Expo.Asset`: [Expo.Asset](https://docs.expo.io/versions/latest/sdk/asset.html)
|
133 | - `string`: A uri path to an asset
|
134 |
|
135 | #### Returns
|
136 |
|
137 | This returns many different things, based on the input file.
|
138 | For a more predictable return value you should use one of the more specific model loaders.
|
139 |
|
140 | #### Example
|
141 |
|
142 | ```js
|
143 | const texture = await ExpoTHREE.loadAsync(
|
144 | 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
|
145 | );
|
146 | ```
|
147 |
|
148 | ## Loaders
|
149 |
|
150 | ### loadAsync(assetReference, onProgress, onAssetRequested)
|
151 |
|
152 | A universal loader that can be used to load images, models, scenes, and animations.
|
153 | Optionally more specific loaders are provided with less complexity.
|
154 |
|
155 | ```js
|
156 | // A THREE.Texture from a static resource.
|
157 | const texture = await ExpoTHREE.loadAsync(require('./icon.png'));
|
158 | const obj = await ExpoTHREE.loadAsync(
|
159 | [require('./cartman.obj'), require('./cartman.mtl')],
|
160 | null,
|
161 | imageName => resources[imageName],
|
162 | );
|
163 | const { scene } = await ExpoTHREE.loadAsync(
|
164 | resources['./kenny.dae'],
|
165 | onProgress,
|
166 | resources,
|
167 | );
|
168 | ```
|
169 |
|
170 | ### loadObjAsync({ asset, mtlAsset, materials, onAssetRequested, onMtlAssetRequested })
|
171 |
|
172 | #### Props
|
173 |
|
174 | - `asset`: a `obj` model reference that will be evaluated using `AssetUtils.uriAsync`
|
175 | - `mtlAsset`: an optional prop that will be loaded using `loadMtlAsync()`
|
176 | - `onAssetRequested`: A callback that is used to evaluate urls found within the `asset` and optionally the `mtlAsset`. You can also just pass in a dictionary of key values if you know the assets required ahead of time.
|
177 | - `materials`: Optionally you can provide an array of materials returned from `loadMtlAsync()`
|
178 | - `onMtlAssetRequested`: If provided this will be used to request assets in `loadMtlAsync()`
|
179 |
|
180 | This function is used as a more direct method to loading a `.obj` model.
|
181 | You should use this function to debug when your model has a corrupted format.
|
182 |
|
183 | ```js
|
184 | const mesh = await loadObjAsync({ asset: 'https://www.members.com/chef.obj' });
|
185 | ```
|
186 |
|
187 | ### loadTextureAsync({ asset })
|
188 |
|
189 | #### Props
|
190 |
|
191 | - `asset`: an `Expo.Asset` that could be evaluated using `AssetUtils.resolveAsync` if `localUri` is missing or the asset hasn't been downloaded yet.
|
192 |
|
193 | This function is used as a more direct method to loading an image into a texture.
|
194 | You should use this function to debug when your image is using an odd extension like `.bmp`.
|
195 |
|
196 | ```js
|
197 | const texture = await loadTextureAsync({ asset: require('./image.png') });
|
198 | ```
|
199 |
|
200 | ### loadMtlAsync({ asset, onAssetRequested })
|
201 |
|
202 | #### Props
|
203 |
|
204 | - `asset`: a `mtl` material reference that will be evaluated using `AssetUtils.uriAsync`
|
205 | - `onAssetRequested`: A callback that is used to evaluate urls found within the `asset`, optionally you can just pass in a dictionary of key values if you know the assets required ahead of time.
|
206 |
|
207 | ```js
|
208 | const materials = await loadMtlAsync({
|
209 | asset: require('chef.mtl'),
|
210 | onAssetRequested: modelAssets,
|
211 | });
|
212 | ```
|
213 |
|
214 | ### loadDaeAsync({ asset, onAssetRequested, onProgress })
|
215 |
|
216 | #### Props
|
217 |
|
218 | - `asset`: a reference to a `dae` scene that will be evaluated using `AssetUtils.uriAsync`
|
219 | - `onAssetRequested`: A callback that is used to evaluate urls found within the `asset`, optionally you can just pass in a dictionary of key values if you know the assets required ahead of time.
|
220 | - `onProgress`: An experimental callback used to track loading progress.
|
221 |
|
222 | ```js
|
223 | const { scene } = await loadDaeAsync({
|
224 | asset: require('chef.dae'),
|
225 | onAssetRequested: modelAssets,
|
226 | onProgress: () => {},
|
227 | });
|
228 | ```
|
229 |
|
230 | ---
|
231 |
|
232 | ## `ExpoTHREE.utils`
|
233 |
|
234 | ### `ExpoTHREE.utils.alignMesh()`
|
235 |
|
236 | #### Props
|
237 |
|
238 | ```js
|
239 | type Axis = {
|
240 | x?: number,
|
241 | y?: number,
|
242 | z?: number,
|
243 | };
|
244 | ```
|
245 |
|
246 | | Property | Type | Description |
|
247 | | -------- | :---------: | --------------------------------- |
|
248 | | mesh | &THREE.Mesh | The mesh that will be manipulated |
|
249 | | axis | ?Axis | Set the relative center axis |
|
250 |
|
251 | #### Example
|
252 |
|
253 | ```js
|
254 | ExpoTHREE.utils.alignMesh(mesh, { x: 0.0, y: 0.5 });
|
255 | ```
|
256 |
|
257 | ---
|
258 |
|
259 | ### `ExpoTHREE.utils.scaleLongestSideToSize()`
|
260 |
|
261 | #### Props
|
262 |
|
263 | | Property | Type | Description |
|
264 | | -------- | :---------: | ------------------------------------------------------------ |
|
265 | | mesh | &THREE.Mesh | The mesh that will be manipulated |
|
266 | | size | number | The size that the longest side of the mesh will be scaled to |
|
267 |
|
268 | #### Example
|
269 |
|
270 | ```js
|
271 | ExpoTHREE.utils.scaleLongestSideToSize(mesh, 3.2);
|
272 | ```
|
273 |
|
274 | ---
|
275 |
|
276 | ### `ExpoTHREE.utils.computeMeshNormals()`
|
277 |
|
278 | Used for smoothing imported geometry, specifically when imported from `.obj` models.
|
279 |
|
280 | #### Props
|
281 |
|
282 | | Property | Type | Description |
|
283 | | -------- | :---------: | ------------------------------------------------- |
|
284 | | mesh | &THREE.Mesh | The mutable (inout) mesh that will be manipulated |
|
285 |
|
286 | #### Example
|
287 |
|
288 | ````js
|
289 | ExpoTHREE.utils.computeMeshNormals(mesh);
|
290 | ```
|
291 |
|
292 | ---
|
293 |
|
294 | ## THREE Extensions
|
295 |
|
296 | ### `suppressExpoWarnings`
|
297 |
|
298 | A function that suppresses EXGL compatibility warnings and logs them instead.
|
299 | You will need to import the `ExpoTHREE.THREE` global instance to use this. By
|
300 | default this function will be activated on import.
|
301 |
|
302 | * `shouldSuppress`: boolean
|
303 |
|
304 | ```js
|
305 | import { THREE } from 'expo-three';
|
306 | THREE.suppressExpoWarnings();
|
307 | ````
|
308 |
|
309 | ---
|
310 |
|
311 | ## ⛓ Links
|
312 |
|
313 | Somewhat out of date
|
314 |
|
315 | - [Loading Text](https://github.com/EvanBacon/expo-three-text)
|
316 | - [three.js docs](https://threejs.org/docs/)
|
317 |
|
318 | - [Random Demos](https://github.com/EvanBacon/expo-three-demo)
|
319 | - [Game: Expo Sunset Cyberspace](https://github.com/EvanBacon/Sunset-Cyberspace)
|
320 | - [Game: Crossy Road](https://github.com/EvanBacon/Expo-Crossy-Road)
|
321 | - [Game: Nitro Roll](https://github.com/EvanBacon/Expo-Nitro-Roll)
|
322 | - [Game: Pillar Valley](https://github.com/EvanBacon/Expo-Pillar-Valley)
|
323 | - [Voxel Terrain](https://github.com/EvanBacon/Expo-Voxel)
|
324 |
|
325 | ## 🤝 Contributing
|
326 |
|
327 | Contributions, issues and feature requests are welcome!<br />Feel free to check [issues page](https://github.com/Expo/expo-three/issues).
|
328 |
|
329 | ## Show your support
|
330 |
|
331 | Give a ⭐️ if this project helped you!
|
332 |
|
333 | ## 📝 License
|
334 |
|
335 | Copyright © 2019 [650 Industries](https://expo.io/about).<br />
|
336 | This project is [MIT](https://github.com/Expo/expo-three/blob/master/LICENSE) licensed.
|
337 |
|
\ | No newline at end of file |