Tres Components
The core idea of TresJS is to provide an autogenerated catalogue of all the Three.js elements. This catalogue is generated based on the Three.js source code, so it's always up to date.
When using plain Three.js, you need to import the elements you want to use. For example, if you want to use a PerspectiveCamera, you need to import it from the three package:
import { PerspectiveCamera } from 'three'
const camera = new PerspectiveCamera(45, width / height, 1, 1000)
For example, if you want to use a PerspectiveCamera you would use the <TresPerspectiveCamera /> component.
<template>
<TresCanvas>
<TresPerspectiveCamera />
<!-- Your scene goes here -->
</TresCanvas>
</template>
This means that you can rely on the same documentation as you would when using plain Three.js, but with the power of Vue.
Declaring objects
If we follow this argument, you should be able to lay out an instance like this: ❌
<template>
<TresCanvas>
<TresPerspectiveCamera visible :position="new THREE.Vector3(1, 2, 3)" />
<!-- Your scene goes here -->
</TresCanvas>
</template>
But with Tres this is not needed, you can define properties declaratively like this: ✅
<template>
<TresCanvas>
<TresPerspectiveCamera visible :position="[1, 2, 3]" />
<!-- Your scene goes here -->
</TresCanvas>
</template>
TresJS follows a simple naming convention: any component prefixed with Tres is automatically mapped to its Three.js counterpart. Some examples:
| Vue Component | Instance |
|---|---|
<TresPerspectiveCamera /> | new THREE.PerspectiveCamera() |
<TresMesh /> | new THREE.Mesh() |
<TresBoxGeometry /> | new THREE.BoxGeometry() |
<TresMeshBasicMaterial /> | new THREE.MeshBasicMaterial() |
Constructor Arguments with args
Many Three.js objects require constructor arguments. TresJS provides the args prop as an array of constructor arguments that are passed directly to the Three.js constructor:
For example, the PerspectiveCamera constructor has the following arguments:
fov- Camera frustum vertical field of viewaspect- Camera frustum aspect rationear- Camera frustum near planefar- Camera frustum far plane
To pass these arguments to the <TresPerspectiveCamera /> component, you can use the args prop:
<template>
<TresCanvas>
<!-- Creates: new THREE.PerspectiveCamera(45, 1, 0.1, 1000) -->
<TresPerspectiveCamera :args="[45, 1, 0.1, 1000]" />
<!-- Your scene goes here -->
</TresCanvas>
</template>
Basic Usage
<template>
<TresCanvas>
<!-- Creates: new THREE.PerspectiveCamera(45, 1, 0.1, 1000) -->
<TresPerspectiveCamera :args="[45, 1, 0.1, 1000]" />
<!-- Creates: new THREE.BoxGeometry(1, 2, 3) -->
<TresBoxGeometry :args="[1, 2, 3]" />
<!-- Creates: new THREE.MeshBasicMaterial({ color: 'red' }) -->
<TresMeshBasicMaterial :args="[{ color: 'red' }]" />
</TresCanvas>
</template>
Common Patterns
<template>
<!-- Box: width, height, depth -->
<TresBoxGeometry :args="[2, 2, 2]" />
<!-- Sphere: radius, widthSegments, heightSegments -->
<TresSphereGeometry :args="[1, 32, 32]" />
<!-- Plane: width, height, widthSegments, heightSegments -->
<TresPlaneGeometry :args="[10, 10, 1, 1]" />
</template>
<template>
<!-- PerspectiveCamera: fov, aspect, near, far -->
<TresPerspectiveCamera :args="[75, window.innerWidth / window.innerHeight, 0.1, 1000]" />
<!-- OrthographicCamera: left, right, top, bottom, near, far -->
<TresOrthographicCamera :args="[-5, 5, 5, -5, 0.1, 1000]" />
</template>
<template>
<!-- DirectionalLight: color, intensity -->
<TresDirectionalLight :args="['#ffffff', 1]" />
<!-- PointLight: color, intensity, distance, decay -->
<TresPointLight :args="['#ff0000', 2, 100, 2]" />
</template>
Declarative Properties
Beyond constructor arguments, TresJS allows you to set properties declaratively using Vue props:
Property Mapping
<template>
<!-- Three.js equivalent:
const mesh = new THREE.Mesh()
mesh.position.set(0, 1, 0)
mesh.rotation.set(0, Math.PI, 0)
mesh.visible = true
-->
<TresMesh
:position="[0, 1, 0]"
:rotation="[0, Math.PI, 0]"
:visible="true"
>
<TresBoxGeometry />
<TresMeshBasicMaterial color="blue" />
</TresMesh>
</template>
Shorthand Properties
TresJS provides convenient shorthands for common transformations:
<template>
<!-- Individual axis manipulation -->
<TresMesh
:position-x="1"
:position-y="2"
:position-z="3"
:rotation-x="Math.PI / 4"
:scale-y="2"
/>
<!-- Color properties -->
<TresMeshBasicMaterial
:color-r="0.8"
:color-g="0.2"
:color-b="0.1"
/>
</template>
Set Methods
Properties with .set() methods can accept arrays:
<template>
<!-- Automatically calls position.set(1, 2, 3) -->
<TresMesh :position="[1, 2, 3]" />
<!-- Automatically calls scale.set(2, 2, 2) -->
<TresMesh :scale="2" />
<!-- Automatically calls lookAt(0, 0, 0) -->
<TresPerspectiveCamera :look-at="[0, 0, 0]" />
</template>
Extending the Catalogue 🔌
Tres offers bare bones functionality, but it's easy to add third-party elements and extend them into its internal catalogue.
Most of 3D experience uses OrbitControls which is not part of the core threejs library. You can add it to your project by importing it from the three/addons/controls/OrbitControls module.
import { OrbitControls } from 'three/addons/controls/OrbitControls'
Then you can extend the catalogue with the extend function:
<script setup lang="ts">
import { extend } from '@tresjs/core'
import { OrbitControls } from 'three/addons/controls/OrbitControls'
import { TextGeometry } from 'three/addons/geometries/TextGeometry'
// Add the element to the catalogue
extend({ TextGeometry, OrbitControls })
</script>
<template>
<TresCanvas shadows alpha>
<TresPerspectiveCamera :position="[5, 5, 5]" />
<TresOrbitControls v-if="state.renderer" :args="[state.camera, state.renderer?.domElement]" />
<TresMesh>
<TresTextGeometry :args="['TresJS', { font, ...fontOptions }]" center />
<TresMeshMatcapMaterial :matcap="matcapTexture" />
</TresMesh>
</TresCanvas>
</template>