Token导航 LogoToken导航

Agent Skill · 前端设计

r3f-geometry(r3f 几何)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

r3f-geometry 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 757。

总安装 12,545周安装 528GitHub Stars 79下载 4,393核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:r3f-geometry(r3f 几何)
来源仓库:https://github.com/enzed/r3f-skills
仓库路径:skills/r3f-geometry
安装命令:
npx skills add https://github.com/enzed/r3f-skills --skill r3f-geometry
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/enzed/r3f-skills --skill r3f-geometry

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

反应三纤维几何形状的内置形状、自定义网格、实例和粒子系统。

Includes 15+ built-in Three.js geometries (box, sphere, cylinder, torus, polyhedrons) plus path-based shapes (lathe, tube, extrude) with configurable segments and parameters 使用顶点、法线、UV 和索引创建自定义 BufferGeometry;支持通过needsUpdate进行动态更新 动画变形标志 Drei 助手通过实例提供方便的形状组件(Box、Sphere、RoundedBox)和高性能实例 并合并 用于渲染数千个相同的对象 用于粒子效果和曲线的点和线系统,包括 CatmullRom、Bézier 和虚线变体;用于线框可视化的边缘组件 用于几何布局和相机拟合的 Text3D、Center 和 Bounds 实用程序;性能技巧强调段数调整和几何重用

来源仓库内路径:skills/r3f-geometry

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/enzed/r3f-skills --skill r3f-geometry;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

r3f-geometry 怎么安装?

在终端执行 npx skills add https://github.com/enzed/r3f-skills --skill r3f-geometry。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

r3f-geometry 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

r3f-geometry 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

r3f-geometry 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

r3f-geometry 用的人多吗?

公开数据是累计安装 12,545 次,近一周安装 528 次,下载 4,393 次,GitHub 79 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

r3f-geometry 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
r3f-geometry

r3f 几何 · 本页

12,54579权限未标注MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

React Three Fiber Geometry

Quick Start

import { Canvas } from '@react-three/fiber'

function Scene() {
  return (
    <Canvas>
      <ambientLight />
      <mesh position={[0, 0, 0]}>
        <boxGeometry args={[1, 1, 1]} />
        <meshStandardMaterial color="hotpink" />
      </mesh>
    </Canvas>
  )
}

Built-in Geometries

All Three.js geometries are available as JSX elements. The args prop passes constructor arguments.

Basic Shapes

// BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)
<boxGeometry args={[1, 1, 1]} />
<boxGeometry args={[2, 1, 0.5, 2, 2, 2]} />

// SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength)
<sphereGeometry args={[1, 32, 32]} />
<sphereGeometry args={[1, 64, 64]} />  // High quality
<sphereGeometry args={[1, 32, 32, 0, Math.PI]} />  // Hemisphere

// PlaneGeometry(width, height, widthSegments, heightSegments)
<planeGeometry args={[10, 10]} />
<planeGeometry args={[10, 10, 32, 32]} />  // Subdivided for displacement

// CircleGeometry(radius, segments, thetaStart, thetaLength)
<circleGeometry args={[1, 32]} />
<circleGeometry args={[1, 32, 0, Math.PI]} />  // Semicircle

// CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded)
<cylinderGeometry args={[1, 1, 2, 32]} />
<cylinderGeometry args={[0, 1, 2, 32]} />  // Cone
<cylinderGeometry args={[1, 1, 2, 6]} />   // Hexagonal prism

// ConeGeometry(radius, height, radialSegments, heightSegments, openEnded)
<coneGeometry args={[1, 2, 32]} />

// TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)
<torusGeometry args={[1, 0.4, 16, 100]} />

// TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q)
<torusKnotGeometry args={[1, 0.4, 100, 16, 2, 3]} />

// RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments)
<ringGeometry args={[0.5, 1, 32]} />

Advanced Shapes

