使用@react-three/fiber,@mkkellogg/gaussian-splats-3d加载.splat,.ply,.ksplat文件

前言

假设您正在现有项目中集成这些包,而该项目的构建工具为 Webpack 或 Vite。同时,您对 Three.js 和 React 有一定的了解。如果您发现有任何错误或有更好的方法,请随时留言。

安装

cmd 复制代码
npm install three @types/three @react-three/fiber @react-three/drei @mkkellogg/gaussian-splats-3d

设置两个标头

gaussian-splats-3d内部使用WorkerSharedArrayBuffer(共享内存)。

对于顶级文档,需要设置两个标头来实现你网站的跨源隔离:

  • Cross-Origin-Opener-Policy 设置为 same-origin(来保护你的源站点免受攻击)
  • Cross-Origin-Embedder-Policy 设置为 require-corp 或 credentialless(保护受害者免受你的源站点的影响)
webpack设置标头
json 复制代码
{
    "devServer":{
        "headers": {
      "Cross-Origin-Embedder-Policy": "require-corp",
       "Cross-Origin-Opener-Policy": "same-origin"
      }
    }
}
vite设置标头
cmd 复制代码
npm i -D vite-plugin-cross-origin-isolation
js 复制代码
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

js 复制代码
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();
  }, []);
};
js 复制代码
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;

效果

相关推荐
excel几秒前
ES6 中函数的双重调用方式:fn() 与 fn\...``
前端
可乐爱宅着13 分钟前
全栈框架next.js入手指南
前端·next.js
你的人类朋友2 小时前
什么是API签名?
前端·后端·安全
会豪4 小时前
Electron-Vite (一)快速构建桌面应用
前端
中微子4 小时前
React 执行阶段与渲染机制详解(基于 React 18+ 官方文档)
前端
唐某人丶4 小时前
教你如何用 JS 实现 Agent 系统(2)—— 开发 ReAct 版本的“深度搜索”
前端·人工智能·aigc
中微子4 小时前
深入剖析 useState产生的 setState的完整执行流程
前端
遂心_4 小时前
JavaScript 函数参数传递机制:一道经典面试题解析
前端·javascript
小徐_23334 小时前
uni-app vue3 也能使用 Echarts?Wot Starter 是这样做的!
前端·uni-app·echarts
RoyLin4 小时前
TypeScript设计模式:适配器模式
前端·后端·node.js