mcpField
T
threejs-impl-drei

threejs-impl-drei

github.com/impertio-studio开发23145 次安装30 周前更新
代码仓库

关于 threejs-impl-drei

面向 React Three Fiber 开发者的 Drei 实现参考技能,汇总相机控制、环境、阴影、文本、材质和模型加载等组件与 Hooks。也介绍实例化、性能监控及场景布局工具。

主要功能

  1. 01相机控制与场景布置组件
  2. 02环境、灯光与阴影工具
  3. 03文本、HTML 与材质组件
  4. 04模型、纹理和动画加载 Hooks
  5. 05实例化与性能辅助工具

适用场景

  1. 01搭建产品查看器或建筑漫游场景
  2. 02加载 GLTF 模型并播放动画
  3. 03在 3D 场景中添加文本或 HUD
  4. 04优化大量网格和复杂模型的渲染

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/impertio-studio/three.js-claude-skill-package --skill threejs-impl-drei

安装后在 Claude Code 中输入/threejs-impl-drei确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
anti-patterns.md
examples.md
methods.md

详细介绍

threejs-impl-drei

快速参考

安装
npm install @react-three/drei @react-three/fiber three
关键警告

务必将使用加载器 Hook(useGLTF、useTexture、useFBX、useKTX2、useFont)的组件包裹在 <Suspense fallback={...}> 中。省略 Suspense 会导致整个 React 树崩溃。

务必为主要相机控制组件添加 makeDefault(<OrbitControls makeDefault />)。如果没有 makeDefault,Drei 控制组件就无法接入 R3F 的事件系统,指针事件也会失效。

切勿使用无效的 Environment 预设名称。有效预设仅限:apartment、city、dawn、forest、lobby、night、park、studio、sunset、warehouse。

切勿忘记为关键资源调用 .preload()。在模块作用域中使用 useGLTF.preload('/model.glb'),即可在组件挂载前开始加载。

务必使用 <Instances> 渲染超过 100 个相同网格。每个独立网格都会产生一次绘制调用;实例会将它们批量合并为一次调用。


控制组件

OrbitControls

最常用的相机控制组件。围绕目标进行环绕、缩放和平移。

import { OrbitControls } from '@react-three/drei'

<OrbitControls
  makeDefault           // ALWAYS add — integrates with R3F events
  enableDamping         // smooth movement
  dampingFactor={0.05}
  minDistance={2}
  maxDistance={20}
  minPolarAngle={0}
  maxPolarAngle={Math.PI / 2}  // prevent going below ground
/>
其他控制组件
组件使用场景
CameraControls功能全面的相机(适用于复杂场景)
MapControls顶视图地图导航(环绕限制在垂直轴上)
PresentationControls带弹簧物理效果的拖动旋转(产品查看器)
ScrollControls滚动驱动的动画(pages 属性用于设置滚动长度)
TransformControls对选中对象进行平移、旋转和缩放的控件
DragControls在 3D 空间中拖动对象
KeyboardControls将键盘输入作为 React 上下文提供
FaceControls面部追踪相机移动
ScrollControls 模式
import { ScrollControls, useScroll } from '@react-three/drei'

<ScrollControls pages={3} damping={0.1}>
  <ScrollScene />
</ScrollControls>

function ScrollScene() {
  const scroll = useScroll()
  useFrame(() => {
    const offset = scroll.offset // 0 to 1
  })
  return <mesh />
}

环境与布景

Environment

加载 HDR 环境贴图,实现逼真的反射和照明。

import { Environment } from '@react-three/drei'

// Preset (downloads from polyhaven CDN)
<Environment preset="city" background blur={0.5} />

// Custom HDR file
<Environment files="/env.hdr" background />

// Custom environment with Lightformers
<Environment background>
  <Lightformer form="rect" intensity={2} position={[0, 5, -5]} scale={[10, 5, 1]} />
</Environment>

有效预设: apartment、city、dawn、forest、lobby、night、park、studio、sunset、warehouse。

Stage

在一个组件中完成照明和阴影设置,适用于产品查看器。

import { Stage } from '@react-three/drei'

<Stage preset="rembrandt" intensity={0.5} environment="city" adjustCamera>
  <Model />