// CapsuleGeometry(radius, length, capSegments, radialSegments)
<capsuleGeometry args={[0.5, 1, 4, 16]} />

// Polyhedrons
<dodecahedronGeometry args={[1, 0]} />  // radius, detail
<icosahedronGeometry args={[1, 0]} />
<octahedronGeometry args={[1, 0]} />
<tetrahedronGeometry args={[1, 0]} />

// Higher detail = more subdivisions
<icosahedronGeometry args={[1, 4]} />  // Approximates sphere

Path-Based Shapes

import * as THREE from 'three'

// LatheGeometry - revolve points around Y axis
function LatheShape() {
  const points = [
    new THREE.Vector2(0, 0),
    new THREE.Vector2(0.5, 0),
    new THREE.Vector2(0.5, 0.5),
    new THREE.Vector2(0.3, 1),
    new THREE.Vector2(0, 1),
  ]

  return (
    <mesh>
      <latheGeometry args={[points, 32]} />
      <meshStandardMaterial color="gold" side={THREE.DoubleSide} />
    </mesh>
  )
}

// TubeGeometry - extrude along a curve
function TubeShape() {
  const curve = new THREE.CatmullRomCurve3([
    new THREE.Vector3(-2, 0, 0),
    new THREE.Vector3(-1, 1, 0),
    new THREE.Vector3(1, -1, 0),
    new THREE.Vector3(2, 0, 0),
  ])

  return (
    <mesh>
      <tubeGeometry args={[curve, 64, 0.2, 8, false]} />
      <meshStandardMaterial color="blue" />
    </mesh>
  )
}

// ExtrudeGeometry - extrude a 2D shape
function ExtrudedShape() {
  const shape = new THREE.Shape()
  shape.moveTo(0, 0)
  shape.lineTo(1, 0)
  shape.lineTo(1, 1)
  shape.lineTo(0, 1)
  shape.lineTo(0, 0)

  const extrudeSettings = {
    steps: 2,
    depth: 0.5,
    bevelEnabled: true,
    bevelThickness: 0.1,
    bevelSize: 0.1,
    bevelSegments: 3,
  }

  return (
    <mesh>
      <extrudeGeometry args={[shape, extrudeSettings]} />
      <meshStandardMaterial color="purple" />
    </mesh>
  )
}

Drei Shape Helpers

@react-three/drei provides convenient shape components.

import {
  Box, Sphere, Plane, Circle, Cylinder, Cone,
  Torus, TorusKnot, Ring, Capsule, Dodecahedron,
  Icosahedron, Octahedron, Tetrahedron, RoundedBox
} from '@react-three/drei'

function DreiShapes() {
  return (
    <>
      {/* All shapes accept mesh props directly */}
      <Box args={[1, 1, 1]} position={[-3, 0, 0]}>
        <meshStandardMaterial color="red" />
      </Box>

      <Sphere args={[0.5, 32, 32]} position={[-1, 0, 0]}>
        <meshStandardMaterial color="blue" />
      </Sphere>

      <Cylinder args={[0.5, 0.5, 1, 32]} position={[1, 0, 0]}>
        <meshStandardMaterial color="green" />
      </Cylinder>

      {/* RoundedBox - box with rounded edges */}
      <RoundedBox
        args={[1, 1, 1]}      // width, height, depth
        radius={0.1}          // border radius
        smoothness={4}        // smoothness of rounded edges
        position={[3, 0, 0]}
      >
        <meshStandardMaterial color="orange" />
      </RoundedBox>
    </>
  )
}

Custom BufferGeometry

Basic Custom Geometry

import { useMemo, useRef } from 'react'
import * as THREE from 'three'

