---
title: Your First Scene
description: Learn how to create your first 3D scene with TresJS with this step-by-step guide.
navigation:
icon: i-lucide-donut
---
## What You'll Build
By the end of this guide, you'll have created:
- A 3D scene with a rotating donut
- A reusable component structure
- Animation using TresJS composables
::examples-my-first-scene
::
::steps{level="2"}
## Step 1: Set Up the Canvas Component
First, let's create the main canvas component that will host our 3D scene. This component will contain the `TresCanvas` and handle the overall scene setup.
```vue [app.vue]
```
::note
The `TresCanvas` component is the root container for your 3D scene. The `clear-color` prop sets the background color, and `window-size` makes the canvas automatically fill the entire window without needing a parent container.
::
## Step 2: Set Up the Camera
Let's start by creating the experience component with just a camera. This will allow us to see the clear background color of our canvas.
::tip
**Best Practice**: We recommend separating your `TresCanvas` component from your 3D experience. This pattern helps with organization, reusability, and makes your code easier to maintain.
::
```vue [components/FirstExperience.vue]
```
**What you should see**: A solid turquoise background (`#82DBC5`) filling your entire window.
::note
**Common Mistake**: A common mistake is not setting the camera position, which defaults to `[0, 0, 0]` (the center of the scene). Always position your camera away from the origin to have a proper viewpoint of your 3D objects.
::
The camera defines the viewpoint of your scene:
- `position="[7, 7, 7]"` places the camera at coordinates X=7, Y=7, Z=7 in 3D space
- `look-at="[0, 0, 0]"` points the camera toward the center of the scene
## Step 3: Add Visual Helpers
Before adding our donut, let's add some visual helpers to better understand the 3D space. These helpers will show us the coordinate axes and a grid.
```vue [components/FirstExperience.vue]
```
**What you should see**: A turquoise background with red, green, and blue arrows showing the X, Y, Z axes, plus a grid on the ground plane.
### Understanding the Helpers
- **`TresAxesHelper`**: Shows the coordinate system with colored arrows
- **Red arrow**: X-axis (left/right)
- **Green arrow**: Y-axis (up/down)
- **Blue arrow**: Z-axis (forward/backward)
- **`TresGridHelper`**: Shows a grid on the XZ plane (ground)
- Helps visualize object positioning and scale
- The grid center is at the origin (0, 0, 0)
::tip
**Development Tip**: These helpers are invaluable for development and debugging. Remove them when your scene is ready for production!
::
## Step 4: Add the Donut
Now let's add our 3D donut to the scene. In TresJS, 3D objects are created using a `TresMesh` component with geometry and material as children.
```vue [components/FirstExperience.vue]
```
**What you should see**: A bright orange donut shape in the center of your scene!
### Understanding the Mesh Structure
In TresJS, 3D objects follow a **slot-based pattern**:
- `TresMesh` is the container that represents a 3D object
- The first child defines the **geometry** (shape)
- The second child defines the **material** (appearance)
**Geometry Parameters:**
- `TresTorusGeometry` creates the donut shape with an array of parameters `[radius, tube, radialSegments, tubularSegments]`:
- `radius: 1` - Overall size of the donut
- `tube: 0.4` - Thickness of the donut tube
- `radialSegments: 16` - How smooth the donut curve is
- `tubularSegments: 32` - How smooth the tube surface is
**Material Types:**
- `TresMeshBasicMaterial` - Simple material that doesn't require lighting
- Perfect for beginners and solid colors
## Step 5: Add Animation
Finally, let's make our donut rotate! We'll use TresJS's `useLoop` composable to create smooth animations.
```vue [components/FirstExperience.vue]
```
**What you should see**: Your donut now rotates smoothly on both the X and Y axes!
### Understanding Animation
The animation (system) consists of:
1. **Template Ref**: `ref="donutRef"` creates a reference to the mesh object
2. **useLoop Hook**: Provides access to the render loop
3. **onBeforeRender**: Runs before each frame is rendered
4. **Elapsed Time**: `elapsed` parameter gives us the total time since animation started
```typescript
onBeforeRender(({ elapsed }) => {
if (donutRef.value) {
donutRef.value.rotation.x = elapsed * 0.5 // Rotates on X-axis
donutRef.value.rotation.y = elapsed * 0.3 // Rotates on Y-axis (different speed)
}
})
```
::note
Using `elapsed` time creates smooth, time-based animations that run consistently regardless of frame rate. The multipliers (0.5 and 0.3) control the rotation speed on each axis.
::
## Step 6: Running Your Scene
Your scene is now complete! Since we've set up everything in `app.vue`, your 3D scene will automatically render when you start your application. The `window-size` prop ensures the canvas fills the entire viewport automatically.
::
## Final Project Structure
Here's the complete file structure and code for your first TresJS scene:
:::code-tree{default-value="components/FirstExperience.vue"}
```vue [app.vue]
```
```vue [components/FirstExperience.vue]
```
```typescript [main.ts]
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
```
```json [package.json]
{
"name": "my-first-scene",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"@tresjs/core": "latest",
"three": "^0.158.0",
"vue": "^3.3.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.4.0",
"typescript": "^5.0.2",
"vite": "^4.4.5",
"vue-tsc": "^1.8.5"
}
}
```
```typescript [vite.config.ts]
import { templateCompilerOptions } from '@tresjs/core'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue({
// Other config
...templateCompilerOptions
}),
],
})
```
:::
## Key Concepts Learned
:::card-group
::card{title="Component Separation" icon="i-lucide-layers"}
Separating `TresCanvas` from your 3D experience improves code organization and reusability.
::
::card{title="Objects and Materials" icon="i-lucide-donut"}
In TresJS, 3D objects are created using a `TresMesh` component with geometry and material as children.
::
::card{title="Animation Loop" icon="i-lucide-rotate-cw"}
Using `useLoop` provides a clean way to handle animations and updates in your 3D scene.
::
::card{title="Template Refs" icon="i-lucide-link"}
Using Vue's template refs allows you to directly manipulate 3D objects in your animations.
::
:::
## Next Steps
Now that you have your first scene running, you can:
- **Extract the donut into its own component** - Create a `TheDonut.vue` component to practice component composition
- Experiment with different geometries and materials
- Add more objects to your scene (Get inspired by Three.js's [Geometries](https://threejs.org/manual/#en/primitives) and [Materials](https://threejs.org/manual/#en/materials))
- Try different camera positions and angles
- Explore more complex animations
::tip
Check out our [Cookbook](/cookbook) section to see more complex scenes and learn advanced techniques!
::
::callout{icon="i-lucide-grid-3x3"}
**Related Examples Placeholder**: Add a component here showing cards with related examples like "Basic Primitives", "Lighting Setup", "Animation Patterns", etc.
::