H5小游戏 活跃维护

expo-three

expo/expo-three

在 Expo 上使用 THREE.js 的工具

870
Stars 标星
95
Forks 分支
18
Watchers 关注
103
Open Issues
TypeScript
主要语言
MIT
开源协议
102.5 MB
仓库大小
2 年前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:expo/expo-three
git clone https://github.com/expo/expo-three.git
git clone git@github.com:expo/expo-three.git
README.md master

机器翻译正文由机器翻译自项目原始文档(英文),排版经程序统一处理,可能存在偏差,请以原项目仓库为准。

欢迎来到 Expo & Three.JS 👋

使用 three.js 创建通用 3D 体验的工具 | 在浏览器中尝试!

这个包将 Three.js 与 Expo GL 连接起来——这是一个为 React 中的原生 OpenGL-ES 提供 WebGL 接口的包。总体上,这有助于将 Three.js 中的 DOM 部分抽象出来。

AR 已在 expo-three@5.0.0 中移动到 expo-three-ar

快速开始

使用 expo-three 设置创建一个通用的 React 项目:

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

对于更具声明性的接口,您可以将此包与 react-three-fiber 一起使用。您可以通过以下方式引导它:

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

安装

在 expo-three@5.0.0 及更高版本中,Three.js 是一个对等依赖

yarn add three expo-three expo-gl

用法

将库导入到你的项目文件中:

import { Renderer } from 'expo-three';

从 expo-three 获取 three.js 的全局实例:

import { THREE } from 'expo-three';

🚨 你将需要使用实体设备,因为 iOS 模拟器和 Android 模拟器与 Three.js EXGL 配合不太好。

由于Metro 打包器的一些问题,你可能需要手动定义 Three.js 的全局实例。这很重要,因为 Three.js 并不完全使用 ECMAScript,而是通过副作用修改 THREE 的单个全局实例。

global.THREE = global.THREE || THREE;

创建渲染器

给定一个来自 GLView 的 gl,返回一个 THREE.WebGLRenderer 来向其绘制。

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);
      }}
    />
  );
}

正在加载资产

Metro 打包器无法加载任意文件类型,如 ( .obj , .mtl , .dae 等)。为了支持它们,你必须在项目根目录中创建一个 ./metro.config.js,并添加你想支持的文件扩展名。

metro.config.js

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

所有资源都需要本地 URI 才能加载。您可以使用 expo-asset 来解析本地 URI。

import { Asset } from 'expo-asset';

// Create an Asset from a local resource
const [{ localUri }] = await Asset.loadAsync(require('./image.png'));

正在加载纹理

当你加载了一个资产后,你可以使用它来创建一个 Three.js 纹理。expo-three 提供了一个辅助工具,可以在内部解析该资产并进行其他修改,以支持更广泛的图像类型:

import { TextureLoader } from 'expo-three';

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

可选地,您可以手动从本地 URI 创建纹理(这可能对大多数图像类型不起作用):

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

// Create an Asset from a resource
const [{ localUri }] = await Asset.loadAsync(require('./img.png'));

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

正在加载 obj 模型

请确保为您希望加载的任何模型扩展向您的 metro.config.js 添加支持,然后您可以使用本地 URI 加载模型:

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

const [{ localUri }] = await Asset.loadAsync(require('./model.obj'));

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

ExpoTHREE.loadAsync()

一个基于文件扩展名异步加载文件的函数。

注意:记得更新你的 metro.config.js 以打包不常见的文件类型!

metro.config.js

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

属性

属性 类型 描述
resource PossibleAsset 将异步解析的资源
onProgress (xhr) => void 当发生 xhr 事件时调用的函数
assetProvider () => Promise 每当请求未知资源时调用的函数
PossibleAsset 格式

导出类型 PossibleAsset = Expo.Asset | number | string | AssetFormat;

type PossibleAsset = number | string | Expo.Asset;
  • number:静态文件引用 require('./model.*')
  • Expo.Asset: Expo.Asset
  • string:资源的 URI 路径

返回

根据输入文件的不同,这会返回许多不同的内容。为了获得更可预测的返回值,你应该使用更具体的模型加载器之一。

示例

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

加载器

loadAsync(assetReference, onProgress, onAssetRequested)

一个通用的加载器,可用于加载图像、模型、场景和动画。可选择提供更具体的加载器,复杂性更低。

// 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 })

🚨 已弃用: 使用 JS 模块 three/examples/jsm/loaders/OBJLoader 手动加载 OBJ 文件

属性

  • asset: 一个 obj 模型引用,将使用 AssetUtils.resolveAsync 进行评估
  • mtlAsset: 可选属性,将使用 loadMtlAsync() 加载
  • onAssetRequested: 一个回调,用于评估 asset 和可选的 mtlAsset 中的 URL。如果你提前知道所需的资产,也可以直接传入一个键值字典。
  • materials: 可选,你可以提供一个由 loadMtlAsync() 返回的材质数组
  • onMtlAssetRequested: 如果提供,将用于请求 loadMtlAsync() 中的资产

