├── .gitignore
├── README.md
├── declarations.d.ts
├── package.json
├── src
├── index.html
├── script.ts
├── shaders
│ ├── fragment.glsl
│ └── vertex.glsl
└── style.css
├── static
└── boilerplate.gif
├── tsconfig.json
└── vite.config.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Basic Three.js Template
2 |
3 | ## Now supports TypeScript as well
4 |
5 | A streamlined boilerplate for Three.js projects, designed to get you up and running quickly.
6 |
7 | 
8 |
9 | ## 🚀 Quick Start
10 |
11 | Follow these steps to set up your project using this boilerplate:
12 |
13 | ```bash
14 | # Clone the repository and cd into the project
15 | git clone https://github.com/zoyron/threejs-boilerplate.git your-project-name
16 | cd your-project-name
17 |
18 | # Remove git history and start fresh with your own Git history
19 | rm -rf .git
20 | git init
21 |
22 | # Install dependencies
23 | npm install
24 |
25 | # Run the development server
26 | npm run dev
27 | ```
28 |
29 | Your project is now running at http://localhost:5173 (or another port if 5173 is occupied).
30 |
31 | ## Threejs Project Structure
32 |
33 | ### Base Setup(includes the following):
34 |
35 | - Canvas
36 | - Scene
37 | - Sizes(the object)
38 |
39 | ### The Camera, groups(optional) and lights(optional):
40 |
41 | - Perspective Camera(most usualy and popular choice)
42 | - Lights(optional, with ambient light being the most popular choice)
43 |
44 | ### Creating an object and adding it to scene
45 |
46 | - Creating geometry or points-geometry; could be inbuilt, custom, random or using shaders
47 | - Creating material or points-material; could be inbuilt, custom, random or using shaders
48 | - Creating mesh or points; could be inbuilt, custom, random or using shaders
49 |
50 | > above three are the points where we mostly use shaders
51 |
52 | - Adding the created mesh or points to the scene or group
53 |
54 | ### Renderer and Resizing
55 |
56 | - Adding a scene renderer
57 | - Adding a window resizing event listener, and updating the render inside it
58 |
59 | ### Controls and Animate function
60 |
61 | - Adding orbit controls and damping them if required
62 | - adding the animate() function, and giving necessary logic and functionality to it
63 | - calling the animate() function
64 |
--------------------------------------------------------------------------------
/declarations.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.glsl" {
2 | const content: string;
3 | export default content;
4 | }
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "threejs-template",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "typescript": "^5.5.3",
13 | "vite": "^6.2.0",
14 | "vite-plugin-glsl": "^1.3.0",
15 | "vite-plugin-restart": "^0.4.1"
16 | },
17 | "dependencies": {
18 | "@types/three": "^0.169.0",
19 | "lil-gui": "^0.20.0",
20 | "three": "^0.174.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Threejs Template
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/script.ts:
--------------------------------------------------------------------------------
1 | import * as THREE from "three";
2 | import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
3 |
4 | /**
5 | * Base setup
6 | */
7 |
8 | // Canvas
9 | const canvas = document.querySelector("canvas.webgl");
10 |
11 | // Scene
12 | const scene = new THREE.Scene();
13 | scene.background = new THREE.Color(0xf0f0f0);
14 |
15 | // Sizes
16 | const sizes = {
17 | width: window.innerWidth,
18 | height: window.innerHeight,
19 | };
20 |
21 | /**
22 | * Camera and lights(optional)
23 | */
24 |
25 | // Perspective Camera
26 | const camera = new THREE.PerspectiveCamera(
27 | 75,
28 | sizes.width / sizes.height,
29 | 0.1,
30 | 1000
31 | );
32 | camera.position.set(3, 3, 3);
33 | scene.add(camera);
34 |
35 | /**
36 | * Adding a base mesh
37 | */
38 | const side = 1;
39 | const geometry = new THREE.BoxGeometry(side,side,side, 8, 8, 8);
40 | const material = new THREE.MeshNormalMaterial();
41 | const mesh = new THREE.Mesh(geometry, material);
42 | scene.add(mesh);
43 |
44 | /**
45 | * Renderer and Resizing
46 | */
47 | // renderer
48 | const renderer = new THREE.WebGLRenderer({
49 | canvas: canvas,
50 | });
51 | renderer.setSize(sizes.width, sizes.height);
52 | renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
53 |
54 | // Resizing
55 | window.addEventListener("resize", () => {
56 | // Update sizes
57 | sizes.width = window.innerWidth;
58 | sizes.height = window.innerHeight;
59 |
60 | // Update camera
61 | camera.aspect = sizes.width / sizes.height;
62 | camera.updateProjectionMatrix();
63 |
64 | // Update renderer
65 | renderer.setSize(sizes.width, sizes.height);
66 | renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
67 | });
68 |
69 | /**
70 | * Animate and controls
71 | */
72 | // Controls
73 | const controls = new OrbitControls(camera, canvas);
74 | controls.enableDamping = true;
75 |
76 | // Animate
77 | const animate = () => {
78 | // Rotate mesh
79 | mesh.rotation.x += 0.0125;
80 | mesh.rotation.y += 0.0125;
81 |
82 | // Update controls
83 | controls.update();
84 |
85 | // Adding renderer
86 | renderer.render(scene, camera);
87 |
88 | // Call animate again on the next frame
89 | window.requestAnimationFrame(animate);
90 | };
91 |
92 | animate();
93 |
--------------------------------------------------------------------------------
/src/shaders/fragment.glsl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zoyron/threejs-template/dd312257598e33ae019ba1d326bd23ebf96d7be0/src/shaders/fragment.glsl
--------------------------------------------------------------------------------
/src/shaders/vertex.glsl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zoyron/threejs-template/dd312257598e33ae019ba1d326bd23ebf96d7be0/src/shaders/vertex.glsl
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | body,
2 | html {
3 | margin: 0;
4 | padding: 0;
5 | width: 100%;
6 | height: 100vh;
7 | overflow: hidden;
8 | background-color: black;
9 | }
10 |
11 | canvas {
12 | display: block;
13 | position: fixed;
14 | top: 0;
15 | left: 0;
16 | width: 100%;
17 | height: 100%;
18 | }
19 |
--------------------------------------------------------------------------------
/static/boilerplate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zoyron/threejs-template/dd312257598e33ae019ba1d326bd23ebf96d7be0/static/boilerplate.gif
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "module": "ESNext",
6 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "isolatedModules": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noFallthroughCasesInSwitch": true
21 | },
22 | "include": ["src/**/*.ts", "declarations.d.ts"]
23 | }
24 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import restart from 'vite-plugin-restart'
2 | import glsl from 'vite-plugin-glsl'
3 |
4 | export default {
5 | root: 'src/',
6 | publicDir: '../static/',
7 | base: './',
8 | server:
9 | {
10 | host: true, // Open to local network and display URL
11 | open: !('SANDBOX_URL' in process.env || 'CODESANDBOX_HOST' in process.env) // Open if it's not a CodeSandbox
12 | },
13 | build:
14 | {
15 | outDir: '../dist', // Output in the dist/ folder
16 | emptyOutDir: true, // Empty the folder first
17 | sourcemap: true // Add sourcemap
18 | },
19 | plugins:
20 | [
21 | restart({ restart: [ '../static/**', ] }), // Restart server on static file change
22 | glsl() // Handle shader files
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------