TresJS v2 First steps with 3D on Vue

alvarosabu

Alvaro Saburido

Posted on June 20, 2023

TresJS v2 First steps with 3D on Vue

The TresJS team released v2 of TresJS on stage at VueJS Live London 2023 and we made the repo public for the community live on stage.

TresJS live at Vuejs Live London

This version came with a lot of improvements, including some breaking changes (😜 TresJS is now based on Custom Render API), so the first content of the series became obsolete.

So today, we are going to start fresh with the v2 and explain some of the core concepts. The video above is the updated version.

This will be the first article of a series with Basics of TresJS.

It doesn't matter if you don't have previous experience with 3D or ThreeJS, this article will guide you on your first steps using a familiar ecosystem like Vue.

You can follow the series code available on this repository https://github.com/alvarosabu/tresjs-basics

Basic parts of a 3D scene

Parts of a 3D scene

Before jumping to the code, let me quickly explain the parts that make up a 3D scene

  • Objects, could be a sphere, a plane, lights, a 3D model of you favorite character (slide show 3D scene examples resembling the words, make pauses )
  • Then we need a Camera to see those objects, to capture them.
  • We wrap all in a Scene and then
  • We tell the Renderer to render everything into a DOM Canvas element.

Installing

To get started we are going to take a Vue app made with Vite, we are going to install the library by using:

pnpm add @tresjs/core three
Enter fullscreen mode Exit fullscreen mode

If we want to have typescript support, we also need to install the latest types using pnpm add @types/three -D . This will ensure that your IDE gets the proper Intellisense.

Usage

Now let’s open our App.vue and remove the default code and leave the script tag and the template tag empty

Next we import the TresCanvas component from the @tresjs/core package:

<script lang="ts" setup>
import { TresCanvas } from '@tresjs/core'
</script>

<template>
  <TresCanvas>

  </TresCanas>
</template>
Enter fullscreen mode Exit fullscreen mode

Something really important to know is that <TresCanvas /> component will create a <canvas /> DOM element which size (width and height) is exactly the one of it's parent. So if you don't see your scene, it's probably because it has a height of 0px.

To avoid that mistake, we are going to add some minimal css into our App.

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}
#app {
  height: 100%;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

TresCanvas Props

As we would do with normal Vue, you can pass props to your TresCanvas component. Here is the list of props available for the renderer

<TresCanvas :clear-color="'#82DBC5">

</TresCanas>
Enter fullscreen mode Exit fullscreen mode

This will set the background color of the scene to a fun one, however, we still see only a blank page right πŸ€”?

That's because we haven't add a Camera yet.

Perspective Camera

To be able to see (render) our scene, we need a camera, specifically a Perspective Camera which is the most similar to how camera works on videos or cinema.

<TresCanvas :clear-color="'#82DBC5">
 <TresPerspectiveCamera />  
</TresCanas>
Enter fullscreen mode Exit fullscreen mode

Now you should be seeing something like this on your browser.

Empty scene with background

Psst πŸ™Š, this is gonna be improved on upcoming v2.2 where there is a default PerspectiveCamera added by default.

Adding an object

So now that we have "something" render on the browser, let's add a 3D Object.

A Mesh (a.k.a your object) is the rendering result of combining:

  • Geometry: the structure composed of points (vertices), lines (edges) and polygons (faces).
  • Material: are the visual properties of that object, it's color, texture, how reflective it is, if it shines etc.

Mesh is the combination of a Geometry and a Material

All we need to add to our template is a <TresMesh /> component.

<TresMesh>
   <TresBoxGeometry/>
   <TresMeshNormalMaterial />
</TresMesh>
Enter fullscreen mode Exit fullscreen mode

Notice how we pass 2 more components via slots, the TresBoxGeometry and the TresMeshNormalMaterial, both custom render components based on THREE.BoxGeometry and THREE.MeshNormalMaterial from ThreeJS.

Cube Mesh with NormalMaterial

For now, we are going to use a cube with a normal material that resembles the RGB colors (looks pretty cool). In the follow up series we are going to go deeper in Geometries and Materials.

Initialise instances with args

In the previous example we created a Cube of 1x1x1. How can we tell TresJS to create a wider box? We can use args prop to initialise the instance with different arguments.

<TresMesh>
   <TresBoxGeometry :args="[2,1,1]"/>
   <TresMeshNormalMaterial />
</TresMesh>
Enter fullscreen mode Exit fullscreen mode

The result should be something like this:

Box with args

To check what arguments the component expect, you can easily search for the constructor arguments available on the ThreeJS docs

