All Projects → expo → Expo Three

expo / Expo Three

Licence: mit
Utilities for using THREE.js on Expo

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Expo Three

Expo Chroma Key Camera
Live green-screen effect with Expo and THREE.js
Stars: ✭ 28 (-93.52%)
Mutual labels:  threejs, expo, arkit
Expo-Nitro-Roll
A cross-platform video game built with Expo and three.js!
Stars: ✭ 16 (-96.3%)
Mutual labels:  threejs, javascript-game, expo
Expo Three Demo
🍎👩‍🏫 Collection of Demos for THREE.js in Expo!
Stars: ✭ 76 (-82.41%)
Mutual labels:  threejs, expo, arkit
Expo Crossy Road
🐥🚙 Crossy Road game clone made in Expo (iOS, Android, web), THREE.js, Tween, React Native. 🐔
Stars: ✭ 701 (+62.27%)
Mutual labels:  threejs, expo
Expo Three Ar
Utilities for using Expo AR with THREE.js
Stars: ✭ 40 (-90.74%)
Mutual labels:  expo, arkit
Sunset Cyberspace
🎮👾Retro-runner Game made in Expo, Three.js, OpenGL, WebGL, Tween. 🕹
Stars: ✭ 54 (-87.5%)
Mutual labels:  threejs, expo
Lego Expo
Play with Lego bricks anywhere using Expo
Stars: ✭ 65 (-84.95%)
Mutual labels:  threejs, expo
Mage
Mage is a 3D Game Engine, built on top of THREE.js. It features Unity-like scripting, AMMO.js powered physics workers, an Infernojs powered UI and a clean API. Under (very) active development.
Stars: ✭ 76 (-82.41%)
Mutual labels:  threejs, javascript-game
expo-three-template
Template for building three.js apps in expo
Stars: ✭ 12 (-97.22%)
Mutual labels:  threejs, expo
Pillar Valley
👾A cross-platform video game built with Expo, three.js, and Firebase! 🎮🕹
Stars: ✭ 242 (-43.98%)
Mutual labels:  threejs, expo
Expo Voxel
🎮🌳 Voxel Terrain made in React Native. ∛
Stars: ✭ 169 (-60.88%)
Mutual labels:  threejs, expo
expo-three-orbit-controls
🎥 Three.js Orbit Controls (Camera) bridged into React Native
Stars: ✭ 43 (-90.05%)
Mutual labels:  threejs, expo
Wizardwarz
WebGL Multiplayer game with NodeJS backend
Stars: ✭ 270 (-37.5%)
Mutual labels:  javascript-game, threejs
Lottery
🎉🌟✨🎈年会抽奖程序,基于 Express + Three.js的 3D 球体抽奖程序,奖品🧧🎁,文字,图片,抽奖规则均可配置,😜抽奖人员信息Excel一键导入😍,抽奖结果Excel导出😎,给你的抽奖活动带来全新酷炫体验🚀🚀🚀
Stars: ✭ 363 (-15.97%)
Mutual labels:  threejs
Game
⚔️ An online JavaScript 2D Medieval RPG.
Stars: ✭ 388 (-10.19%)
Mutual labels:  javascript-game
Tinyconstraints
Nothing but sugar.
Stars: ✭ 3,721 (+761.34%)
Mutual labels:  arkit
Openscope
openScope Air Traffic Control Simulator
Stars: ✭ 358 (-17.13%)
Mutual labels:  javascript-game
React Native Version
🔢 Version your React Native or Expo app in a `npm version` fashion.
Stars: ✭ 408 (-5.56%)
Mutual labels:  expo
Firebase Instagram
📸 Instagram clone with Firebase Cloud Firestore, Expo, and React Native 😁😍
Stars: ✭ 389 (-9.95%)
Mutual labels:  expo
Measure
Using ARKit to make calculate the distance of real-world objects
Stars: ✭ 357 (-17.36%)
Mutual labels:  arkit

Welcome to Expo & Three.JS 👋

Tools for using three.js to create universal 3D experiences | Try it in the browser!

GitHub Actions status

Twitter: expo Medium: exposition

This package bridges Three.js to Expo GL - a package which provides a WebGL interface for native OpenGL-ES in React. Largely this helps with abstracting the DOM parts away from Three.js.