</Stage>
阴影组件
组件使用场景关键属性
ContactShadows柔和的地面阴影(无需灯光)opacity、scale、blur、far、resolution、color
AccumulativeShadows高质量的烘焙柔和阴影frames、alphaTest、scale、opacity
RandomizedLightAccumulativeShadows 的子组件amount、radius、intensity、position
BakeShadows烘焙阴影贴图后停止更新—
SoftShadows用于实时灯光的 PCSS 柔和阴影—
AccumulativeShadows 模式
<AccumulativeShadows temporal frames={100} scale={10} position={[0, -0.5, 0]}>
  <RandomizedLight amount={8} radius={4} position={[5, 5, -10]} />
</AccumulativeShadows>
大气效果
组件用途关键属性
Sky程序化天空穹顶sunPosition、turbidity、rayleigh
Stars粒子星空radius、count、factor、fade
Sparkles漂浮粒子count、size、speed、color
Cloud体积云opacity、speed、segments、bounds

文本与 HTML

Text(SDF)

通过 troika-three-text 使用有符号距离场渲染的高质量 2D 文本。

import { Text } from '@react-three/drei'

<Text
  fontSize={0.5}
  color="white"
  anchorX="center"
  anchorY="middle"
  maxWidth={2}
  font="/fonts/Inter-Bold.woff"
>
  Hello World
</Text>
Text3D

带挤出效果的 3D 几何文本。需要 JSON 字体文件(使用 facetype.js 转换)。

import { Text3D, Center } from '@react-three/drei'

<Center>
  <Text3D font="/fonts/Inter_Bold.json" size={0.75} height={0.2} bevelEnabled bevelSize={0.02}>
    Hello
    <meshStandardMaterial color="orange" />
  </Text3D>
</Center>
Html

渲染定位在 3D 空间中的 DOM 元素。

import { Html } from '@react-three/drei'

<mesh position={[0, 2, 0]}>
  <Html
    transform            // transforms with 3D position
    distanceFactor={10}  // scales with distance
    occlude              // hides behind 3D objects
    center               // centers the HTML element
    className="label"
  >
    <div style={{ color: 'white' }}>Annotation</div>
  </Html>
</mesh>
Billboard

始终朝向相机。用于标签和精灵。

import { Billboard, Text } from '@react-three/drei'

<Billboard follow={true} lockX={false} lockY={false} lockZ={false}>
  <Text fontSize={0.5}>Always Visible</Text>
</Billboard>
Hud

在独立的正交场景中渲染平视显示界面。

import { Hud, OrthographicCamera } from '@react-three/drei'

<Hud renderPriority={1}>
  <OrthographicCamera makeDefault position={[0, 0, 5]} />
  <Text position={[0, 0, 0]} fontSize={0.1}>HUD Text</Text>
</Hud>

材质

组件用途
MeshReflectorMaterial支持模糊、扭曲和分辨率设置的反射地面
MeshTransmissionMaterial支持色差、扭曲和厚度设置的玻璃
MeshRefractionMaterial使用环境立方体贴图实现折射
MeshWobbleMaterial在 MeshStandardMaterial 上实现动态摇摆效果
MeshDistortMaterial在 MeshStandardMaterial 上实现 Perlin 噪声扭曲
MeshDiscardMaterial不渲染任何内容(仅阴影对象)
shaderMaterial用于将自定义 ShaderMaterial 创建为 JSX 的辅助工具
MeshReflectorMaterial 示例
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
  <planeGeometry args={[50, 50]} />
  <MeshReflectorMaterial
    blur={[300, 100]}
    resolution={1024}
    mixBlur={1}
    mixStrength={50}
    roughness={1}
    depthScale={1.2}
    minDepthThreshold={0.4}
    maxDepthThreshold={1.4}
    color="#151515"
    metalness={0.5}
  />
</mesh>
shaderMaterial 辅助工具
import { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'

const WaveMaterial = shaderMaterial(
  { uTime: 0, uColor: new THREE.Color(0.2, 0.0, 0.1) },
  /* vertex */ `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`,
  /* fragment */ `uniform float uTime; uniform vec3 uColor; varying vec2 vUv; void main() { gl_FragColor = vec4(vUv * uColor, 1.0); }`
)
extend({ WaveMaterial })
// Usage: <waveMaterial uTime={clock.elapsedTime} />

加载器

始终将使用加载器的组件包裹在 <Suspense> 中。

Hook返回值预加载
useGLTF(url){ nodes, materials, scene, animations }useGLTF.preload(url)
useTexture(url)THREE.Texture 或贴图对象useTexture.preload(url)
useFBX(url)THREE.GroupuseFBX.preload(url)
useKTX2(url)压缩纹理useKTX2.preload(url)
useFont(url)用于 Text3D 的字体数据useFont.preload(url)
useAnimations(clips, ref){ actions, names, mixer, ref }—
useVideoTexture(url)THREE.VideoTexture—
useGLTF 用法模式
import { useGLTF } from '@react-three/drei'

function Model(props) {
  const { nodes, materials } = useGLTF('/model.glb')
  return (
    <group {...props}>
      <mesh geometry={nodes.Body.geometry} material={materials.Metal} />
    </group>
  )
}
useGLTF.preload('/model.glb')
useTexture 搭配多个贴图
const textures = useTexture({
  map: '/color.jpg',
  normalMap: '/normal.jpg',
  roughnessMap: '/roughness.jpg',
  aoMap: '/ao.jpg',
})
// Spread directly onto material
<meshStandardMaterial {...textures} />
useAnimations 用法模式
function AnimatedModel() {
  const group = useRef()
  const { nodes, animations } = useGLTF('/character.glb')
  const { actions } = useAnimations(animations, group)

  useEffect(() => {
    actions['Walk']?.play()
    return () => actions['Walk']?.stop()
  }, [actions])

  return <group ref={group}><primitive object={nodes.Scene} /></group>
}

性能

实例

对于大量相同网格(>100),始终使用此功能。可将绘制调用从 N 次减少到 1 次。

import { Instances, Instance } from '@react-three/drei'

<Instances limit={1000} range={1000}>
  <boxGeometry />
  <meshStandardMaterial />
  {positions.map((pos, i) => (
    <Instance key={i} position={pos} color="orange" />
  ))}
</Instances>
合并

将不同几何体合并为一次绘制调用。

import { Merged } from '@react-three/drei'

function Furniture({ nodes }) {
  return (
    <Merged meshes={[nodes.Chair, nodes.Table, nodes.Lamp]}>
      {(Chair, Table, Lamp) => (
        <>
          <Chair position={[0, 0, 0]} />
          <Table position={[2, 0, 0]} />
          <Lamp position={[1, 1, 0]} />
        </>
      )}
    </Merged>
  )
}
性能辅助工具
组件用途
DetailedLOD——根据相机距离切换几何体
BakeShadows烘焙一次阴影,然后停止更新
AdaptiveDpr性能下降时降低设备像素比
AdaptiveEvents性能下降时降低事件触发频率
PerformanceMonitor监控 FPS,并触发性能回归回调
Bvh为复杂网格提供 BVH 加速的光线投射
meshBounds快速包围盒光线投射(替代逐三角形检测)
PerformanceMonitor 用法模式
<PerformanceMonitor
  onIncline={() => setDpr(2)}
  onDecline={() => setDpr(1)}
  flipflops={3}
  onFallback={() => setDpr(0.5)}
/>

布景与布局

组件用途关键属性
Center将子项居中到原点top、right、bottom、left、front、back
Float悬浮动画speed、rotationIntensity、floatIntensity
Bounds根据内容自动调整相机fit、clip、observe、margin
Resize将子项规格化为单位大小width、height、depth

抽象与效果

组件用途
Edges渲染线框边缘
Outlines屏幕空间轮廓
Trail对象后方的运动轨迹
Decal将纹理投射到网格表面
Splat高斯泼溅渲染器
Clone深度克隆,并共享几何体和材质
Image带着色器效果的纹理映射平面
MeshPortalMaterial传送门——在网格表面内渲染场景
GradientTexture程序化渐变纹理

操纵控件

组件用途
GizmoHelper视口方向控件
PivotControls交互式枢轴操纵控件(平移/旋转/缩放)
TransformControlsThree.js TransformControls 封装
Grid可配置的无限网格平面
Helper / useHelper可视化灯光/相机辅助对象

组件选择指南

场景组件
产品查看器Stage + OrbitControls + Environment
建筑漫游CameraControls + Environment + ContactShadows
滚动体验ScrollControls + useScroll
数据可视化Instances + Html + Billboard
3D 文本标签Text(2D)或 Text3D(挤出)+ Billboard
玻璃/透明物体MeshTransmissionMaterial + Environment
反射地板MeshReflectorMaterial
大量相同的网格Instances(>100)或 Merged(混合几何体)
模型加载useGLTF + Suspense + .preload()
HUD/叠加层Hud 或带有 fullscreen 的 Html

参考链接

官方来源

评论

支持 Markdown