Threlte first scene

Efficiently configure Threlte scene
Threlte is a 3D framework for the web. Built on top of SvelteandThree.js.
Threlte first scene
Installation & Configuration
1. Install required packagesĀ
terminal
npm install three @threlte/core \ @threlte/extras \ @threlte/rapier @dimforge/rapier3d-compat \ @threlte/theatre @theatre/core @theatre/studio \ @threlte/xr
This will install all necessary packages for threlte
2. Configure vite.config.js
vite.config.js
import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vitest/config'; export default defineConfig({ plugins: [sveltekit()], test: { include: ['src/**/*.{test,spec}.{js,ts}'] }, ssr: { noExternal: ['three'] } });
File structure
3. Every threlte consists of a couple of components
3a. Route page aka the ā+page.svelteā [Contains Canvas from threlte core]
3b. 3d Model File, named like 3dModelName.svelte [normally under lib folder, this file is dedicated to the model configuration, material, texture, model loader, etc. ]
3c. Scene File named like Scene3.svelte [HDR, Camera, Grid & import the model file here]
Create svelte threlte component from GLB fileĀ
1. Export the glb model from blender (eg. PaperCup_Tutorial.glb)
2. Copy the glb model to the static folder
3. Open terminal from the sveltekit project folder, using the terminal change your directory to the model folder.
4. Run
terminal
npx @threlte/gltf@next ./PaperCup_Tutorial.glb
5. This will create a svelte component named PaperCup_Tutorial.svelte
Creating the scene file
Here is an example of a scene file, Usually I create this file under "Scenes" folder inside the "lib" folder Check the provided code, I have tried to include the required snippet, you must update the code based on your requirements. You must update the Environment path and files name (In my case, I have a HDR file named "stadium_01_2k.hdr" resides under static/hdr folder, the hdr file downloaded from hdrheaven)
scene.svelte
<script> import { T } from '@threlte/core'; import { Environment, OrbitControls, TransformControls, interactivity, ContactShadows, SoftShadows, HTML } from '@threlte/extras'; import { BoxGeometry, DirectionalLightHelper, MeshStandardMaterial } from 'three'; import { spring, tweened } from 'svelte/motion'; </script> <!-- This requires a .hdr file inside static folder --> <Environment path="/hdr/" files="stadium_01_2k.hdr" isBackground={false} /> <T.PerspectiveCamera makeDefault position={[3, 3, 10]} lookAt.y={0.0} fov={30}> <OrbitControls enableDamping /> </T.PerspectiveCamera> <T.GridHelper args={[10, 10]} /> <TransformControls> <T.Mesh position={[0, 0.5, 0]} scale={7}> <T.SphereGeometry /> <T.MeshStandardMaterial roughness={0} color="gray" side={0} /> </T.Mesh> </TransformControls> <HTML position.y={2} scale={0.5} transform occlude={false} sprite={false} center> <button class="btn btn-primary"> Hello Threlte </button> </HTML> <ContactShadows scale={20} blur={2} far={2.5} opacity={1} position={[0, -1, 0]} />
Creating the route file
1. Open +page.svelte file, Import Canvas and sceneOne (this is the file where we will build the scene)file from library
import { Canvas } from '@threlte/core'; import SceneOne from '../lib/SceneOne.svelte';
2. Inside +page.svelte file, Create a section where we want the canvas to live, the canvas is our placeholder to render all three js objects and interactivitiesĀ
+page.svelte
<section class="p-5"> <div class="canvas-wrapper ring h-[500px]"> <Canvas> <SceneOne /> </Canvas> </div> </section>
3. Letās update the sceneOne.svelte file, in my case, resides under the lib folder which is under the src folder.
Import required packages
sceneOne.svelte
import { PerspectiveCamera, DirectionalLight, AmbientLight, Mesh, useFrame } from '@threlte/core'; import { MeshStandardMaterial, IcosahedronGeometry } from 'three'; import { tweened } from 'svelte/motion'; // tweened take a new number and go from defined number (which is 3 in this case) to that new number // within defined duration (which is 2000 in our case) const t = tweened(0, { duration: 2000 }); const t2 = tweened(1, { duration: 50 }); // setTimeout(() => { // t.set(-3); // }); let rotation = 0; useFrame(() => { rotation += 0.01; });
4. Now create camera, light, and mesh
<PerspectiveCamera position={{ y: 0, z: 20 }} lookAt={{ x: 0, y: 0, z: 0 }} /> <DirectionalLight /> <AmbientLight /> <!-- when we want to interact with any 3d object we must set the properties to 'interactive' --> <Mesh geometry={new IcosahedronGeometry()} material={new MeshStandardMaterial({ color: 'seagreen' })} position={{ x: $t, y: 0, z: 15 }} rotation={{ x: rotation, y: 0, z: rotation }} scale={$t2} interactive on:pointerleave={() => { $t2 = 1; // console.log('reverse pointer enter'); }} on:pointerenter={() => { $t2 = 1.3; // console.log('pointer enter'); }} on:click={() => { $t = $t > 0 ? -4 : 4; }} />
Thatās pretty much it