fix: convert apps/website from submodule to regular directory

This commit is contained in:
yeuimu
2026-07-16 01:42:45 +08:00
parent f12ae12ad3
commit 9595030625
341 changed files with 50808 additions and 1 deletions
+125
View File
@@ -0,0 +1,125 @@
---
name: tresjs
description: Use when building 3D scenes with TresJS (Vue Three.js) - provides TresCanvas, composables (useTres, useLoop), Cientos helpers (OrbitControls, useGLTF, Environment), and post-processing effects
license: MIT
---
# TresJS
Vue 3 framework for building 3D scenes with Three.js. Declarative components that wrap Three.js objects.
**Packages:** `@tresjs/core` (required), `@tresjs/cientos` (helpers), `@tresjs/post-processing` (effects)
## Installation
```bash
# Core (required)
pnpm add three @tresjs/core
# Helpers - controls, loaders, materials, staging
pnpm add @tresjs/cientos
# Post-processing effects
pnpm add @tresjs/post-processing
```
## Quick Reference
| Working on... | Load file |
| ---------------------------- | ---------------------- |
| TresCanvas, useTres, useLoop | references/core.md |
| Controls, loaders, materials | references/cientos.md |
| Bloom, glitch, DOF effects | references/effects.md |
| Common patterns, recipes | references/cookbook.md |
## Loading Files
**Load based on your task:**
- [ ] [references/core.md](references/core.md) - TresCanvas setup, composables, events, primitives
- [ ] [references/cientos.md](references/cientos.md) - OrbitControls, useGLTF, Environment, materials
- [ ] [references/effects.md](references/effects.md) - EffectComposer, bloom, glitch, DOF
- [ ] [references/cookbook.md](references/cookbook.md) - Load models, camera setup, animations
**DO NOT load all files at once.** Load only what's relevant.
## Core Concepts
### TresCanvas
Root component that creates WebGL renderer and scene:
```vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas shadows alpha>
<TresPerspectiveCamera :position="[5, 5, 5]" />
<TresMesh>
<TresBoxGeometry />
<TresMeshStandardMaterial color="orange" />
</TresMesh>
<TresAmbientLight :intensity="0.5" />
<TresDirectionalLight :position="[3, 3, 3]" :intensity="1" />
</TresCanvas>
</template>
```
### Component Naming
All Three.js classes available as Vue components with `Tres` prefix:
- `THREE.PerspectiveCamera``<TresPerspectiveCamera />`
- `THREE.Mesh``<TresMesh />`
- `THREE.BoxGeometry``<TresBoxGeometry />`
- `THREE.MeshStandardMaterial``<TresMeshStandardMaterial />`
Constructor arguments via `:args` prop:
```vue
<TresPerspectiveCamera :args="[75, 1, 0.1, 1000]" />
```
### Reactivity
Props are reactive - changes update the 3D scene:
```vue
<script setup>
const color = ref('orange')
const position = ref([0, 0, 0])
</script>
<template>
<TresMesh :position="position">
<TresMeshStandardMaterial :color="color" />
</TresMesh>
</template>
```
### Primitive Component
Inject existing Three.js objects directly:
```vue
<script setup>
import { useGLTF } from '@tresjs/cientos'
const { scene } = await useGLTF('/model.glb')
</script>
<template>
<primitive :object="scene" />
</template>
```
## Available Guidance
**[references/core.md](references/core.md)** - TresCanvas props, useTres, useLoop, useGraph, events, performance
**[references/cientos.md](references/cientos.md)** - OrbitControls, useGLTF, useTexture, Environment, Sky, materials, shapes
**[references/effects.md](references/effects.md)** - EffectComposer vs EffectComposerPmndrs, bloom, glitch, DOF, effect stacking
**[references/cookbook.md](references/cookbook.md)** - Load 3D model, camera with controls, animation loop, post-processing
@@ -0,0 +1,312 @@
# Cientos
Collection of ready-made helpers and components for TresJS. Uses `three-stdlib` under the hood.
```bash
pnpm add @tresjs/cientos
```
No `Tres` prefix needed - import and use directly.
## Controls
### OrbitControls
Orbit around a target:
```vue
<script setup>
import { OrbitControls } from '@tresjs/cientos'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[5, 5, 5]" />
<OrbitControls enable-damping :damping-factor="0.05" />
</TresCanvas>
</template>
```
Key props: `enableDamping`, `autoRotate`, `autoRotateSpeed`, `enableZoom`, `enablePan`, `minDistance`, `maxDistance`, `minPolarAngle`, `maxPolarAngle`
Events: `@change`, `@start`, `@end`
### Other Controls
| Component | Description |
| --------------------- | ------------------------------------- |
| `CameraControls` | Full-featured camera controller |
| `PointerLockControls` | First-person controls (lock cursor) |
| `KeyboardControls` | WASD movement |
| `MapControls` | Panning-focused (like Google Maps) |
| `TransformControls` | Move/rotate/scale objects with gizmo |
| `ScrollControls` | Scroll-driven camera/scene animations |
## Loaders
### useGLTF
Load glTF/GLB models:
```vue
<script setup>
import { useGLTF } from '@tresjs/cientos'
const { scene, nodes, materials } = await useGLTF('/model.glb', { draco: true })
</script>
<template>
<primitive :object="scene" />
</template>
```
Returns: `scene`, `nodes`, `materials`, `animations`
Options: `draco: boolean`, `decoderPath: string`
### GLTFModel Component
Declarative alternative:
```vue
<Suspense>
<GLTFModel path="/model.glb" draco />
</Suspense>
```
### Other Loaders
```ts
import { useFBX, useTexture, useVideoTexture, useSVG } from '@tresjs/cientos'
const fbx = await useFBX('/model.fbx')
const texture = await useTexture('/texture.jpg')
const video = useVideoTexture('/video.mp4')
const svg = await useSVG('/icon.svg')
```
### useProgress
Track loading progress:
```vue
<script setup>
import { useProgress } from '@tresjs/cientos'
const { progress, active, errors, item } = useProgress()
</script>
<template>
<div v-if="active">Loading: {{ Math.round(progress) }}%</div>
</template>
```
## Materials
### GlassMaterial
Realistic glass/crystal:
```vue
<TresMesh>
<TresSphereGeometry />
<GlassMaterial :thickness="0.5" :roughness="0" :transmission="1" />
</TresMesh>
```
### HolographicMaterial
Sci-fi hologram effect:
```vue
<HolographicMaterial
:fresnelAmount="0.5"
:fresnelOpacity="0.8"
:hologramBrightness="1.5"
:scanlineSize="8"
:signalSpeed="2"
hologramColor="#00d5ff"
/>
```
### WobbleMaterial
Animated wobble distortion:
```vue
<WobbleMaterial :speed="2" :factor="0.5" color="hotpink" />
```
### Other Materials
| Component | Description |
| ------------------------ | --------------------------------------------- |
| `CustomShaderMaterial` | Extend built-in materials with custom shaders |
| `MeshReflectionMaterial` | Reflective surfaces like water/mirrors |
| `PointMaterial` | For point clouds |
| `MeshDiscardMaterial` | Invisible (for shadows only) |
## Staging
### Environment
Set up scene environment and background:
```vue
<Suspense>
<Environment files="/sunset.hdr" :background="true" />
</Suspense>
```
Or use presets:
```vue
<Environment preset="city" />
```
Presets: `apartment`, `city`, `dawn`, `forest`, `lobby`, `night`, `park`, `studio`, `sunset`, `warehouse`
### Sky
Procedural sky:
```vue
<Sky :distance="450000" :sun-position="[1, 0.5, 0]" />
```
### Stars
Starfield background:
```vue
<Stars :count="5000" :depth="50" />
```
### Precipitation
Rain/snow:
```vue
<Precipitation :count="5000" :speed="0.5" />
```
### Other Staging
| Component | Description |
| --------------------- | ----------------------------------- |
| `ContactShadows` | Soft contact shadows on ground |
| `AccumulativeShadows` | Progressive shadow baking |
| `SoftShadows` | PCSS soft shadows |
| `Backdrop` | Curved backdrop for studio lighting |
| `Grid` | Ground grid helper |
| `Ocean` | Realistic ocean with waves |
| `Smoke` | Volumetric smoke effect |
| `Sparkles` | Floating particle sparkles |
## Abstractions
### Text3D
3D text geometry:
```vue
<Suspense>
<Text3D font="/fonts/helvetiker.json" text="Hello" :size="1" center>
<TresMeshNormalMaterial />
</Text3D>
</Suspense>
```
Font format: typeface.json (generate at gero3.github.io/facetype.js)
### Html
HTML overlay in 3D space:
```vue
<Html :position="[0, 2, 0]" center transform>
<div class="label">Hello World</div>
</Html>
```
### Billboard
Always face camera:
```vue
<Billboard :position="[0, 1, 0]">
<TresSprite>
<TresSpriteMaterial map="texture" />
</TresSprite>
</Billboard>
```
### Levioso
Floating animation:
```vue
<Levioso :speed="2" :rotation-intensity="2" :float-intensity="1">
<TresMesh><!-- content --></TresMesh>
</Levioso>
```
### Other Abstractions
| Component | Description |
| ----------------- | -------------------------- |
| `Edges` | Render object edges |
| `Outline` | Object outline effect |
| `LensFlare` | Camera lens flare |
| `MouseParallax` | Parallax on mouse movement |
| `Reflector` | Reflective plane |
| `PositionalAudio` | 3D positioned audio |
| `GlobalAudio` | Background audio |
## Shapes
Pre-made geometry components:
```vue
<Box :args="[1, 1, 1]" />
<Sphere :args="[0.5, 32, 32]" />
<Plane :args="[5, 5]" />
<Circle :args="[0.5, 32]" />
<Cone :args="[0.5, 1, 32]" />
<Cylinder :args="[0.5, 0.5, 1, 32]" />
<Torus :args="[0.5, 0.2, 16, 32]" />
<TorusKnot :args="[0.5, 0.15, 100, 16]" />
<RoundedBox :args="[1, 1, 1]" :radius="0.1" />
```
All shapes support mesh props like `position`, `rotation`, `scale`, and accept a default slot for materials.
## Debug/Performance
### Stats
FPS counter:
```vue
<Stats />
```
### StatsGl
WebGL stats panel:
```vue
<StatsGl />
```
### Lod
Level of detail:
```vue
<Lod>
<TresMesh :distance="0"><!-- high detail --></TresMesh>
<TresMesh :distance="50"><!-- medium detail --></TresMesh>
<TresMesh :distance="100"><!-- low detail --></TresMesh>
</Lod>
```
@@ -0,0 +1,310 @@
# TresJS Cookbook
Common patterns and recipes.
## Load and Display 3D Model
```vue
<script setup lang="ts">
import { OrbitControls, useGLTF } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
const { scene } = await useGLTF('/models/robot.glb', { draco: true })
</script>
<template>
<TresCanvas shadows>
<TresPerspectiveCamera :position="[3, 3, 3]" />
<OrbitControls enable-damping />
<Suspense>
<primitive :object="scene" />
</Suspense>
<TresDirectionalLight :position="[5, 5, 5]" :intensity="1" cast-shadow />
<TresAmbientLight :intensity="0.3" />
</TresCanvas>
</template>
```
## Camera Setup with OrbitControls
```vue
<script setup lang="ts">
import { OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera
:position="[5, 5, 5]"
:fov="45"
:near="0.1"
:far="1000"
/>
<OrbitControls
enable-damping
:damping-factor="0.05"
:min-distance="2"
:max-distance="20"
:max-polar-angle="Math.PI / 2"
/>
<!-- scene -->
</TresCanvas>
</template>
```
## Animation Loop
```vue
<script setup lang="ts">
import { TresCanvas, useLoop } from '@tresjs/core'
import { shallowRef } from 'vue'
const meshRef = shallowRef()
const { onBeforeRender } = useLoop()
onBeforeRender(({ delta }) => {
if (meshRef.value) {
meshRef.value.rotation.y += delta
meshRef.value.rotation.x += delta * 0.5
}
})
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[3, 3, 3]" />
<TresMesh ref="meshRef">
<TresBoxGeometry />
<TresMeshStandardMaterial color="orange" />
</TresMesh>
<TresAmbientLight :intensity="0.5" />
</TresCanvas>
</template>
```
## Add Post-Processing Effects
```vue
<script setup lang="ts">
import { BloomPmndrs, EffectComposerPmndrs, VignettePmndrs } from '@tresjs/post-processing'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[5, 5, 5]" />
<!-- Scene with emissive materials for bloom -->
<TresMesh>
<TresSphereGeometry :args="[1, 32, 32]" />
<TresMeshStandardMaterial
color="#ff6600"
:emissive="0xff6600"
:emissive-intensity="2"
/>
</TresMesh>
<TresAmbientLight :intensity="0.2" />
<Suspense>
<EffectComposerPmndrs>
<BloomPmndrs :intensity="3" :luminance-threshold="0.2" mipmap-blur />
<VignettePmndrs :darkness="0.4" />
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
```
## Responsive Canvas
```vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<!-- Fill parent container -->
<div class="canvas-container">
<TresCanvas>
<!-- scene -->
</TresCanvas>
</div>
<!-- Or fill entire window -->
<TresCanvas window-size>
<!-- scene -->
</TresCanvas>
</template>
<style scoped>
.canvas-container {
width: 100%;
height: 100vh;
}
</style>
```
## Environment and Lighting Setup
```vue
<script setup lang="ts">
import { Environment, ContactShadows, Sky } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas shadows>
<TresPerspectiveCamera :position="[5, 5, 5]" />
<!-- HDR environment for reflections -->
<Suspense>
<Environment preset="sunset" :background="true" />
</Suspense>
<!-- Or procedural sky -->
<Sky :sun-position="[100, 20, 100]" />
<!-- Content -->
<TresMesh :position="[0, 0.5, 0]" cast-shadow>
<TresSphereGeometry :args="[0.5, 32, 32]" />
<TresMeshStandardMaterial :metalness="0.9" :roughness="0.1" />
</TresMesh>
<!-- Ground with contact shadows -->
<ContactShadows :opacity="0.5" :blur="2" :position="[0, 0, 0]" />
<!-- Or regular ground -->
<TresMesh :rotation="[-Math.PI / 2, 0, 0]" receive-shadow>
<TresPlaneGeometry :args="[10, 10]" />
<TresMeshStandardMaterial color="#444" />
</TresMesh>
</TresCanvas>
</template>
```
## Interactive Objects
```vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { ref } from 'vue'
const hovered = ref(false)
const clicked = ref(false)
const scale = computed(() => (clicked.value ? 1.5 : hovered.value ? 1.2 : 1))
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[3, 3, 3]" />
<TresMesh
:scale="scale"
@click="clicked = !clicked"
@pointer-enter="hovered = true"
@pointer-leave="hovered = false"
>
<TresBoxGeometry />
<TresMeshStandardMaterial :color="hovered ? 'hotpink' : 'orange'" />
</TresMesh>
<TresAmbientLight :intensity="0.5" />
<TresDirectionalLight :position="[5, 5, 5]" />
</TresCanvas>
</template>
```
## Multiple Models with Suspense
```vue
<script setup lang="ts">
import { OrbitControls, useGLTF, useProgress } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
const { progress, active } = useProgress()
const robot = useGLTF('/models/robot.glb', { draco: true })
const car = useGLTF('/models/car.glb', { draco: true })
</script>
<template>
<div v-if="active" class="loading">Loading: {{ Math.round(progress) }}%</div>
<TresCanvas>
<TresPerspectiveCamera :position="[10, 5, 10]" />
<OrbitControls />
<Suspense>
<primitive :object="robot.scene" :position="[-2, 0, 0]" />
</Suspense>
<Suspense>
<primitive :object="car.scene" :position="[2, 0, 0]" />
</Suspense>
<TresAmbientLight :intensity="0.5" />
<TresDirectionalLight :position="[5, 5, 5]" />
</TresCanvas>
</template>
```
## Text in 3D Scene
```vue
<script setup lang="ts">
import { Text3D, Center } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[0, 0, 10]" />
<Suspense>
<Center>
<Text3D
font="/fonts/helvetiker_regular.typeface.json"
text="Hello TresJS"
:size="1"
:height="0.2"
center
>
<TresMeshNormalMaterial />
</Text3D>
</Center>
</Suspense>
<TresAmbientLight :intensity="0.5" />
</TresCanvas>
</template>
```
## Floating Animation
```vue
<script setup lang="ts">
import { Levioso, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[3, 3, 3]" />
<OrbitControls />
<Levioso :speed="2" :rotation-intensity="2" :float-intensity="1">
<TresMesh>
<TresIcosahedronGeometry :args="[1, 1]" />
<TresMeshNormalMaterial flat-shading />
</TresMesh>
</Levioso>
<TresAmbientLight />
</TresCanvas>
</template>
```
@@ -0,0 +1,196 @@
# TresJS Core
Core package for building 3D scenes with Vue components.
## TresCanvas Props
| Prop | Type | Default | Description |
| ------------------ | -------------------------- | ----------------------- | --------------------------------- |
| `shadows` | `boolean \| ShadowMapType` | `false` | Enable shadow maps |
| `alpha` | `boolean` | `false` | Transparent background |
| `clearColor` | `string` | `#000000` | Background color |
| `antialias` | `boolean` | `true` | Enable antialiasing |
| `toneMapping` | `ToneMapping` | `ACESFilmicToneMapping` | Tone mapping |
| `outputColorSpace` | `ColorSpace` | `SRGBColorSpace` | Output color space |
| `windowSize` | `boolean` | `false` | Use window size instead of parent |
| `preset` | `'realistic' \| 'low'` | - | Quality presets |
```vue
<TresCanvas
shadows
alpha
clear-color="#1a1a2e"
:tone-mapping="NoToneMapping"
window-size
>
<!-- scene -->
</TresCanvas>
```
## Composables
### useTres
Access Three.js instances from any component inside TresCanvas:
```ts
import { useTres } from '@tresjs/core'
const { scene, renderer, camera, sizes } = useTres()
// scene: THREE.Scene
// renderer: THREE.WebGLRenderer
// camera: computed<THREE.Camera>
// sizes: { width, height, aspectRatio }
```
### useLoop
Register callbacks in the render loop:
```ts
import { useLoop } from '@tresjs/core'
const { onBeforeRender, pause, resume } = useLoop()
onBeforeRender(({ delta, elapsed }) => {
mesh.value.rotation.y += delta
})
```
Render priority (lower = earlier):
```ts
onBeforeRender(({ delta }) => {
// physics update
}, { priority: -1 })
onBeforeRender(({ delta }) => {
// animation update
}, { priority: 0 })
```
### useGraph
Navigate object hierarchies by name:
```ts
import { useGraph } from '@tresjs/core'
const { nodes, materials } = useGraph(model)
// Access by name
const head = nodes.Head
const skin = materials.Skin
```
### useLoader
Generic loader wrapper:
```ts
import { useLoader } from '@tresjs/core'
import { TextureLoader, CubeTextureLoader } from 'three'
const texture = await useLoader(TextureLoader, '/texture.jpg')
const cubeTexture = await useLoader(CubeTextureLoader, [
'/px.jpg', '/nx.jpg', '/py.jpg', '/ny.jpg', '/pz.jpg', '/nz.jpg'
])
```
## Events
Pointer events on meshes:
```vue
<TresMesh
@click="onClick"
@pointer-move="onPointerMove"
@pointer-enter="onPointerEnter"
@pointer-leave="onPointerLeave"
>
<TresBoxGeometry />
<TresMeshStandardMaterial />
</TresMesh>
```
Event payload:
```ts
function onClick(event) {
event.object // The mesh that was clicked
event.point // THREE.Vector3 intersection point
event.distance // Distance from camera
event.uv // UV coordinates
event.face // Intersected face
event.stopPropagation() // Stop event bubbling
}
```
Enable pointer events on canvas:
```vue
<TresCanvas :pointer="{ events: true }">
```
## Template Ref
Access Three.js objects directly:
```vue
<script setup>
import { shallowRef, onMounted } from 'vue'
const meshRef = shallowRef()
onMounted(() => {
console.log(meshRef.value) // THREE.Mesh
meshRef.value.rotation.x = Math.PI / 4
})
</script>
<template>
<TresMesh ref="meshRef">
<TresBoxGeometry />
<TresMeshStandardMaterial />
</TresMesh>
</template>
```
Use `shallowRef` for Three.js objects to avoid deep reactivity overhead.
## Extend Catalog
Register custom Three.js classes:
```ts
import { extend } from '@tresjs/core'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
extend({ OrbitControls })
```
Then use as component:
```vue
<TresOrbitControls :args="[camera, renderer.domElement]" />
```
Note: Cientos already extends common classes for you.
## Performance Tips
1. **Use `shallowRef`** for Three.js objects
2. **Dispose resources** when unmounting:
```ts
onUnmounted(() => {
geometry.dispose()
material.dispose()
texture.dispose()
})
```
3. **Limit reactive props** - static values don't need refs
4. **Use `window-size`** for fullscreen to avoid resize listeners
5. **Set `antialias: false`** on mobile for better performance
6. **Use `preset="low"`** for performance mode
@@ -0,0 +1,274 @@
# Post-Processing Effects
Visual effects applied after scene render. Two effect systems available.
```bash
pnpm add @tresjs/post-processing
```
## Effect Composers
### EffectComposer (Three.js native)
Uses Three.js built-in effects:
```vue
<script setup>
import { EffectComposer, UnrealBloom, Glitch } from '@tresjs/post-processing'
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera :position="[5, 5, 5]" />
<!-- scene content -->
<Suspense>
<EffectComposer>
<UnrealBloom :strength="1.5" :radius="0.5" :threshold="0.8" />
<Glitch />
</EffectComposer>
</Suspense>
</TresCanvas>
</template>
```
### EffectComposerPmndrs (pmndrs postprocessing)
Uses pmndrs/postprocessing library (more effects, better performance):
```vue
<script setup>
import { EffectComposerPmndrs, BloomPmndrs, GlitchPmndrs } from '@tresjs/post-processing'
</script>
<template>
<Suspense>
<EffectComposerPmndrs>
<BloomPmndrs :intensity="4" :luminance-threshold="0.1" mipmap-blur />
<GlitchPmndrs />
</EffectComposerPmndrs>
</Suspense>
</template>
```
**Rule:** Pmndrs effects end with `Pmndrs` suffix and require `EffectComposerPmndrs`.
## Three.js Effects (EffectComposer)
### UnrealBloom
Glow around bright areas:
```vue
<UnrealBloom :strength="1.5" :radius="0.5" :threshold="0.8" />
```
| Prop | Description | Default |
| ----------- | ---------------- | ------- |
| `strength` | Bloom intensity | `1` |
| `radius` | Bloom spread | `0` |
| `threshold` | Luminance cutoff | `0` |
### Glitch
Digital glitch distortion:
```vue
<Glitch />
```
### Halftone
Halftone print effect:
```vue
<Halftone :radius="4" :scatter="0" />
```
### Pixelation
Pixelated look:
```vue
<Pixelation :granularity="5" />
```
### Output
Color space/tone mapping:
```vue
<Output />
```
### SMAA
Anti-aliasing pass:
```vue
<SMAA />
```
## Pmndrs Effects (EffectComposerPmndrs)
More effects with better performance through effect merging.
### BloomPmndrs
Advanced bloom:
```vue
<BloomPmndrs
:intensity="4"
:luminance-threshold="0.1"
:luminance-smoothing="0.3"
:radius="0.85"
mipmap-blur
/>
```
| Prop | Description | Default |
| -------------------- | -------------------------------- | ------- |
| `intensity` | Effect strength | `1` |
| `luminanceThreshold` | Brightness cutoff (0-1) | `0.9` |
| `luminanceSmoothing` | Threshold smoothness | `0.025` |
| `mipmapBlur` | Enable mipmap blur (like Unreal) | `false` |
| `radius` | Blur radius | - |
### DepthOfFieldPmndrs
Camera focus blur:
```vue
<DepthOfFieldPmndrs
:focus-distance="0.5"
:focus-range="0.1"
:bokeh-scale="2"
/>
```
| Prop | Description | Default |
| -------------------- | ------------------------------- | ------- |
| `focusDistance` | Normalized focus distance (0-1) | - |
| `focusRange` | Focus range (0-1) | `0.1` |
| `bokehScale` | Bokeh blur scale | `1` |
| `worldFocusDistance` | Focus in world units | - |
### GlitchPmndrs
Digital glitch:
```vue
<GlitchPmndrs
:delay="[1.5, 3.5]"
:duration="[0.6, 1.0]"
:strength="[0.3, 1.0]"
/>
```
| Prop | Description | Default |
| ---------- | -------------------------------------------- | ------------ |
| `delay` | [min, max] delay between glitches (s) | `[1.5, 3.5]` |
| `duration` | [min, max] glitch duration (s) | `[0.6, 1.0]` |
| `strength` | [weak, strong] glitch intensity | `[0.3, 1.0]` |
| `mode` | `SPORADIC`, `CONSTANT_MILD`, `CONSTANT_WILD` | `SPORADIC` |
| `active` | Enable/disable | - |
### ChromaticAberrationPmndrs
Color fringing:
```vue
<ChromaticAberrationPmndrs :offset="[0.002, 0.002]" />
```
### VignettePmndrs
Darkened edges:
```vue
<VignettePmndrs :darkness="0.5" :offset="0.3" />
```
### NoisePmndrs
Film grain:
```vue
<NoisePmndrs :opacity="0.1" />
```
### OutlinePmndrs
Object outlines:
```vue
<OutlinePmndrs
:selected-objects="[meshRef]"
:edge-strength="3"
:pulse-speed="0"
visible-edge-color="#ffffff"
hidden-edge-color="#22090a"
/>
```
### Other Pmndrs Effects
| Effect | Description |
| -------------------------- | --------------------------- |
| `AsciiPmndrs` | ASCII art rendering |
| `BarrelBlurPmndrs` | Barrel distortion with blur |
| `BrightnessContrastPmndrs` | Adjust brightness/contrast |
| `ColorAveragePmndrs` | Grayscale conversion |
| `ColorDepthPmndrs` | Reduce color depth |
| `DotScreenPmndrs` | Dot matrix effect |
| `FishEyePmndrs` | Fisheye lens distortion |
| `FXAAPmndrs` | Fast anti-aliasing |
| `GodRaysPmndrs` | Volumetric light rays |
| `GridPmndrs` | Grid overlay |
| `HueSaturationPmndrs` | Color adjustment |
| `KuwaharaPmndrs` | Painterly effect |
| `LensDistortionPmndrs` | Lens distortion |
| `LinocutPmndrs` | Linocut print effect |
| `PixelationPmndrs` | Pixelation |
| `ScanlinePmndrs` | CRT scanlines |
| `SepiaPmndrs` | Sepia tone |
| `ShockWavePmndrs` | Shockwave ripple |
| `SMAAPmndrs` | Enhanced anti-aliasing |
| `TexturePmndrs` | Texture overlay |
| `TiltShiftPmndrs` | Miniature effect |
| `ToneMappingPmndrs` | Tone mapping |
## Effect Stacking
Effects apply in order. Combine for complex looks:
```vue
<EffectComposerPmndrs>
<!-- Base effects first -->
<SMAAPmndrs />
<!-- Main effects -->
<BloomPmndrs :intensity="2" />
<DepthOfFieldPmndrs :focus-distance="0.5" />
<!-- Color grading -->
<VignettePmndrs :darkness="0.3" />
<NoisePmndrs :opacity="0.05" />
</EffectComposerPmndrs>
```
## Performance
1. **Use Pmndrs** - effects are merged into fewer passes
2. **Limit effects** - each adds GPU cost
3. **Consider mobile** - reduce or disable on low-end devices
4. **Wrap in Suspense** - effects load asynchronously
```vue
<Suspense>
<EffectComposerPmndrs>
<!-- effects -->
</EffectComposerPmndrs>
</Suspense>
```