我试图在不使用expo的情况下在react native项目中显示3d模型。所有我能找到的是使用博览会的例子react native。
简短的回答:是的,你可以。
长话短说:你将需要相当多的图书馆,其中一些图书馆来自EXPO。你可以在纯react native中使用expo库,而不需要使用expo CLI。
这是加载3D模型类型。obj与轨道控制的工作代码示例。
import React, { useState, useEffect } from 'react';
import { View } from 'react-native';
import { ExpoWebGLRenderingContext, GLView } from 'expo-gl';
import { resolveAsync } from 'expo-asset-utils';
import * as FileSystem from 'expo-file-system';
import { decode } from 'base64-arraybuffer';
import { Renderer, TextureLoader, loadObjAsync, loadTextureAsync } from 'expo-three';
import OrbitControlsView from 'expo-three-orbit-controls';
import { Asset } from 'expo-asset'
import {
AmbientLight,
BoxGeometry,
Fog,
GridHelper,
Mesh,
MeshStandardMaterial,
PerspectiveCamera,
PointLight,
Scene,
SpotLight,
Camera,
} from 'three';
const ThreeD = () => {
const [camera, setCamera] = useState<Camera | null>(null);
let timeout;
useEffect(() => {
return () => clearTimeout(timeout);
}, []);
const onContextCreate = async (gl: ExpoWebGLRenderingContext) => {
const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;
const sceneColor = 0x6ad6f0;
// Create a WebGLRenderer without a DOM element
const renderer = new Renderer({ gl });
renderer.setSize(width, height);
renderer.setClearColor(sceneColor);
const camera = new PerspectiveCamera(70, width / height, 0.01, 1000);
camera.position.set(2, 5, 5);
setCamera(camera);
const scene = new Scene();
scene.fog = new Fog(sceneColor, 1, 10000);
scene.add(new GridHelper(10, 10));
const ambientLight = new AmbientLight(0xB1B1B1, 1.5);
scene.add(ambientLight);
const spotLight = new SpotLight(0xffffff, 1.5);
spotLight.position.set(0, 200, 200);
spotLight.lookAt(scene.position);
scene.add(spotLight);
const texture = await loadTextureAsync({
asset: require('../assets/3D/model_texture.xpng'),
});
const obj = await loadObjAsync({
asset: require('../assets/3D/model.obj')
});
obj.traverse(function(object) {
if (object instanceof THREE.Mesh) {
object.material.map = texture;
}
});
scene.add(obj);
camera.lookAt(obj.position);
function update() {
obj.rotation.y = 0;
obj.rotation.x = 0;
}
// Setup an animation loop
const render = () => {
timeout = requestAnimationFrame(render);
update();
renderer.render(scene, camera);
gl.endFrameEXP();
};
render();
};
return (
<View style={{flex: 1}}>
<OrbitControlsView style={{ flex: 1 }} camera={camera}>
<GLView style={{ flex: 1 }} onContextCreate={onContextCreate} key="d" />
</OrbitControlsView>
</View>
);
};
export default ThreeD;
这已经在GitHub上讨论过了。所以,我就不多讲了。
你可以去这个评论阅读更多。
你可以使用Three.js在react-native中实现3D模型(gltf, glb, obj…)
的例子:https://github.com/pmndrs/react-three-fiber
import { createRoot } from 'react-dom/client'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
function Box(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => (ref.current.rotation.x += 0.01))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
createRoot(document.getElementById('root')).render(
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
)
你可以在这里找到完整的文档:https://github.com/pmndrs/react-three-fiber
注意:这不是我的代码,我只是把它粘贴在这里供参考。