feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma binaryTargets for openssl 3.0 - nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal cron, http->https redirect - prisma: add origin_goods.delisted migration, sync missing schema (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz - api: CORS wildcard reflection, helmet CORP cross-origin, price backfill in persistProductDetail, categoryIcon ancestor fallback, mediaByColor per-color gallery in public goods detail - admin: /admin base path (vite + router) - import-data.mjs: udt_name casting, serial sequence advance fix
This commit is contained in:
@@ -1,125 +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
|
||||
---
|
||||
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
|
||||
|
||||
@@ -1,312 +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>
|
||||
```
|
||||
# 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>
|
||||
```
|
||||
|
||||
@@ -1,310 +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>
|
||||
```
|
||||
# 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>
|
||||
```
|
||||
|
||||
@@ -1,196 +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
|
||||
# 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
|
||||
|
||||
@@ -1,274 +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>
|
||||
```
|
||||
# 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>
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user