此函数用于更直接地加载 .obj 模型。当模型格式损坏时,你应该使用此函数进行调试。

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

loadTextureAsync({ 资源 })

🚨 已弃用: 使用 three 的 JS 模块手动加载纹理

属性

  • asset:一个 Expo.Asset,如果 localUri 缺失或资源还未下载,可以使用 AssetUtils.resolveAsync 来评估。

此函数用作将图像加载到纹理中的更直接方法。当你的图像使用诸如 .bmp 这样奇怪的扩展名时,你应该使用此函数进行调试。

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

loadMtlAsync({ asset, onAssetRequested })

🚨 已弃用: 使用 JS 模块 three/examples/jsm/loaders/MTLLoader 手动加载 MTL 文件

属性

  • asset:一个 mtl 材质引用,将使用 AssetUtils.resolveAsync 进行评估
  • onAssetRequested:一个回调,用于评估 asset 中找到的 URL,如果你预先知道所需资源,也可以直接传入一个键值字典。
const materials = await loadMtlAsync({
  asset: require('chef.mtl'),
  onAssetRequested: modelAssets,
});

loadDaeAsync({ 资源, 请求资产回调, 进度回调 })

🚨 已弃用: 使用 JS 模块 three/examples/jsm/loaders/ColladaLoader 手动加载 DAE 文件

属性

  • asset :对 dae 场景的引用,该场景将使用 AssetUtils.resolveAsync 进行评估
  • onAssetRequested :用于评估 asset 内找到的 URL 的回调函数,如果你事先知道所需资源,也可以直接传入键值对字典。
  • onProgress :用于跟踪加载进度的实验性回调函数。
const { scene } = await loadDaeAsync({
  asset: require('chef.dae'),
  onAssetRequested: modelAssets,
  onProgress: () => {},
});

ExpoTHREE.工具

这些是 Three.js 的工具,但使用 Expo 与 Three.js 时并不需要它们。

ExpoTHREE.utils.alignMesh()

属性

type Axis = {
  x?: number,
  y?: number,
  z?: number,
};
属性 类型 描述
网格 &THREE.Mesh 将被操作的网格
轴 ?Axis 设置相对中心轴

示例

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

ExpoTHREE.utils.scaleLongestSideToSize()

属性

属性 类型 描述
mesh &THREE.Mesh 将被操作的网格
size 数字 网格最长边将被缩放到的尺寸

示例

ExpoTHREE.utils.scaleLongestSideToSize(mesh, 3.2);

ExpoTHREE.utils.computeMeshNormals()

用于平滑导入的几何体,特别是从 .obj 模型导入时。

属性

属性 类型 描述
网格 &THREE.Mesh 将被操作的可变(输入输出)网格

示例

ExpoTHREE.utils.computeMeshNormals(mesh);

THREE 扩展

suppressMetroWarnings

一个用于抑制 EXGL 兼容性警告并改为记录这些警告的函数。默认情况下,这在原生环境中是启用的,因为它可能会显著降低 Metro 开发服务器的速度。你需要导入 ExpoTHREE.THREE 全局实例才能使用此功能。默认情况下,该函数在导入时将被激活。

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

运行示例应用

克隆仓库并 cd expo-three 然后运行:

yarn
yarn build
# CMD+C to exit build watch mode
cd example
npx expo prebuild
npx expo run:android # or npx expo run:ios

⛓ 链接

有点过时

🤝 贡献

欢迎贡献、提交问题和功能请求!
欢迎随时查看 问题页面。

显示你的支持

如果这个项目对你有帮助,给一个⭐️吧!

📝 许可证

版权所有 © 2019-2022 650 Industries.
本项目采用 MIT 许可证。

本站来源与版权声明
  • 本文标题:expo-three - 在 Expo 上使用 THREE.js 的工具
  • 本文链接:https://cn121.com/h5game/expo-expo-three.html
  • 原项目:expo/expo-three 版权归原作者 expo 及贡献者所有
  • 收录信息:本站于 2026-10-02 收录本项目,本页所列协议与仓库指标均为收录当时的状态;该日期之后原项目的版本更新与协议变更,本页不作同步。
  • 开源协议:收录时本项目采用 MIT(查看 LICENSE 原文),本站译文为其衍生内容;使用、修改、分发请以该仓库 LICENSE 原文为准。
  • 站点出处:本文首发于 OneTwoOne,收录自 GitHub 开源项目 expo/expo-three。
  • 翻译说明:本页正文为人工智能生成内容——由机器翻译对原项目 README 初译、经程序校验排版,可能存在错漏,请以原项目文档为准。
  • 引用声明:商业转载、第三方聚合或 AI 检索训练引用时,请务必保留以上来源出处、本文永久链接,以及原项目的版权声明与许可信息。
  • 下架通道:若原项目此后变更或收紧了许可协议、或作者/权利人认为本站的收录方式(译文、排版适配、简介翻译等)超出其授权范围,请通过 xyd3302001@163.com 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。