A React component library for rendering NURBS (Non-Uniform Rational B-Spline) surfaces in Three.js. Built with React Three Fiber, this library provides an easy way to create and visualize complex curved surfaces in your 3D applications.
- 🎯 Simple React component API for NURBS surfaces
- 📐 Support for arbitrary degree NURBS surfaces
- ✂️ Trimmed surfaces with multiple trimming curves
- 🔄 Revolved surfaces with custom axes
- 📈 Lofted surfaces from multiple curves
- 🎨 Customizable surface appearance with R3F materials
- 🔄 Automatic normal calculation for proper lighting
- 🎮 Interactive 3D visualization with React Three Fiber
- 📦 Written in TypeScript with full type support
- 🎨 Compatible with drei's Line component for curves
npm install react-three-nurbsimport { NurbsSurface } from 'react-three-nurbs'
import { Canvas } from '@react-three/fiber'
function App() {
// Define a simple 4x4 control point grid for a surface
const controlPoints = [
[[-1, -1, 0], [-1, -0.5, 0], [-1, 0.5, 0], [-1, 1, 0]],
[[-0.5, -1, 0], [-0.5, -0.5, 1], [-0.5, 0.5, 1], [-0.5, 1, 0]],
[[0.5, -1, 0], [0.5, -0.5, 1], [0.5, 0.5, 1], [0.5, 1, 0]],
[[1, -1, 0], [1, -0.5, 0], [1, 0.5, 0], [1, 1, 0]]
]
// Define weights for each control point (1.0 for uniform B-spline)
const weights = [
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]
]
return (
<Canvas>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<NurbsSurface
controlPoints={controlPoints}
weights={weights}
degreeU={3}
degreeV={3}
color="#ff0000"
wireframe={false}
/>
</Canvas>
)
}import { NurbsSurface } from 'react-three-nurbs'
import { Canvas } from '@react-three/fiber'
import { MeshStandardMaterial } from 'three'
function App() {
// ... control points and weights as above ...
return (
<Canvas>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<NurbsSurface
controlPoints={controlPoints}
weights={weights}
degreeU={3}
degreeV={3}
position={[0, 0, 0]}
rotation={[0, Math.PI / 4, 0]}
>
<meshStandardMaterial
color="#00ff00"
metalness={0.5}
roughness={0.5}
wireframe={true}
/>
</NurbsSurface>
</Canvas>
)
}import { NurbsCurve } from 'react-three-nurbs'
import { Canvas } from '@react-three/fiber'
function App() {
const points = [
[0, 0, 0],
[1, 1, 0],
[2, 0, 0],
[3, 1, 0],
[4, 0, 0],
]
const knots = [0, 0, 0, 0.5, 1, 1, 1]
return (
<Canvas>
<NurbsCurve
points={points}
knots={knots}
degree={2}
color="red"
dashed={true}
segments={true}
vertexColors={[
[1, 0, 0], // red
[0, 1, 0], // green
[0, 0, 1], // blue
[1, 1, 0], // yellow
[1, 0, 1], // magenta
]}
/>
</Canvas>
)
}import { TrimmedSurface, NurbsSurface, NurbsCurve } from 'react-three-nurbs'
import { Canvas } from '@react-three/fiber'
import { DoubleSide } from 'three'
function App() {
// Define control points for the base surface
const controlPoints = [
[[0, 0, 0], [1, 0, 0], [2, 0, 0]],
[[0, 1, 0], [1, 1, 1], [2, 1, 0]],
[[0, 2, 0], [1, 2, 0], [2, 2, 0]]
]
const weights = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]
// Define trimming curve in UV space
const trimPoints = [
[0.2, 0.2],
[0.8, 0.2],
[0.8, 0.8],
[0.2, 0.8]
]
const knots = [0, 0, 0, 0, 1, 1, 1, 1]
return (
<Canvas>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<TrimmedSurface>
<NurbsSurface
controlPoints={controlPoints}
weights={weights}
degreeU={2}
degreeV={2}
/>
<NurbsCurve
points={trimPoints}
knots={knots}
degree={3}
/>
<meshPhongMaterial
color="#ff0000"
side={DoubleSide}
/>
</TrimmedSurface>
</Canvas>
)
}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
controlPoints |
number[][][] |
Yes | - | 3D control points grid defining the surface shape |
weights |
number[][] |
Yes | - | Weights for each control point |
degreeU |
number |
Yes | - | Degree of the surface in U direction |
degreeV |
number |
Yes | - | Degree of the surface in V direction |
color |
string |
No | '#ffffff' |
Surface color (only used if no material is provided) |
wireframe |
boolean |
No | false |
Whether to render as wireframe (only used if no material is provided) |
children |
ReactElement |
No | - | Material component (e.g., meshStandardMaterial, meshPhongMaterial) |
...meshProps |
MeshProps |
No | - | All React Three Fiber mesh props are supported |
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
points |
number[][] |
Yes | - | Control points defining the curve shape |
knots |
number[] |
Yes | - | Knot vector defining the curve parameterization |
degree |
number |
No | 3 |
Degree of the curve |
weights |
number[] |
No | [1, 1, ...] |
Weights for each control point |
curveResolution |
number |
No | 50 |
Number of points to sample along the curve |
color |
string |
No | 'black' |
Line color |
segments |
boolean |
No | false |
Whether to render as line segments |
dashed |
boolean |
No | false |
Whether to render as dashed line |
vertexColors |
number[][] |
No | - | RGB colors for each vertex |
...lineProps |
LineProps |
No | - | All drei Line component props are supported |
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children |
ReactElement[] |
Yes | - | Must contain exactly one NurbsSurface, one or more NurbsCurve components for trimming, and one material component |
...meshProps |
MeshProps |
No | - | All React Three Fiber mesh props are supported |
The TrimmedSurface component requires its children to be in this specific order:
- A
NurbsSurfacecomponent defining the base surface - One or more
NurbsCurvecomponents defining the trimming curves (in UV space) - A material component (e.g.,
meshStandardMaterial,meshPhongMaterial)
This project is built with:
- React
- Three.js
- React Three Fiber
- verb-nurbs for NURBS calculations
- Vite for building
- TypeScript for type safety
# Install dependencies
npm install
# Start development server
npm run dev
# Build the library
npm run build
# Run Storybook
npm run storybookMIT
Contributions are welcome! Please feel free to submit a Pull Request.