function CustomTriangle() {
  const geometry = useMemo(() => {
    const geo = new THREE.BufferGeometry()

    // Vertices (3 floats per vertex: x, y, z)
    const vertices = new Float32Array([
      -1, -1, 0,  // vertex 0
       1, -1, 0,  // vertex 1
       0,  1, 0,  // vertex 2
    ])

    // Normals (pointing toward camera)
    const normals = new Float32Array([
      0, 0, 1,
      0, 0, 1,
      0, 0, 1,
    ])

    // UVs
    const uvs = new Float32Array([
      0, 0,
      1, 0,
      0.5, 1,
    ])

    geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
    geo.setAttribute('normal', new THREE.BufferAttribute(normals, 3))
    geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))

    return geo
  }, [])

  return (
    <mesh geometry={geometry}>
      <meshStandardMaterial color="cyan" side={THREE.DoubleSide} />
    </mesh>
  )
}

Indexed Geometry

function CustomQuad() {
  const geometry = useMemo(() => {
    const geo = new THREE.BufferGeometry()

    // 4 vertices for a quad
    const vertices = new Float32Array([
      -1, -1, 0,  // 0: bottom-left
       1, -1, 0,  // 1: bottom-right
       1,  1, 0,  // 2: top-right
      -1,  1, 0,  // 3: top-left
    ])

    // Indices to form 2 triangles
    const indices = new Uint16Array([
      0, 1, 2,  // triangle 1
      0, 2, 3,  // triangle 2
    ])

    const normals = new Float32Array([
      0, 0, 1,  0, 0, 1,  0, 0, 1,  0, 0, 1,
    ])

    const uvs = new Float32Array([
      0, 0,  1, 0,  1, 1,  0, 1,
    ])

    geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
    geo.setAttribute('normal', new THREE.BufferAttribute(normals, 3))
    geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
    geo.setIndex(new THREE.BufferAttribute(indices, 1))

    return geo
  }, [])

  return (
    <mesh geometry={geometry}>
      <meshStandardMaterial color="lime" side={THREE.DoubleSide} />
    </mesh>
  )
}

Dynamic Geometry

import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'

function WavyPlane() {
  const meshRef = useRef()

  useFrame(({ clock }) => {
    const positions = meshRef.current.geometry.attributes.position
    const time = clock.elapsedTime

    for (let i = 0; i < positions.count; i++) {
      const x = positions.getX(i)
      const y = positions.getY(i)
      positions.setZ(i, Math.sin(x * 2 + time) * Math.cos(y * 2 + time) * 0.5)
    }

    positions.needsUpdate = true
    meshRef.current.geometry.computeVertexNormals()
  })

  return (
    <mesh ref={meshRef} rotation={[-Math.PI / 2, 0, 0]}>
      <planeGeometry args={[10, 10, 32, 32]} />
      <meshStandardMaterial color="royalblue" side={THREE.DoubleSide} />
    </mesh>
  )
}

Drei Instancing

Efficient rendering of many identical objects.

Instances Component

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

function InstancedBoxes() {
  const count = 1000

  return (
    <Instances limit={count} range={count}>
      <boxGeometry args={[0.5, 0.5, 0.5]} />
      <meshStandardMaterial />

      {Array.from({ length: count }, (_, i) => (
        <AnimatedInstance key={i} index={i} />
      ))}
    </Instances>
  )
}

function AnimatedInstance({ index }) {
  const ref = useRef()

  // Random initial position
  const position = useMemo(() => [
    (Math.random() - 0.5) * 20,
    (Math.random() - 0.5) * 20,
    (Math.random() - 0.5) * 20,
  ], [])

  const color = useMemo(() =>
    ['red', 'blue', 'green', 'yellow', 'purple'][index % 5],
  [index])

  useFrame(({ clock }) => {
    const t = clock.elapsedTime
    ref.current.rotation.x = t + index
    ref.current.rotation.y = t * 0.5 + index
  })

  return (
    <Instance
      ref={ref}
      position={position}
      color={color}
      scale={0.5 + Math.random() * 0.5}
    />
  )
}

Merged Geometry

For static instances, merge geometry for best performance:

