使用@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;

效果

相关推荐
李贺梖梖4 小时前
CSS学习
前端·css
蚂小蚁5 小时前
一文吃透:宏任务、微任务、事件循环、浏览器渲染、Vue 批处理与 Node 差异(含性能优化)
前端·面试·架构
狼性书生5 小时前
uniapp实现的Tab 选项卡组件模板
前端·uni-app·vue·组件·插件
吃饺子不吃馅5 小时前
前端画布类型编辑器项目,历史记录技术方案调研
前端·架构·github
拜晨5 小时前
使用motion实现小宇宙贴纸墙效果
前端·交互设计
拜晨5 小时前
使用motion实现小宇宙节目广场的效果
前端·交互设计
知花实央l6 小时前
【Web应用实战】 文件上传漏洞实战:Low/Medium/High三级绕过(一句话木马拿webshell全流程)
前端·学习·网络安全·安全架构
华仔啊6 小时前
JavaScript + Web Audio API 打造炫酷音乐可视化效果,让你的网页跟随音乐跳起来
前端·javascript
鸡吃丸子6 小时前
SEO入门
前端