Transform the object

Transforming your mesh is easier that you would imagine. You just need to set a prop for:

  • Position
  • Rotation
  • Scale

You can pass an array of numbers [1, 2, 3] where [x,y,z], or a new THREE.Vector(1,2,3) vector. TresJS will format it for you.

Intellisense showing position prop type

Position

To change the position of an object relative to the world origin [0,0,0] just pass a value to the prop like this:

<TresMesh :position="[1,2,-1]">
   <TresBoxGeometry/>
   <TresMeshNormalMaterial />
</TresMesh>
Enter fullscreen mode Exit fullscreen mode

Box moved to new position

Rotation

In addition to changing the position of an object, you may also want to adjust the rotation. This is typically done using Euler angles in the x, y, and z dimensions. The rotation values are given in radians.

For instance, if you want to rotate an object 90 degrees about the Y axis, you will use Math.PI/2 as the value. You may specify the rotation of the object with the rotation prop, which also takes an array of three values or a Vector3, representing rotations along the x, y, and z axis respectively. Here's an example:

<TresMesh :rotation="[Math.PI/4, Math.PI/2, 0]">
   <TresBoxGeometry/>
   <TresMeshNormalMaterial />
</TresMesh>
Enter fullscreen mode Exit fullscreen mode

Box rotated in X and Y axis

In this example, the mesh is rotated 90 degrees around the Y axis and 45 degrees on the X axis. Notice that we didn't rotate it around Z (values are 0).

Scale

The scale of an object determines its size in the 3D world. It's specified in terms of the scale prop. By default, the scaling factor of an object is 1 in all directions.

You can use the scale prop to make an object larger or smaller. For instance, if you want to make an object twice as wide and half as tall, you could pass [2,0.5,1] as the value to the scale prop, like so:

<TresMesh :scale="[2, 0.5, 1]">
   <TresBoxGeometry/>
   <TresMeshNormalMaterial />
</TresMesh>
Enter fullscreen mode Exit fullscreen mode

Box scaled twice as wide and half as tall

Transform the Camera

Just like other objects in the 3D world, the camera in a 3D scene can also be manipulated in terms of its position and rotation. In Vue, this can be done using the TresPerspectiveCamera component. This is particularly useful to frame the view of your scene to fit your specific needs.

Unlike other objects, though, the camera also has the ability to "look at" a particular point in the scene. This is not equivalent to rotation, as rotation for the camera involves changing the direction it's facing. Instead, "look at" sets the direction the camera is facing to point directly at a specific point.

Here's an example of how you might change the position of the camera and have it look at the center of the scene:

<TresPerspectiveCamera 
    :position="[10,10,10]"
    :lookAt="[0,0,0]"
/>
Enter fullscreen mode Exit fullscreen mode

In this example, the camera is positioned at the coordinates [10,10,10], which would place it in the top right front corner of the scene when looking from the origin. The lookAt prop is used to direct the camera towards the center of the scene, [0,0,0].

The "look at" functionality is extremely useful for focusing the camera on specific areas of a 3D scene, especially when used in combination with adjusting the camera's position. By manipulating these properties, you can achieve an ideal perspective for your particular 3D scene.

Conclusion

In this article, we've explored the core aspects of creating 3D scenes using Tres.js v2 in a Vue application. We started off with the installation process of Tres.js, leading into a basic understanding of 3D scenes, and how to setup the TresCanvas.

We discussed the perspective camera, which is a critical component of a 3D scene. This sets the viewpoint from which your scene will be observed. We also covered how to add objects (meshes) to the scene, which require a geometry and a material. The geometry determines the shape of the object, while the material defines its appearance.

From there, we explored transformation properties, including position, rotation, and scale, which allow you to control where your object is, how it's oriented, and what size it is in the scene. Furthermore, we've seen that not only meshes, but any object in the 3D world, including the camera itself, can be transformed and manipulated to fit the needs of your scene.

This provides a solid basis for getting started with 3D scenes in Vue using Tres.js. Remember, this is just the beginning - there's a whole world of complex and beautiful 3D scenes you can create from here!

As always, if you have any questions, comments, or insights you'd like to share, please feel free to leave them below. Your feedback is not only welcomed, but highly appreciated as it helps us all learn and grow. And remember to stay tuned for more articles in this series as we dive deeper into the fascinating world of 3D modeling with Tres.js and Vue!

Happy coding 😊✌️

πŸ’– πŸ’ͺ πŸ™… 🚩
alvarosabu
Alvaro Saburido

Posted on June 20, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related