--- 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. ::