@tresjs/core 5.9.0
Vue custom renderer for Three.js: any THREE class becomes a component by prefixing Tres (<TresMesh>, <TresBoxGeometry>). Prepared source: package.json, dist/tres.d.ts (public types), dist/tres.js.
npm dist-tags at generation time: latest 5.9.0, rc 5.0.0-rc.0, next 5.0.0-next.6, beta 2.0.0-beta.13, alpha 5.0.0-alpha.2.
Environment limits
- ESM-only since v5. No UMD, no
require().import { TresCanvas } from '@tresjs/core'. - Peer deps:
vue >=3.4,three >=0.133(package.json:44-46). Built against three^0.184. - Time source: three
Timeron r179+, falls back toClockon older three (dist/tres.d.ts:962-970). - WebGPU is experimental; requires the
rendererprop with athree/webgpuRenderer(see references/webgpu.md).
Setup
pnpm i @tresjs/core three
pnpm i @types/three -D # TypeScript
Vite: spread templateCompilerOptions into the Vue plugin, or Tres components warn as unknown custom elements (README.md:36-50):
import { templateCompilerOptions } from '@tresjs/core'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [vue({ ...templateCompilerOptions })],
})
A separate subpath export @tresjs/core/template-compiler-options exists for hosts that only need compiler options (package.json:21-25). For Nuxt use @tresjs/nuxt instead of manual setup.
Core model
- Component catalogue is autogenerated from the
THREEnamespace:Tres+ capitalized class name, also available kebab-case (<tres-mesh>, supported since v5.1.0) (dist/tres.d.ts:497-509). argspasses constructor arguments:<TresBoxGeometry :args="[1, 2, 3]" />. Changing reactiveargsrecreates the whole instance; use props for everything settable after construction (dist/tres.d.ts:405-411).- Props map to instance properties. Math types accept shorthand:
:position="[1, 2, 3]",:rotation="[0, Math.PI, 0]",color="#00ff00"(dist/tres.d.ts:457-485). - Child material/geometry auto-attach via
attach:<TresMesh><TresBoxGeometry /><TresMeshNormalMaterial /></TresMesh>works without explicitattach. extend({ MyObject })before using non-THREE classes as<TresMyObject>(dist/tres.d.ts:872-874).<primitive :object="existingThreeObject" />mounts an object you created in JS. It does not own disposal; dispose manually (see references/performance.md).
Minimal scene:
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
</script>
<template>
<TresCanvas shadows>
<TresPerspectiveCamera :position="[3, 3, 3]" :look-at="[0, 0, 0]" />
<TresMesh>
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshNormalMaterial />
</TresMesh>
<TresDirectionalLight :position="[3, 3, 3]" :intensity="1" cast-shadow />
</TresCanvas>
</template>
Without an explicit camera, a default PerspectiveCamera is created (dist/tres.d.ts:682-685).
API changes to know
v5 breaking (migrate with references/migration-v4-v5.md):
useLoaderreturns reactive state{ state, isLoading, error, progress, load }, no longer a Promise (dist/tres.d.ts:40-65).- Pointer events use native DOM names:
@pointerdown, not@pointer-down. Only the first intersected object fires. useTexturemoved to@tresjs/cientos.useRenderLoop,useCamera,useSeek,useRaycaster,useTresReady,useTresEventManager,useLoggerwere removed. Replacements:useLoop,useTres,useGraph,@readyevent.useTresContext().camerais a camera manager; useuseTres().camerafor the active camera instance (dist/tres.d.ts:574-606).- WebGL context props (
alpha,antialias,depth,stencil,powerPreference,logarithmicDepthBuffer,preserveDrawingBuffer,failIfMajorPerformanceCaveat) are readonly; set once at mount (dist/tres.d.ts:141-206).
Recent additions:
- 5.9.0:
TresPortalcomponent reparents children into anyObject3D/Scenetarget (dist/tres.d.ts:853-858), https://docs.tresjs.org/api/components/tres-portal - 5.9.0:
isWebGPURendererguard and reactivecontext.isWebGPUflag (dist/tres.d.ts:350-367, 1204-1222) - 5.9.0:
shadowMapTypedefaults toPCFShadowMapon WebGL,PCFSoftShadowMapon WebGPU (dist/tres.d.ts:250-255) - 5.8.0:
fpsLimitprop caps render FPS (dist/tres.d.ts:692-696) - 5.7.0: three
<r179compatibility viaTimertoClockfallback (dist/tres.d.ts:962-970) - 5.5.0:
TresCanvasContext(theContextcomponent) for bringing your own<canvas>(dist/tres.d.ts:680-708) - 5.3.0:
customRendererOptions.primitivePrefixrenames<primitive>(dist/tres.d.ts:622-625) - 5.2.0:
TresCanvasProps/TresCanvasEmitstypes exported (dist/tres.d.ts:776-781) - Full history: https://github.com/Tresjs/tres/blob/main/packages/core/CHANGELOG.md
Common tasks
Animate with frame-rate independence (delta in seconds):
<script setup lang="ts">
import { useLoop } from '@tresjs/core'
const { onBeforeRender } = useLoop()
const cube = shallowRef<TresInstance | null>(null)
onBeforeRender(({ delta, elapsed }) => {
if (!cube.value) return
cube.value.rotation.y += delta * 2 // 2 rad/s on any refresh rate
cube.value.position.y = Math.sin(elapsed * 3) * 0.5
})
</script>
<template>
<TresMesh ref="cube">
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshNormalMaterial />
</TresMesh>
</template>
useLoop only works inside child components of TresCanvas; on the canvas itself use @before-loop / @loop events (https://docs.tresjs.org/api/composables/use-loop).
Load a model:
import { useLoader } from '@tresjs/core'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
const { state: model, isLoading, error, progress } = useLoader(
GLTFLoader,
'/models/duck.gltf', // MaybeRef<string>: changing the ref reloads
{ extensions: (loader) => loader.setDRACOLoader(dracoLoader) },
)
// template: <primitive v-if="!isLoading && model?.scene" :object="model.scene" />
Click a mesh:
<TresMesh @click="(e) => e.object.material.color.set('#ff0000')">
<TresBoxGeometry />
<TresMeshNormalMaterial />
</TresMesh>
Event payloads carry point, object, distance, face, uv, xy. @pointermissed on TresCanvas catches clicks on empty space. Details: references/pointer-events.md.
Best practices
- Use
shallowReffor template refs to Three.js instances and for any object passed to<primitive>; deeprefproxies cost real frame time. https://docs.tresjs.org/api/advanced/performance - Prefer
renderMode="on-demand"plusinvalidate()for non-game scenes;renderMode="manual"plusadvance()for full control (dist/tres.d.ts:134-139). - In
on-demandmode, callinvalidate()after mutating objects through refs, since those mutations bypass Vue reactivity. - Take over rendering with
useLoop().render(fn)only for post-processing or multi-pass; the fn must callnotifySuccess()or render modes break (https://docs.tresjs.org/api/composables/use-loop). - Register ordered updates via the
priorityargument ofonBeforeRender/onRender(default 0, higher runs later). useGraph(object)gives namednodes,materials,meshesmaps for loaded GLTF scenes instead of manual traversal (dist/tres.d.ts:565).- Call
dispose()(exported from@tresjs/core) on programmatically created objects used via<primitive>; template-created objects are disposed automatically. - Keep
argsstatic unless you intend instance recreation; animate via props or refs instead. - Debug with
v-log/v-log:material,v-light-helper,v-distance-todirectives (dist/tres.d.ts:934-952), https://docs.tresjs.org/api/utils/directives
References
- references/components.md: TresCanvas props and events, TresCanvasContext, TresPortal, UseLoader component
- references/composables.md: useTres vs useTresContext, useLoop, useLoader, useGraph, manager composables
- references/performance.md: render modes, reactivity, disposal, dpr, fpsLimit
- references/pointer-events.md: event names, hit rules, payloads, propagation
- references/webgpu.md: custom renderer factory, isWebGPU, capability branching
- references/migration-v4-v5.md: v4 to v5 migration detail
Official docs: https://docs.tresjs.org