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() |
args
Constructor Arguments with
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>