r3f-geometry

安装量: 287
排名: #3141

安装

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

React Three Fiber Geometry Quick Start import { Canvas } from '@react-three/fiber'

function Scene() { return ( ) }

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)

// SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) // High quality // Hemisphere

// PlaneGeometry(width, height, widthSegments, heightSegments) // Subdivided for displacement

// CircleGeometry(radius, segments, thetaStart, thetaLength) // Semicircle

// CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded) // Cone // Hexagonal prism

// ConeGeometry(radius, height, radialSegments, heightSegments, openEnded)

// TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)

// TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q)

// RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments)

Advanced Shapes // CapsuleGeometry(radius, length, capSegments, radialSegments)

// Polyhedrons // radius, detail

// Higher detail = more subdivisions // 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 ( ) }

// 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 ( ) }

// 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 ( ) }

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 /}

  <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 ( ) }

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 ( ) }

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 ( ) }

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 (

  {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 ( ) }

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 ( {({ Sphere, Box, Cone }) => ( <> </> )} ) }

Points (Particle Systems) Basic Points import { Points, Point, PointMaterial } from '@react-three/drei'

function ParticleField() { const count = 5000

return ( {Array.from({ length: count }, (_, i) => ( hsl(${Math.random() * 360}, 100%, 50%)} /> ))} ) }

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 ( ) }

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 ( ) }

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

function CurvedLines() { return ( <> {/ Smooth curve through points /}

  {/* 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

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

function BoxWithEdges() { return ( 15 degrees color="black" /> ) }

// Wireframe material function WireframeBox() { return ( ) }

Text Geometry Using Drei Text3D import { Text3D, Center } from '@react-three/drei'

function Text3DExample() { return (

Hello R3F
) }

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

function CenteredModel() { return (

) }

// With options

{/* Align to top-left */}

// Get bounding info

{ console.log('Dimensions:', width, height, depth) }}>

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

function FitToView() { return ( ) }

function SelectToZoom() { const bounds = useBounds()

return ( { e.stopPropagation() bounds.refresh(e.object).fit() }} > ) }

Performance Tips Reuse geometries: Same geometry instance = better batching Use Instances: For many identical objects Merge static meshes: Use for static scenes Appropriate segment counts: Balance quality vs performance Dispose unused geometry: R3F handles this automatically // Good segment counts // Standard quality // High quality // Performance mode

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

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

返回排行榜