import { Merged } from '@react-three/drei'
import { useMemo } from 'react'
import * as THREE from 'three'

function MergedMeshes() {
  // Create geometries to merge
  const meshes = useMemo(() => ({
    Sphere: new THREE.SphereGeometry(0.5, 32, 32),
    Box: new THREE.BoxGeometry(1, 1, 1),
    Cone: new THREE.ConeGeometry(0.5, 1, 32),
  }), [])

  return (
    <Merged meshes={meshes}>
      {({ Sphere, Box, Cone }) => (
        <>
          <Sphere position={[-2, 0, 0]} color="red" />
          <Sphere position={[-2, 2, 0]} color="orange" />
          <Box position={[0, 0, 0]} color="blue" />
          <Box position={[0, 2, 0]} color="cyan" />
          <Cone position={[2, 0, 0]} color="green" />
          <Cone position={[2, 2, 0]} color="lime" />
        </>
      )}
    </Merged>
  )
}

Points (Particle Systems)

Basic Points

import { Points, Point, PointMaterial } from '@react-three/drei'

function ParticleField() {
  const count = 5000

  return (
    <Points limit={count}>
      <PointMaterial
        transparent
        vertexColors
        size={0.05}
        sizeAttenuation
        depthWrite={false}
      />
      {Array.from({ length: count }, (_, i) => (
        <Point
          key={i}
          position={[
            (Math.random() - 0.5) * 10,
            (Math.random() - 0.5) * 10,
            (Math.random() - 0.5) * 10,
          ]}
          color={`hsl(${Math.random() * 360}, 100%, 50%)`}
        />
      ))}
    </Points>
  )
}

Buffer-Based Points (High Performance)

import { useMemo, useRef } from 'react'
import { useFrame } from '@react-three/fiber'
import * as THREE from 'three'

function BufferParticles() {
  const count = 10000
  const pointsRef = useRef()

  const { positions, colors } = useMemo(() => {
    const positions = new Float32Array(count * 3)
    const colors = new Float32Array(count * 3)

    for (let i = 0; i < count; i++) {
      positions[i * 3] = (Math.random() - 0.5) * 10
      positions[i * 3 + 1] = (Math.random() - 0.5) * 10
      positions[i * 3 + 2] = (Math.random() - 0.5) * 10

      colors[i * 3] = Math.random()
      colors[i * 3 + 1] = Math.random()
      colors[i * 3 + 2] = Math.random()
    }

    return { positions, colors }
  }, [])

  useFrame(({ clock }) => {
    pointsRef.current.rotation.y = clock.elapsedTime * 0.1
  })

  return (
    <points ref={pointsRef}>
      <bufferGeometry>
        <bufferAttribute
          attach="attributes-position"
          count={count}
          array={positions}
          itemSize={3}
        />
        <bufferAttribute
          attach="attributes-color"
          count={count}
          array={colors}
          itemSize={3}
        />
      </bufferGeometry>
      <pointsMaterial size={0.05} vertexColors sizeAttenuation />
    </points>
  )
}

Lines

Basic Line

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

function BasicLine() {
  const points = [
    [0, 0, 0],
    [1, 1, 0],
    [2, 0, 0],
    [3, 1, 0],
  ]

  return (
    <Line
      points={points}
      color="red"
      lineWidth={2}
    />
  )
}

Curved Line

import { CatmullRomLine, QuadraticBezierLine, CubicBezierLine } from '@react-three/drei'

function CurvedLines() {
  return (
    <>
      {/* Smooth curve through points */}
      <CatmullRomLine
        points={[[0, 0, 0], [1, 1, 0], [2, 0, 0], [3, 1, 0]]}
        color="blue"
        lineWidth={2}
        segments={64}
      />

      {/* Quadratic bezier */}
      <QuadraticBezierLine
        start={[0, 0, 0]}
        mid={[1, 2, 0]}
        end={[2, 0, 0]}
        color="green"
        lineWidth={2}
      />

      {/* Cubic bezier */}
      <CubicBezierLine
        start={[0, 0, 0]}
        midA={[0.5, 2, 0]}
        midB={[1.5, -1, 0]}
        end={[2, 0, 0]}
        color="purple"
        lineWidth={2}
      />
    </>
  )
}

