5.3.3

Extending the Catalogue

Learn how to add custom Three.js classes and third-party libraries to TresJS using the extend function.

The TresJS Catalogue

TresJS automatically generates Vue components for all classes exported from the three package. This catalogue maps component names to Three.js constructors:

ComponentThree.js Class
<TresMesh />THREE.Mesh
<TresBoxGeometry />THREE.BoxGeometry
<TresPerspectiveCamera />THREE.PerspectiveCamera

But Three.js has many useful classes in three/addons/ that aren't included by default, plus third-party libraries you might want to use.

The extend Function

The extend function adds new classes to the catalogue, making them available as Tres components:

import { extend } from '@tresjs/core'
import { OrbitControls } from 'three/addons/controls/OrbitControls'

// Add to catalogue
extend({ OrbitControls })

// Now available as <TresOrbitControls />

Common Extensions

Controls

<script setup lang="ts">
import { extend } from '@tresjs/core'
import { OrbitControls } from 'three/addons/controls/OrbitControls'
import { TransformControls } from 'three/addons/controls/TransformControls'

extend({ OrbitControls, TransformControls })
</script>

<template>
  <TresCanvas>
    <TresPerspectiveCamera :position="[5, 5, 5]" />
    <TresOrbitControls />
    <!-- ... -->
  </TresCanvas>
</template>
Some controls like OrbitControls require access to the camera and renderer. Use them with useTresContext() or inside the canvas.

Geometries

<script setup lang="ts">
import { extend } from '@tresjs/core'
import { TextGeometry } from 'three/addons/geometries/TextGeometry'
import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry'

extend({ TextGeometry, RoundedBoxGeometry })
</script>

<template>
  <TresCanvas>
    <TresMesh>
      <TresRoundedBoxGeometry :args="[1, 1, 1, 4, 0.1]" />
      <TresMeshStandardMaterial />
    </TresMesh>
  </TresCanvas>
</template>

Loaders

<script setup lang="ts">
import { extend } from '@tresjs/core'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader'
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader'

extend({ GLTFLoader, DRACOLoader })
</script>

Post-Processing

<script setup lang="ts">
import { extend } from '@tresjs/core'
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer'
import { RenderPass } from 'three/addons/postprocessing/RenderPass'
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass'

extend({ EffectComposer, RenderPass, UnrealBloomPass })
</script>
For post-processing, consider using which provides ready-to-use effect components.

Third-Party Libraries

Using drei-style Libraries

<script setup lang="ts">
import { extend } from '@tresjs/core'
import { MeshWobbleMaterial } from 'some-threejs-library'

extend({ MeshWobbleMaterial })
</script>

<template>
  <TresCanvas>
    <TresMesh>
      <TresBoxGeometry />
      <TresMeshWobbleMaterial color="hotpink" :factor="1" :speed="2" />
    </TresMesh>
  </TresCanvas>
</template>

Custom Classes

You can extend with your own Three.js classes:

<script setup lang="ts">
import { extend } from '@tresjs/core'
import * as THREE from 'three'

// Custom geometry class
class StarGeometry extends THREE.BufferGeometry {
  constructor(innerRadius = 0.5, outerRadius = 1, points = 5) {
    super()
    // ... geometry creation logic
  }
}

extend({ StarGeometry })
</script>

<template>
  <TresCanvas>
    <TresMesh>
      <TresStarGeometry :args="[0.5, 1, 5]" />
      <TresMeshStandardMaterial color="gold" />
    </TresMesh>
  </TresCanvas>
</template>

Naming Convention

The component name is derived from the class name you provide to extend:

extend({ OrbitControls })      // <TresOrbitControls />
extend({ TextGeometry })       // <TresTextGeometry />
extend({ MyCustomMaterial })   // <TresMyCustomMaterial />

You can also use custom names:

extend({
  CustomControls: OrbitControls  // <TresCustomControls />
})

Global vs Local Extension

Extend in your main app entry or a plugin:

// plugins/tres.ts or main.ts
import { extend } from '@tresjs/core'
import { OrbitControls } from 'three/addons/controls/OrbitControls'
import { TextGeometry } from 'three/addons/geometries/TextGeometry'

extend({ OrbitControls, TextGeometry })

Local Extension (Component-Specific)

Extend in the component that needs it:

<script setup lang="ts">
import { extend } from '@tresjs/core'
import { SomeSpecialGeometry } from 'special-library'

// Only this component uses this class
extend({ SomeSpecialGeometry })
</script>

TypeScript Support

For type safety with extended components, declare the types:

// types/tres.d.ts
import type { OrbitControls } from 'three/addons/controls/OrbitControls'

declare module '@tresjs/core' {
  interface TresObjectMap {
    OrbitControls: typeof OrbitControls
  }
}

Complete Example

<script setup lang="ts">
import { extend, useTresContext } from '@tresjs/core'
import { OrbitControls } from 'three/addons/controls/OrbitControls'
import { TextGeometry } from 'three/addons/geometries/TextGeometry'
import { FontLoader } from 'three/addons/loaders/FontLoader'

extend({ OrbitControls, TextGeometry })

// Load font for TextGeometry
const fontLoader = new FontLoader()
const font = await new Promise((resolve) => {
  fontLoader.load('/fonts/helvetiker_regular.typeface.json', resolve)
})

const fontOptions = {
  font,
  size: 1,
  height: 0.2,
  curveSegments: 12,
}
</script>

<template>
  <TresCanvas shadows>
    <TresPerspectiveCamera :position="[5, 5, 5]" />
    <TresOrbitControls />

    <TresMesh :position="[0, 0, 0]">
      <TresTextGeometry :args="['TresJS', fontOptions]" center />
      <TresMeshStandardMaterial color="#82dbc5" />
    </TresMesh>

    <TresAmbientLight :intensity="0.5" />
    <TresDirectionalLight :position="[10, 10, 10]" />
  </TresCanvas>
</template>

Key Takeaways

extend() Function

Use extend() to add any Three.js class to the TresJS catalogue.

Addons Support

Classes from three/addons/ aren't included by default - extend them as needed.

Custom Classes

Your own Three.js classes can be extended and used as Vue components.

Tres Prefix

Extended classes become available with the Tres prefix: OrbitControls<TresOrbitControls />.