AR was moved to expo-three-ar in [email protected]

Quick Start

Create a universal React project with expo-three setup:

npx create-react-native-app -t with-three

For a more declarative interface, you can use this package with react-three-fiber. You can bootstrap that with:

npx create-react-native-app -t with-react-three-fiber

Installation

In [email protected] Three.js is a peer dependency

yarn add three expo-three expo-gl

Usage

Import the library into your project file:

import { Renderer } from 'expo-three';

Get a global instance of three.js from expo-three:

import { THREE } from 'expo-three';

🚨 You'll need to use a physical device as the iOS Simulators and Android emulators do not work well with Three.js + EXGL.

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.

global.THREE = global.THREE || THREE;

Creating a Renderer

Given a gl from a GLView, return a THREE.WebGLRenderer that draws to it.

import * as React from 'react';
import { ExpoWebGLRenderingContext, GLView } from 'expo-gl';
import { Renderer } from 'expo-three';

export default function App() {
  return (
    <GLView
      style={{ flex: 1 }}
      onContextCreate={(gl: ExpoWebGLRenderingContext) => {
        // Create a WebGLRenderer without a DOM element
        const renderer = new Renderer({ gl });
        renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
      }}
    />
  );
}

Loading assets

The Metro bundler cannot load arbitrary file types like (.obj, .mtl, .dae, etc..). In order to support them you must create a ./metro.config.js in your project root, and add the file extensions you want to support.

metro.config.js

module.exports = {
  resolver: {
    assetExts: ['db', 'mp3', 'ttf', 'obj', 'png', 'jpg'],
  },
};

All assets require a local URI to be loaded. You can resolve a local URI with expo-asset.

import { Asset } from 'expo-asset';

// Create an Asset from a resource
const asset = Asset.fromModule(require('./image.png'));

await asset.downloadAsync();

// This is the local URI
const uri = asset.localUri;

Loading a texture

After you have an asset loaded, you can use it to create a Three.js Texture. expo-three provides a helper utility that can resolve the asset internally and make other modifications to support a wider variety of images:

import { TextureLoader } from 'expo-three';

// This texture will be immediately ready but it'll load asynchronously
const texture = new TextureLoader().load(require('./img.png'));

Optionally, you can create a texture from the local URI manually (this may not work for most image types):

import { TextureLoader } from 'three';
import { Asset } from 'expo-asset';

// Create an Asset from a resource
const asset = Asset.fromModule(require('./img.png'));

await asset.downloadAsync();
// This texture will be immediately ready but it'll load asynchronously
const texture = new TextureLoader().load(asset.localUri);

Loading an obj model

Be sure to add support for whatever model extension you wish to load to your metro.config.js, then you can load a model using the local URI:

// Import from jsm for smaller bundles and faster apps
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { Asset } from 'expo-asset';

const asset = Asset.fromModule(require('./model.obj'));
await asset.downloadAsync();

const loader = new OBJLoader();
loader.load(asset.localUri, group => {
  // Model loaded...
});

ExpoTHREE.loadAsync()

A function that will asynchronously load files based on their extension.

Notice: Remember to update your metro.config.js to bundle obscure file types!

metro.config.js

module.exports = {
  resolver: {
    assetExts: ['db', 'mp3', 'ttf', 'obj', 'png', 'jpg'],
  },
};

Props

Property Type Description
resource PossibleAsset The asset that will be parsed asynchornously
onProgress (xhr) => void A function that is called with an xhr event
assetProvider () => Promise<Expo.Asset> A function that is called whenever an unknown asset is requested
PossibleAsset Format

export type PossibleAsset = Expo.Asset | number | string | AssetFormat;

type PossibleAsset = number | string | Expo.Asset;
  • number: Static file reference require('./model.*')
  • Expo.Asset: Expo.Asset
  • string: A uri path to an asset

Returns

This returns many different things, based on the input file. For a more predictable return value you should use one of the more specific model loaders.

Example

const texture = await ExpoTHREE.loadAsync(
  'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
);

Loaders

loadAsync(assetReference, onProgress, onAssetRequested)

A universal loader that can be used to load images, models, scenes, and animations. Optionally more specific loaders are provided with less complexity.

