r3f-peridot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +333 -0
- package/dist/index.d.mts +125 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.js +817 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +789 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +81 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Christian Dimitri
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# 💎 Peridot
|
|
2
|
+
|
|
3
|
+
### High-Quality Outlines for React Three Fiber - GLTF, IFC & Beyond
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/r3f-peridot)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
**Peridot** brings professional-grade outline rendering to React Three Fiber. Perfect for architectural visualization, BIM workflows, CAD applications, and any 3D model that needs crisp, clean edges.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## ✨ Why Peridot?
|
|
13
|
+
|
|
14
|
+
- 🏗️ **IFC Support** - First-class support for Building Information Modeling (BIM/IFC) files
|
|
15
|
+
- 📦 **GLTF Ready** - Works seamlessly with GLTF/GLB models
|
|
16
|
+
- 🎨 **High-Quality** - Uses advanced depth, normal, and surface ID detection
|
|
17
|
+
- ⚡ **Performant** - Efficient post-processing shader implementation
|
|
18
|
+
- 🎛️ **Customizable** - Full control over outline appearance
|
|
19
|
+
- 🔍 **Debug Modes** - Multiple visualization modes for fine-tuning
|
|
20
|
+
- 📦 **TypeScript** - Full type definitions included
|
|
21
|
+
- 🌲 **Tree-Shakeable** - Optimized bundle size
|
|
22
|
+
|
|
23
|
+
## 🚀 Quick Start
|
|
24
|
+
|
|
25
|
+
### Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install r3f-peridot
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn add r3f-peridot
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm add r3f-peridot
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Basic Usage
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { Canvas } from '@react-three/fiber'
|
|
43
|
+
import { OutlineEffect } from 'r3f-peridot'
|
|
44
|
+
|
|
45
|
+
function Scene() {
|
|
46
|
+
return (
|
|
47
|
+
<Canvas>
|
|
48
|
+
<OutlineEffect outlineColor="#ffffff" />
|
|
49
|
+
|
|
50
|
+
{/* Your 3D content */}
|
|
51
|
+
<mesh>
|
|
52
|
+
<boxGeometry />
|
|
53
|
+
<meshStandardMaterial />
|
|
54
|
+
</mesh>
|
|
55
|
+
</Canvas>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### With GLTF Models
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { useGLTF } from '@react-three/drei'
|
|
64
|
+
import { OutlineEffect } from 'r3f-peridot'
|
|
65
|
+
|
|
66
|
+
function Model() {
|
|
67
|
+
const { scene } = useGLTF('/model.glb')
|
|
68
|
+
return <primitive object={scene} />
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function App() {
|
|
72
|
+
return (
|
|
73
|
+
<Canvas>
|
|
74
|
+
<OutlineEffect outlineColor="#00ff00" />
|
|
75
|
+
<Model />
|
|
76
|
+
</Canvas>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### With IFC Models 🏗️
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { IFCLoader } from 'web-ifc-three/IFCLoader'
|
|
85
|
+
import { OutlineEffect } from 'r3f-peridot'
|
|
86
|
+
import { useEffect, useState } from 'react'
|
|
87
|
+
|
|
88
|
+
function IFCModel({ url }) {
|
|
89
|
+
const [model, setModel] = useState(null)
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
const loader = new IFCLoader()
|
|
93
|
+
loader.load(url, setModel)
|
|
94
|
+
}, [url])
|
|
95
|
+
|
|
96
|
+
return model ? <primitive object={model} /> : null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function App() {
|
|
100
|
+
return (
|
|
101
|
+
<Canvas>
|
|
102
|
+
<OutlineEffect
|
|
103
|
+
outlineColor="#0080ff"
|
|
104
|
+
depthMultiplier={25.0}
|
|
105
|
+
/>
|
|
106
|
+
<IFCModel url="/building.ifc" />
|
|
107
|
+
</Canvas>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 📖 API Reference
|
|
113
|
+
|
|
114
|
+
### `<OutlineEffect />`
|
|
115
|
+
|
|
116
|
+
The main component that adds outline post-processing to your R3F scene.
|
|
117
|
+
|
|
118
|
+
#### Props
|
|
119
|
+
|
|
120
|
+
| Prop | Type | Default | Description |
|
|
121
|
+
|------|------|---------|-------------|
|
|
122
|
+
| `enabled` | `boolean` | `true` | Enable or disable the effect |
|
|
123
|
+
| `outlineColor` | `string \| THREE.Color` | `'#ffffff'` | Color of the outline |
|
|
124
|
+
| `depthBias` | `number` | `0.9` | Bias for depth-based edge detection (0-2) |
|
|
125
|
+
| `depthMultiplier` | `number` | `20.0` | Multiplier for depth-based edges (0-50) |
|
|
126
|
+
| `normalBias` | `number` | `1.0` | Bias for normal-based edge detection (0-2) |
|
|
127
|
+
| `normalMultiplier` | `number` | `1.0` | Multiplier for normal-based edges (0-10) |
|
|
128
|
+
| `debugVisualize` | `number` | `0` | Debug visualization mode (see below) |
|
|
129
|
+
|
|
130
|
+
#### Debug Visualization Modes
|
|
131
|
+
|
|
132
|
+
- `0` - **Outlines V2** (Surface ID based) - Best for CAD/BIM models
|
|
133
|
+
- `1` - **Outlines V1** (Depth/Normal based) - Alternative method
|
|
134
|
+
- `2` - **Original Scene** - No outline effect
|
|
135
|
+
- `3` - **Depth Buffer** - Visualize depth information
|
|
136
|
+
- `4` - **Normal Buffer** - Visualize normal information
|
|
137
|
+
- `5` - **Surface ID Buffer** - Visualize surface IDs (random colors)
|
|
138
|
+
- `6` - **Outlines Only** - Show only the outline effect
|
|
139
|
+
|
|
140
|
+
## 🎨 Advanced Usage
|
|
141
|
+
|
|
142
|
+
### Custom Outline Colors
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
import * as THREE from 'three'
|
|
146
|
+
|
|
147
|
+
// Using hex string
|
|
148
|
+
<OutlineEffect outlineColor="#ff0000" />
|
|
149
|
+
|
|
150
|
+
// Using THREE.Color
|
|
151
|
+
<OutlineEffect outlineColor={new THREE.Color('hotpink')} />
|
|
152
|
+
|
|
153
|
+
// Dynamic colors
|
|
154
|
+
const [color, setColor] = useState('#00ff00')
|
|
155
|
+
<OutlineEffect outlineColor={color} />
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Fine-Tuning for Different Models
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
// For architectural/BIM models (IFC)
|
|
162
|
+
<OutlineEffect
|
|
163
|
+
outlineColor="#0080ff"
|
|
164
|
+
depthBias={0.8}
|
|
165
|
+
depthMultiplier={25.0}
|
|
166
|
+
debugVisualize={0} // Use Surface ID mode
|
|
167
|
+
/>
|
|
168
|
+
|
|
169
|
+
// For organic/smooth models
|
|
170
|
+
<OutlineEffect
|
|
171
|
+
outlineColor="#ffffff"
|
|
172
|
+
depthBias={1.2}
|
|
173
|
+
depthMultiplier={15.0}
|
|
174
|
+
normalMultiplier={1.5}
|
|
175
|
+
debugVisualize={1} // Use Depth/Normal mode
|
|
176
|
+
/>
|
|
177
|
+
|
|
178
|
+
// For mechanical/CAD models
|
|
179
|
+
<OutlineEffect
|
|
180
|
+
outlineColor="#000000"
|
|
181
|
+
depthBias={0.6}
|
|
182
|
+
depthMultiplier={30.0}
|
|
183
|
+
debugVisualize={0} // Use Surface ID mode
|
|
184
|
+
/>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Conditional Outlines
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
function Scene() {
|
|
191
|
+
const [showOutlines, setShowOutlines] = useState(true)
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<Canvas>
|
|
195
|
+
<OutlineEffect enabled={showOutlines} />
|
|
196
|
+
{/* Your scene */}
|
|
197
|
+
</Canvas>
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 🏗️ IFC & BIM Workflows
|
|
203
|
+
|
|
204
|
+
Peridot is designed with AEC (Architecture, Engineering, Construction) workflows in mind:
|
|
205
|
+
|
|
206
|
+
### Perfect for:
|
|
207
|
+
- 📐 **Architectural Visualization** - Clean edges for buildings
|
|
208
|
+
- 🏢 **BIM Model Review** - Clear element boundaries
|
|
209
|
+
- 🏗️ **Construction Planning** - Highlight different components
|
|
210
|
+
- 📊 **Facility Management** - Visual clarity for complex structures
|
|
211
|
+
- 🎓 **Educational Content** - Clear technical drawings
|
|
212
|
+
|
|
213
|
+
### IFC Best Practices
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
// Recommended settings for IFC models
|
|
217
|
+
<OutlineEffect
|
|
218
|
+
outlineColor="#003366" // Professional dark blue
|
|
219
|
+
depthBias={0.8}
|
|
220
|
+
depthMultiplier={25.0}
|
|
221
|
+
normalBias={1.0}
|
|
222
|
+
normalMultiplier={1.0}
|
|
223
|
+
debugVisualize={0} // Surface ID mode for clean element separation
|
|
224
|
+
/>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## 🛠️ Utility Functions
|
|
228
|
+
|
|
229
|
+
### `FindSurfaces`
|
|
230
|
+
|
|
231
|
+
Computes surface IDs for meshes based on vertex connectivity.
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
import { FindSurfaces } from 'r3f-peridot'
|
|
235
|
+
|
|
236
|
+
const findSurfaces = new FindSurfaces()
|
|
237
|
+
const surfaceIdAttribute = findSurfaces.getSurfaceIdAttribute(mesh)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### `weldVertices`
|
|
241
|
+
|
|
242
|
+
Merges vertices along edges for improved outline quality.
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import { weldVertices } from 'r3f-peridot'
|
|
246
|
+
|
|
247
|
+
const newIndices = weldVertices(vertices, indices, thresholdAngle)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### `CustomOutlinePass`
|
|
251
|
+
|
|
252
|
+
Direct access to the Three.js post-processing pass.
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
import { CustomOutlinePass } from 'r3f-peridot'
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## 🎯 Examples
|
|
259
|
+
|
|
260
|
+
Check out the `/examples` directory for complete working examples:
|
|
261
|
+
|
|
262
|
+
- **Basic Example** - Simple scene with primitive geometry
|
|
263
|
+
- **GLTF Models** - Loading and outlining GLTF/GLB files
|
|
264
|
+
- **IFC Models** - Working with Building Information Models
|
|
265
|
+
- **Interactive Controls** - Real-time parameter adjustment
|
|
266
|
+
|
|
267
|
+
To run examples locally:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
cd examples
|
|
271
|
+
npm install
|
|
272
|
+
npm run dev
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## 🎓 How It Works
|
|
276
|
+
|
|
277
|
+
Peridot uses the [webgl-outlines technique](https://github.com/OmarShehata/webgl-outlines) by Omar Shehata:
|
|
278
|
+
|
|
279
|
+
1. **Render Passes** - Scene is rendered to depth, normal, and surface ID buffers
|
|
280
|
+
2. **Edge Detection** - Post-process shader detects edges based on buffer differences
|
|
281
|
+
3. **Outline Rendering** - Detected edges are rendered as colored outlines
|
|
282
|
+
4. **Anti-Aliasing** - FXAA pass ensures smooth, crisp edges
|
|
283
|
+
|
|
284
|
+
This approach provides:
|
|
285
|
+
- ✅ High-quality outlines on any geometry
|
|
286
|
+
- ✅ No special mesh preparation required
|
|
287
|
+
- ✅ Works with any material
|
|
288
|
+
- ✅ Minimal performance impact
|
|
289
|
+
|
|
290
|
+
## 📊 Performance
|
|
291
|
+
|
|
292
|
+
- **Bundle Size**: ~27 KB (minified)
|
|
293
|
+
- **Runtime**: < 1ms per frame (typical)
|
|
294
|
+
- **Memory**: Minimal overhead (2-3 render targets)
|
|
295
|
+
- **Compatibility**: WebGL 2.0+ required
|
|
296
|
+
|
|
297
|
+
## 🤝 Contributing
|
|
298
|
+
|
|
299
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
300
|
+
|
|
301
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
302
|
+
|
|
303
|
+
## 📝 License
|
|
304
|
+
|
|
305
|
+
MIT © Christian Dimitri
|
|
306
|
+
|
|
307
|
+
## 🙏 Acknowledgments
|
|
308
|
+
|
|
309
|
+
- [Omar Shehata](https://github.com/OmarShehata) for the original [webgl-outlines](https://github.com/OmarShehata/webgl-outlines) technique
|
|
310
|
+
- [Three.js](https://threejs.org/) for the amazing 3D library
|
|
311
|
+
- [React Three Fiber](https://docs.pmnd.rs/react-three-fiber) for the React renderer
|
|
312
|
+
- [IFC.js](https://ifcjs.github.io/info/) for IFC support
|
|
313
|
+
|
|
314
|
+
## 📚 Resources
|
|
315
|
+
|
|
316
|
+
- [Documentation](https://github.com/yourusername/r3f-peridot#readme)
|
|
317
|
+
- [Examples](https://github.com/yourusername/r3f-peridot/tree/main/examples)
|
|
318
|
+
- [Issues](https://github.com/yourusername/r3f-peridot/issues)
|
|
319
|
+
- [WebGL Outlines Blog Post](https://omar-shehata.medium.com/how-to-render-outlines-in-webgl-8253c14724f9)
|
|
320
|
+
|
|
321
|
+
## 🌟 Show Your Support
|
|
322
|
+
|
|
323
|
+
If you find Peridot useful, please:
|
|
324
|
+
- ⭐ Star the repository
|
|
325
|
+
- 🐦 Share on social media
|
|
326
|
+
- 📝 Write a blog post
|
|
327
|
+
- 🎥 Create a tutorial
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
**Made with 💚 for the open source community**
|
|
332
|
+
|
|
333
|
+
*"Precision outlines for every model" - Peridot* 💎
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { Pass, FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
4
|
+
|
|
5
|
+
interface OutlineEffectProps {
|
|
6
|
+
/** Enable or disable the outline effect */
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
/** Color of the outline (THREE.Color or hex string) */
|
|
9
|
+
outlineColor?: THREE.Color | string;
|
|
10
|
+
/** Depth bias for edge detection (default: 0.9) */
|
|
11
|
+
depthBias?: number;
|
|
12
|
+
/** Depth multiplier for edge detection (default: 20.0) */
|
|
13
|
+
depthMultiplier?: number;
|
|
14
|
+
/** Normal bias for edge detection (default: 1.0) */
|
|
15
|
+
normalBias?: number;
|
|
16
|
+
/** Normal multiplier for edge detection (default: 1.0) */
|
|
17
|
+
normalMultiplier?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Debug visualization mode (default: 0)
|
|
20
|
+
* - 0: Outlines V2 (surface ID based)
|
|
21
|
+
* - 1: Outlines V1 (depth/normal based)
|
|
22
|
+
* - 2: Original scene
|
|
23
|
+
* - 3: Depth buffer
|
|
24
|
+
* - 4: Normal buffer
|
|
25
|
+
* - 5: SurfaceID debug buffer
|
|
26
|
+
* - 6: Outlines only V2
|
|
27
|
+
*/
|
|
28
|
+
debugVisualize?: number;
|
|
29
|
+
/** Array of objects to apply outlines to (currently not used, reserved for future) */
|
|
30
|
+
selectedObjects?: THREE.Object3D[];
|
|
31
|
+
}
|
|
32
|
+
interface OutlineEffectRef {
|
|
33
|
+
/** Update the maximum surface ID for proper normalization */
|
|
34
|
+
updateMaxSurfaceId: (maxSurfaceId: number) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* OutlineEffect - A React Three Fiber component that adds post-processing outline effects
|
|
38
|
+
* to your 3D scene using depth, normals, and surface ID detection.
|
|
39
|
+
*
|
|
40
|
+
* Based on the webgl-outlines technique by Omar Shehata
|
|
41
|
+
* https://github.com/OmarShehata/webgl-outlines
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* import { Canvas } from '@react-three/fiber'
|
|
46
|
+
* import { OutlineEffect } from 'r3f-gltf-outlines'
|
|
47
|
+
*
|
|
48
|
+
* function Scene() {
|
|
49
|
+
* return (
|
|
50
|
+
* <>
|
|
51
|
+
* <OutlineEffect
|
|
52
|
+
* outlineColor="#ffffff"
|
|
53
|
+
* depthBias={0.9}
|
|
54
|
+
* depthMultiplier={20.0}
|
|
55
|
+
* />
|
|
56
|
+
* <mesh>
|
|
57
|
+
* <boxGeometry />
|
|
58
|
+
* <meshStandardMaterial />
|
|
59
|
+
* </mesh>
|
|
60
|
+
* </>
|
|
61
|
+
* )
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare const OutlineEffect: react.ForwardRefExoticComponent<OutlineEffectProps & react.RefAttributes<OutlineEffectRef>>;
|
|
66
|
+
|
|
67
|
+
declare class FindSurfaces {
|
|
68
|
+
surfaceId: number;
|
|
69
|
+
constructor();
|
|
70
|
+
getSurfaceIdAttribute(mesh: THREE.Mesh): Float32Array;
|
|
71
|
+
_generateSurfaceIds(mesh: THREE.Mesh): {
|
|
72
|
+
[key: number]: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
declare function getSurfaceIdMaterial(): THREE.ShaderMaterial;
|
|
77
|
+
declare function getDebugSurfaceIdMaterial(): THREE.ShaderMaterial;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* CustomOutlinePass - A post-processing pass that renders outlines based on depth,
|
|
81
|
+
* normals, and surface IDs.
|
|
82
|
+
*
|
|
83
|
+
* Based on the webgl-outlines technique by Omar Shehata
|
|
84
|
+
* https://github.com/OmarShehata/webgl-outlines
|
|
85
|
+
*/
|
|
86
|
+
declare class CustomOutlinePass extends Pass {
|
|
87
|
+
renderScene: THREE.Scene;
|
|
88
|
+
renderCamera: THREE.Camera;
|
|
89
|
+
resolution: THREE.Vector2;
|
|
90
|
+
fsQuad: FullScreenQuad;
|
|
91
|
+
surfaceBuffer: THREE.WebGLRenderTarget;
|
|
92
|
+
normalOverrideMaterial: THREE.MeshNormalMaterial;
|
|
93
|
+
surfaceIdOverrideMaterial: THREE.ShaderMaterial;
|
|
94
|
+
surfaceIdDebugOverrideMaterial: THREE.ShaderMaterial;
|
|
95
|
+
constructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera);
|
|
96
|
+
dispose(): void;
|
|
97
|
+
updateMaxSurfaceId(maxSurfaceId: number): void;
|
|
98
|
+
setSize(width: number, height: number): void;
|
|
99
|
+
getDebugVisualizeValue(): any;
|
|
100
|
+
isUsingSurfaceIds(): boolean;
|
|
101
|
+
render(renderer: THREE.WebGLRenderer, writeBuffer: THREE.WebGLRenderTarget, readBuffer: THREE.WebGLRenderTarget): void;
|
|
102
|
+
get vertexShader(): string;
|
|
103
|
+
get fragmentShader(): string;
|
|
104
|
+
createOutlinePostProcessMaterial(): THREE.ShaderMaterial;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Merges together vertices along the edges between triangles
|
|
109
|
+
* whose angle is below the given threshold.
|
|
110
|
+
*
|
|
111
|
+
* @param {number[]} vertices - Array of (x,y,z) positions as a flat list.
|
|
112
|
+
* @param {number[]} indices - Array of indices of (v1, v2, v3) that define the triangles.
|
|
113
|
+
* @param {number} [thresholdAngle=1] - In degrees. When the angle between the face normals
|
|
114
|
+
* of 2 triangles is less than this threshold, the vertices along their shared edge are merged.
|
|
115
|
+
* @returns {number[]} - A new index buffer without the extra vertices.
|
|
116
|
+
*/
|
|
117
|
+
declare function weldVertices(vertices: number[], indices: number[], thresholdAngle?: number): number[];
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Hook that computes and applies surface IDs to all meshes in the scene
|
|
121
|
+
* This is required for outline V2 (surface ID based outlines) to work
|
|
122
|
+
*/
|
|
123
|
+
declare function useSurfaceIds(enabled?: boolean): void;
|
|
124
|
+
|
|
125
|
+
export { CustomOutlinePass, FindSurfaces, OutlineEffect, type OutlineEffectProps, type OutlineEffectRef, getDebugSurfaceIdMaterial, getSurfaceIdMaterial, useSurfaceIds, weldVertices };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { Pass, FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
4
|
+
|
|
5
|
+
interface OutlineEffectProps {
|
|
6
|
+
/** Enable or disable the outline effect */
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
/** Color of the outline (THREE.Color or hex string) */
|
|
9
|
+
outlineColor?: THREE.Color | string;
|
|
10
|
+
/** Depth bias for edge detection (default: 0.9) */
|
|
11
|
+
depthBias?: number;
|
|
12
|
+
/** Depth multiplier for edge detection (default: 20.0) */
|
|
13
|
+
depthMultiplier?: number;
|
|
14
|
+
/** Normal bias for edge detection (default: 1.0) */
|
|
15
|
+
normalBias?: number;
|
|
16
|
+
/** Normal multiplier for edge detection (default: 1.0) */
|
|
17
|
+
normalMultiplier?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Debug visualization mode (default: 0)
|
|
20
|
+
* - 0: Outlines V2 (surface ID based)
|
|
21
|
+
* - 1: Outlines V1 (depth/normal based)
|
|
22
|
+
* - 2: Original scene
|
|
23
|
+
* - 3: Depth buffer
|
|
24
|
+
* - 4: Normal buffer
|
|
25
|
+
* - 5: SurfaceID debug buffer
|
|
26
|
+
* - 6: Outlines only V2
|
|
27
|
+
*/
|
|
28
|
+
debugVisualize?: number;
|
|
29
|
+
/** Array of objects to apply outlines to (currently not used, reserved for future) */
|
|
30
|
+
selectedObjects?: THREE.Object3D[];
|
|
31
|
+
}
|
|
32
|
+
interface OutlineEffectRef {
|
|
33
|
+
/** Update the maximum surface ID for proper normalization */
|
|
34
|
+
updateMaxSurfaceId: (maxSurfaceId: number) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* OutlineEffect - A React Three Fiber component that adds post-processing outline effects
|
|
38
|
+
* to your 3D scene using depth, normals, and surface ID detection.
|
|
39
|
+
*
|
|
40
|
+
* Based on the webgl-outlines technique by Omar Shehata
|
|
41
|
+
* https://github.com/OmarShehata/webgl-outlines
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* import { Canvas } from '@react-three/fiber'
|
|
46
|
+
* import { OutlineEffect } from 'r3f-gltf-outlines'
|
|
47
|
+
*
|
|
48
|
+
* function Scene() {
|
|
49
|
+
* return (
|
|
50
|
+
* <>
|
|
51
|
+
* <OutlineEffect
|
|
52
|
+
* outlineColor="#ffffff"
|
|
53
|
+
* depthBias={0.9}
|
|
54
|
+
* depthMultiplier={20.0}
|
|
55
|
+
* />
|
|
56
|
+
* <mesh>
|
|
57
|
+
* <boxGeometry />
|
|
58
|
+
* <meshStandardMaterial />
|
|
59
|
+
* </mesh>
|
|
60
|
+
* </>
|
|
61
|
+
* )
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare const OutlineEffect: react.ForwardRefExoticComponent<OutlineEffectProps & react.RefAttributes<OutlineEffectRef>>;
|
|
66
|
+
|
|
67
|
+
declare class FindSurfaces {
|
|
68
|
+
surfaceId: number;
|
|
69
|
+
constructor();
|
|
70
|
+
getSurfaceIdAttribute(mesh: THREE.Mesh): Float32Array;
|
|
71
|
+
_generateSurfaceIds(mesh: THREE.Mesh): {
|
|
72
|
+
[key: number]: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
declare function getSurfaceIdMaterial(): THREE.ShaderMaterial;
|
|
77
|
+
declare function getDebugSurfaceIdMaterial(): THREE.ShaderMaterial;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* CustomOutlinePass - A post-processing pass that renders outlines based on depth,
|
|
81
|
+
* normals, and surface IDs.
|
|
82
|
+
*
|
|
83
|
+
* Based on the webgl-outlines technique by Omar Shehata
|
|
84
|
+
* https://github.com/OmarShehata/webgl-outlines
|
|
85
|
+
*/
|
|
86
|
+
declare class CustomOutlinePass extends Pass {
|
|
87
|
+
renderScene: THREE.Scene;
|
|
88
|
+
renderCamera: THREE.Camera;
|
|
89
|
+
resolution: THREE.Vector2;
|
|
90
|
+
fsQuad: FullScreenQuad;
|
|
91
|
+
surfaceBuffer: THREE.WebGLRenderTarget;
|
|
92
|
+
normalOverrideMaterial: THREE.MeshNormalMaterial;
|
|
93
|
+
surfaceIdOverrideMaterial: THREE.ShaderMaterial;
|
|
94
|
+
surfaceIdDebugOverrideMaterial: THREE.ShaderMaterial;
|
|
95
|
+
constructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera);
|
|
96
|
+
dispose(): void;
|
|
97
|
+
updateMaxSurfaceId(maxSurfaceId: number): void;
|
|
98
|
+
setSize(width: number, height: number): void;
|
|
99
|
+
getDebugVisualizeValue(): any;
|
|
100
|
+
isUsingSurfaceIds(): boolean;
|
|
101
|
+
render(renderer: THREE.WebGLRenderer, writeBuffer: THREE.WebGLRenderTarget, readBuffer: THREE.WebGLRenderTarget): void;
|
|
102
|
+
get vertexShader(): string;
|
|
103
|
+
get fragmentShader(): string;
|
|
104
|
+
createOutlinePostProcessMaterial(): THREE.ShaderMaterial;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Merges together vertices along the edges between triangles
|
|
109
|
+
* whose angle is below the given threshold.
|
|
110
|
+
*
|
|
111
|
+
* @param {number[]} vertices - Array of (x,y,z) positions as a flat list.
|
|
112
|
+
* @param {number[]} indices - Array of indices of (v1, v2, v3) that define the triangles.
|
|
113
|
+
* @param {number} [thresholdAngle=1] - In degrees. When the angle between the face normals
|
|
114
|
+
* of 2 triangles is less than this threshold, the vertices along their shared edge are merged.
|
|
115
|
+
* @returns {number[]} - A new index buffer without the extra vertices.
|
|
116
|
+
*/
|
|
117
|
+
declare function weldVertices(vertices: number[], indices: number[], thresholdAngle?: number): number[];
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Hook that computes and applies surface IDs to all meshes in the scene
|
|
121
|
+
* This is required for outline V2 (surface ID based outlines) to work
|
|
122
|
+
*/
|
|
123
|
+
declare function useSurfaceIds(enabled?: boolean): void;
|
|
124
|
+
|
|
125
|
+
export { CustomOutlinePass, FindSurfaces, OutlineEffect, type OutlineEffectProps, type OutlineEffectRef, getDebugSurfaceIdMaterial, getSurfaceIdMaterial, useSurfaceIds, weldVertices };
|