机器翻译正文由机器翻译自项目原始文档(英文),排版经程序统一处理,可能存在偏差,请以原项目仓库为准。
欢迎来到 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.Assetstring:资源的 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 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。