// A THREE.Texture from a static resource.
const texture = await ExpoTHREE.loadAsync(require('./icon.png'));
const obj = await ExpoTHREE.loadAsync(
  [require('./cartman.obj'), require('./cartman.mtl')],
  null,
  imageName => resources[imageName]
);
const { scene } = await ExpoTHREE.loadAsync(
  resources['./kenny.dae'],
  onProgress,
  resources
);

loadObjAsync({ asset, mtlAsset, materials, onAssetRequested, onMtlAssetRequested })

🚨 Deprecated: Load OBJ files manually with the JS module three/examples/jsm/loaders/OBJLoader

Props

  • asset: a obj model reference that will be evaluated using AssetUtils.resolveAsync
  • mtlAsset: an optional prop that will be loaded using loadMtlAsync()
  • 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.
  • materials: Optionally you can provide an array of materials returned from loadMtlAsync()
  • onMtlAssetRequested: If provided this will be used to request assets in loadMtlAsync()

This function is used as a more direct method to loading a .obj model. You should use this function to debug when your model has a corrupted format.

const mesh = await loadObjAsync({ asset: 'https://www.members.com/chef.obj' });

loadTextureAsync({ asset })

🚨 Deprecated: Load textures manually with the JS module from three

Props

  • asset: an Expo.Asset that could be evaluated using AssetUtils.resolveAsync if localUri is missing or the asset hasn't been downloaded yet.

This function is used as a more direct method to loading an image into a texture. You should use this function to debug when your image is using an odd extension like .bmp.

const texture = await loadTextureAsync({ asset: require('./image.png') });

loadMtlAsync({ asset, onAssetRequested })

🚨 Deprecated: Load MTL files manually with the JS module three/examples/jsm/loaders/MTLLoader

Props

  • asset: a mtl material reference that will be evaluated using AssetUtils.resolveAsync
  • 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.
const materials = await loadMtlAsync({
  asset: require('chef.mtl'),
  onAssetRequested: modelAssets,
});

loadDaeAsync({ asset, onAssetRequested, onProgress })

🚨 Deprecated: Load DAE files manually with the JS module three/examples/jsm/loaders/ColladaLoader

Props

  • asset: a reference to a dae scene that will be evaluated using AssetUtils.resolveAsync
  • 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.
  • onProgress: An experimental callback used to track loading progress.
const { scene } = await loadDaeAsync({
  asset: require('chef.dae'),
  onAssetRequested: modelAssets,
  onProgress: () => {},
});

ExpoTHREE.utils

These are Three.js utilities that aren't required for using Three.js with Expo.

ExpoTHREE.utils.alignMesh()

Props

type Axis = {
  x?: number,
  y?: number,
  z?: number,
};
Property Type Description
mesh &THREE.Mesh The mesh that will be manipulated
axis ?Axis Set the relative center axis

Example

ExpoTHREE.utils.alignMesh(mesh, { x: 0.0, y: 0.5 });

ExpoTHREE.utils.scaleLongestSideToSize()

Props

Property Type Description
mesh &THREE.Mesh The mesh that will be manipulated
size number The size that the longest side of the mesh will be scaled to

Example

ExpoTHREE.utils.scaleLongestSideToSize(mesh, 3.2);

ExpoTHREE.utils.computeMeshNormals()

Used for smoothing imported geometry, specifically when imported from .obj models.

Props

Property Type Description
mesh &THREE.Mesh The mutable (inout) mesh that will be manipulated

Example

ExpoTHREE.utils.computeMeshNormals(mesh);

THREE Extensions

suppressMetroWarnings

A function that suppresses EXGL compatibility warnings and logs them instead. By default this is enabled on native because it can cause the Metro development server to slow down significantly. You will need to import the ExpoTHREE.THREE global instance to use this. By default this function will be activated on import.

  • shouldSuppress: boolean
import { THREE } from 'expo-three';
THREE.suppressMetroWarnings();

⛓ Links

Somewhat out of date

🤝 Contributing

Contributions, issues and feature requests are welcome!
Feel free to check issues page.

Show your support

Give a ⭐️ if this project helped you!

📝 License

Copyright © 2019 650 Industries.
This project is MIT licensed.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].