前言
假设您正在现有项目中集成这些包,而该项目的构建工具为 Webpack 或 Vite。同时,您对 Three.js 和 React 有一定的了解。如果您发现有任何错误或有更好的方法,请随时留言。
安装
npm install three @types/three @react-three/fiber @react-three/drei @mkkellogg/gaussian-splats-3d
设置两个标头
gaussian-splats-3d内部使用Worker和SharedArrayBuffer(共享内存)。
对于顶级文档,需要设置两个标头来实现你网站的跨源隔离:
- Cross-Origin-Opener-Policy 设置为 same-origin(来保护你的源站点免受攻击)
- Cross-Origin-Embedder-Policy 设置为 require-corp 或 credentialless(保护受害者免受你的源站点的影响)
webpack设置标头
{"devServer":{"headers": {"Cross-Origin-Embedder-Policy": "require-corp","Cross-Origin-Opener-Policy": "same-origin"}}
}
vite设置标头
npm i -D vite-plugin-cross-origin-isolation
import { defineConfig } from "vite";export default defineConfig({plugins: [{name: "configure-response-headers",configureServer: (server) => {server.middlewares.use((_req, res, next) => {res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");res.setHeader("Cross-Origin-Opener-Policy", "same-origin");next();});},},],
});
创建一个组件
useViewer.ts
import { useCallback, useEffect } from 'react';
import * as GaussianSplats3D from '@mkkellogg/gaussian-splats-3d';
import { Scene } from 'three';interface Options {scene: Scene;
}
export const useViewer= ({ scene }: Options) => {const init = useCallback(() => {const viewer = new GaussianSplats3D.DropInViewer();viewer.addSplatScenes([{path: 'assets/bonsai-7k-mini.splat',splatAlphaRemovalThreshold: 20}],true);scene.add(viewer);}, [scene]);useEffect(() => {init();}, []);
};
import React, { useRef } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { PerspectiveCamera, Scene, Vector3 } from 'three';
import { useViewer } from '@/hooks/useWorkRoom';function setupCamera() {const camera = new PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 500);camera.position.set(0, -4, 0);camera.lookAt(new Vector3().fromArray([0, 0, 0]));camera.up = new Vector3().fromArray([0, -1, -0.6]).normalize();return camera;
}function setupScene() {const scene = new Scene();return scene;
}export const Dashboard = () => {const scene = useRef<Scene>(setupScene());const camera = useRef<PerspectiveCamera>(setupCamera());useViewer({ scene: scene.current });return (<Canvas scene={scene.current} camera={camera.current}><OrbitControls /></Canvas>);
};export default Dashboard;