Dashed Line

<Line
  points={[[0, 0, 0], [5, 0, 0]]}
  color="white"
  lineWidth={2}
  dashed
  dashScale={50}
  dashSize={0.5}
  dashOffset={0}
  gapSize={0.2}
/>

Edges and Wireframe

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

function BoxWithEdges() {
  return (
    <mesh>
      <boxGeometry />
      <meshStandardMaterial color="orange" />
      <Edges
        scale={1.1}
        threshold={15}  // Display edges with angle > 15 degrees
        color="black"
      />
    </mesh>
  )
}

// Wireframe material
function WireframeBox() {
  return (
    <mesh>
      <boxGeometry />
      <meshBasicMaterial color="cyan" wireframe />
    </mesh>
  )
}

Text Geometry

Using Drei Text3D

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

function Text3DExample() {
  return (
    <Center>
      <Text3D
        font="/fonts/helvetiker_regular.typeface.json"
        size={1}
        height={0.2}
        curveSegments={12}
        bevelEnabled
        bevelThickness={0.02}
        bevelSize={0.02}
        bevelOffset={0}
        bevelSegments={5}
      >
        Hello R3F
        <meshStandardMaterial color="gold" />
      </Text3D>
    </Center>
  )
}

Geometry Utilities

Center Geometry

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

function CenteredModel() {
  return (
    <Center>
      <mesh>
        <boxGeometry args={[2, 1, 0.5]} />
        <meshStandardMaterial />
      </mesh>
    </Center>
  )
}

// With options
<Center top left>  {/* Align to top-left */}
  <Model />
</Center>

// Get bounding info
<Center onCentered={({ width, height, depth, boundingBox }) => {
  console.log('Dimensions:', width, height, depth)
}}>
  <Model />
</Center>

Compute Bounds

import { useBounds, Bounds } from '@react-three/drei'

function FitToView() {
  return (
    <Bounds fit clip observe margin={1.2}>
      <SelectToZoom />
    </Bounds>
  )
}

function SelectToZoom() {
  const bounds = useBounds()

  return (
    <mesh
      onClick={(e) => {
        e.stopPropagation()
        bounds.refresh(e.object).fit()
      }}
    >
      <boxGeometry />
      <meshStandardMaterial />
    </mesh>
  )
}

Performance Tips

  1. Reuse geometries: Same geometry instance = better batching
  2. Use Instances: For many identical objects
  3. Merge static meshes: Use <Merged> for static scenes
  4. Appropriate segment counts: Balance quality vs performance
  5. Dispose unused geometry: R3F handles this automatically
// Good segment counts
<sphereGeometry args={[1, 32, 32]} />   // Standard quality
<sphereGeometry args={[1, 64, 64]} />   // High quality
<sphereGeometry args={[1, 16, 16]} />   // Performance mode

// Reuse geometry
const sharedGeometry = useMemo(() => new THREE.BoxGeometry(), [])

<mesh geometry={sharedGeometry} position={[0, 0, 0]} />
<mesh geometry={sharedGeometry} position={[2, 0, 0]} />
<mesh geometry={sharedGeometry} position={[4, 0, 0]} />

See Also

  • r3f-fundamentals - JSX elements and refs
  • r3f-materials - Materials for meshes
  • r3f-shaders - Custom vertex manipulation

平台分布

Claude Code

28.23%
按下载量换算1,240

Cursor

21.56%
按下载量换算947

Codex

19.84%
按下载量换算872

Gemini CLI

12.95%
按下载量换算569

Antigravity

8.13%
按下载量换算357

OpenCode

3.39%
按下载量换算149

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills