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

效果

相关推荐
Moment10 分钟前
AI 全栈指南:NestJs 中的 Service Provider 和 Module
前端·后端·面试
IT_陈寒13 分钟前
为什么我的JavaScript异步回调总是乱序执行?
前端·人工智能·后端
Moment16 分钟前
AI全栈入门指南:NestJs 中的 DTO 和数据校验
前端·后端·面试
小码哥_常26 分钟前
告别RecyclerView卡顿!8个优化技巧让列表丝滑如德芙
前端
小村儿36 分钟前
Harness Engineering:为什么你用 AI 越用越累?
前端·后端·ai编程
FrontAI38 分钟前
Next.js从入门到实战保姆级教程:环境配置与项目初始化
react.js·typescript·学习方法
enoughisenough1 小时前
浏览器判断控制台是否开启
前端
Moment1 小时前
当前端开始做 Agent 后,我才知道 LangGraph 有多重要❗❗❗
前端·后端·面试
竹林8181 小时前
RainbowKit 快速集成多链钱包连接:从“连不上”到丝滑切换的踩坑实录
前端·javascript
小蜜蜂dry1 小时前
nestjs实战-登录、鉴权(一)
前端·后端·nestjs