├── .gitignore
├── index.html
├── package-lock.json
├── package.json
├── public
├── LeePerrySmith
│ ├── LeePerrySmith.glb
│ ├── LeePerrySmith_License.txt
│ ├── color.jpg
│ └── normal.jpg
├── chars.png
├── david_head
│ ├── license.txt
│ ├── scene.bin
│ └── scene.gltf
└── vite.svg
├── src
├── canvas.ts
├── components
│ └── model.ts
├── main.ts
├── shaders
│ └── ascii
│ │ └── ascii.glsl
├── style.css
├── types
│ └── types.ts
└── utils
│ └── ascii-effect.ts
├── tsconfig.json
└── vite.config.js
/.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 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + TS
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "three-js-boilerplate",
3 | "version": "0.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "three-js-boilerplate",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "lil-gui": "^0.19.2",
12 | "three": "^0.167.0",
13 | "vite-plugin-glsl": "^1.3.0"
14 | },
15 | "devDependencies": {
16 | "@types/three": "^0.167.1",
17 | "typescript": "^5.2.2",
18 | "vite": "^5.3.4"
19 | }
20 | },
21 | "node_modules/@esbuild/aix-ppc64": {
22 | "version": "0.21.5",
23 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
24 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
25 | "cpu": [
26 | "ppc64"
27 | ],
28 | "optional": true,
29 | "os": [
30 | "aix"
31 | ],
32 | "engines": {
33 | "node": ">=12"
34 | }
35 | },
36 | "node_modules/@esbuild/android-arm": {
37 | "version": "0.21.5",
38 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
39 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
40 | "cpu": [
41 | "arm"
42 | ],
43 | "optional": true,
44 | "os": [
45 | "android"
46 | ],
47 | "engines": {
48 | "node": ">=12"
49 | }
50 | },
51 | "node_modules/@esbuild/android-arm64": {
52 | "version": "0.21.5",
53 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
54 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
55 | "cpu": [
56 | "arm64"
57 | ],
58 | "optional": true,
59 | "os": [
60 | "android"
61 | ],
62 | "engines": {
63 | "node": ">=12"
64 | }
65 | },
66 | "node_modules/@esbuild/android-x64": {
67 | "version": "0.21.5",
68 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
69 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
70 | "cpu": [
71 | "x64"
72 | ],
73 | "optional": true,
74 | "os": [
75 | "android"
76 | ],
77 | "engines": {
78 | "node": ">=12"
79 | }
80 | },
81 | "node_modules/@esbuild/darwin-arm64": {
82 | "version": "0.21.5",
83 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
84 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
85 | "cpu": [
86 | "arm64"
87 | ],
88 | "optional": true,
89 | "os": [
90 | "darwin"
91 | ],
92 | "engines": {
93 | "node": ">=12"
94 | }
95 | },
96 | "node_modules/@esbuild/darwin-x64": {
97 | "version": "0.21.5",
98 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
99 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
100 | "cpu": [
101 | "x64"
102 | ],
103 | "optional": true,
104 | "os": [
105 | "darwin"
106 | ],
107 | "engines": {
108 | "node": ">=12"
109 | }
110 | },
111 | "node_modules/@esbuild/freebsd-arm64": {
112 | "version": "0.21.5",
113 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
114 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
115 | "cpu": [
116 | "arm64"
117 | ],
118 | "optional": true,
119 | "os": [
120 | "freebsd"
121 | ],
122 | "engines": {
123 | "node": ">=12"
124 | }
125 | },
126 | "node_modules/@esbuild/freebsd-x64": {
127 | "version": "0.21.5",
128 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
129 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
130 | "cpu": [
131 | "x64"
132 | ],
133 | "optional": true,
134 | "os": [
135 | "freebsd"
136 | ],
137 | "engines": {
138 | "node": ">=12"
139 | }
140 | },
141 | "node_modules/@esbuild/linux-arm": {
142 | "version": "0.21.5",
143 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
144 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
145 | "cpu": [
146 | "arm"
147 | ],
148 | "optional": true,
149 | "os": [
150 | "linux"
151 | ],
152 | "engines": {
153 | "node": ">=12"
154 | }
155 | },
156 | "node_modules/@esbuild/linux-arm64": {
157 | "version": "0.21.5",
158 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
159 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
160 | "cpu": [
161 | "arm64"
162 | ],
163 | "optional": true,
164 | "os": [
165 | "linux"
166 | ],
167 | "engines": {
168 | "node": ">=12"
169 | }
170 | },
171 | "node_modules/@esbuild/linux-ia32": {
172 | "version": "0.21.5",
173 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
174 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
175 | "cpu": [
176 | "ia32"
177 | ],
178 | "optional": true,
179 | "os": [
180 | "linux"
181 | ],
182 | "engines": {
183 | "node": ">=12"
184 | }
185 | },
186 | "node_modules/@esbuild/linux-loong64": {
187 | "version": "0.21.5",
188 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
189 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
190 | "cpu": [
191 | "loong64"
192 | ],
193 | "optional": true,
194 | "os": [
195 | "linux"
196 | ],
197 | "engines": {
198 | "node": ">=12"
199 | }
200 | },
201 | "node_modules/@esbuild/linux-mips64el": {
202 | "version": "0.21.5",
203 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
204 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
205 | "cpu": [
206 | "mips64el"
207 | ],
208 | "optional": true,
209 | "os": [
210 | "linux"
211 | ],
212 | "engines": {
213 | "node": ">=12"
214 | }
215 | },
216 | "node_modules/@esbuild/linux-ppc64": {
217 | "version": "0.21.5",
218 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
219 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
220 | "cpu": [
221 | "ppc64"
222 | ],
223 | "optional": true,
224 | "os": [
225 | "linux"
226 | ],
227 | "engines": {
228 | "node": ">=12"
229 | }
230 | },
231 | "node_modules/@esbuild/linux-riscv64": {
232 | "version": "0.21.5",
233 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
234 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
235 | "cpu": [
236 | "riscv64"
237 | ],
238 | "optional": true,
239 | "os": [
240 | "linux"
241 | ],
242 | "engines": {
243 | "node": ">=12"
244 | }
245 | },
246 | "node_modules/@esbuild/linux-s390x": {
247 | "version": "0.21.5",
248 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
249 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
250 | "cpu": [
251 | "s390x"
252 | ],
253 | "optional": true,
254 | "os": [
255 | "linux"
256 | ],
257 | "engines": {
258 | "node": ">=12"
259 | }
260 | },
261 | "node_modules/@esbuild/linux-x64": {
262 | "version": "0.21.5",
263 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
264 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
265 | "cpu": [
266 | "x64"
267 | ],
268 | "optional": true,
269 | "os": [
270 | "linux"
271 | ],
272 | "engines": {
273 | "node": ">=12"
274 | }
275 | },
276 | "node_modules/@esbuild/netbsd-x64": {
277 | "version": "0.21.5",
278 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
279 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
280 | "cpu": [
281 | "x64"
282 | ],
283 | "optional": true,
284 | "os": [
285 | "netbsd"
286 | ],
287 | "engines": {
288 | "node": ">=12"
289 | }
290 | },
291 | "node_modules/@esbuild/openbsd-x64": {
292 | "version": "0.21.5",
293 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
294 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
295 | "cpu": [
296 | "x64"
297 | ],
298 | "optional": true,
299 | "os": [
300 | "openbsd"
301 | ],
302 | "engines": {
303 | "node": ">=12"
304 | }
305 | },
306 | "node_modules/@esbuild/sunos-x64": {
307 | "version": "0.21.5",
308 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
309 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
310 | "cpu": [
311 | "x64"
312 | ],
313 | "optional": true,
314 | "os": [
315 | "sunos"
316 | ],
317 | "engines": {
318 | "node": ">=12"
319 | }
320 | },
321 | "node_modules/@esbuild/win32-arm64": {
322 | "version": "0.21.5",
323 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
324 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
325 | "cpu": [
326 | "arm64"
327 | ],
328 | "optional": true,
329 | "os": [
330 | "win32"
331 | ],
332 | "engines": {
333 | "node": ">=12"
334 | }
335 | },
336 | "node_modules/@esbuild/win32-ia32": {
337 | "version": "0.21.5",
338 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
339 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
340 | "cpu": [
341 | "ia32"
342 | ],
343 | "optional": true,
344 | "os": [
345 | "win32"
346 | ],
347 | "engines": {
348 | "node": ">=12"
349 | }
350 | },
351 | "node_modules/@esbuild/win32-x64": {
352 | "version": "0.21.5",
353 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
354 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
355 | "cpu": [
356 | "x64"
357 | ],
358 | "optional": true,
359 | "os": [
360 | "win32"
361 | ],
362 | "engines": {
363 | "node": ">=12"
364 | }
365 | },
366 | "node_modules/@rollup/pluginutils": {
367 | "version": "5.1.0",
368 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
369 | "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
370 | "dependencies": {
371 | "@types/estree": "^1.0.0",
372 | "estree-walker": "^2.0.2",
373 | "picomatch": "^2.3.1"
374 | },
375 | "engines": {
376 | "node": ">=14.0.0"
377 | },
378 | "peerDependencies": {
379 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
380 | },
381 | "peerDependenciesMeta": {
382 | "rollup": {
383 | "optional": true
384 | }
385 | }
386 | },
387 | "node_modules/@rollup/rollup-android-arm-eabi": {
388 | "version": "4.21.1",
389 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz",
390 | "integrity": "sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==",
391 | "cpu": [
392 | "arm"
393 | ],
394 | "optional": true,
395 | "os": [
396 | "android"
397 | ]
398 | },
399 | "node_modules/@rollup/rollup-android-arm64": {
400 | "version": "4.21.1",
401 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz",
402 | "integrity": "sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==",
403 | "cpu": [
404 | "arm64"
405 | ],
406 | "optional": true,
407 | "os": [
408 | "android"
409 | ]
410 | },
411 | "node_modules/@rollup/rollup-darwin-arm64": {
412 | "version": "4.21.1",
413 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz",
414 | "integrity": "sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==",
415 | "cpu": [
416 | "arm64"
417 | ],
418 | "optional": true,
419 | "os": [
420 | "darwin"
421 | ]
422 | },
423 | "node_modules/@rollup/rollup-darwin-x64": {
424 | "version": "4.21.1",
425 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz",
426 | "integrity": "sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==",
427 | "cpu": [
428 | "x64"
429 | ],
430 | "optional": true,
431 | "os": [
432 | "darwin"
433 | ]
434 | },
435 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
436 | "version": "4.21.1",
437 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz",
438 | "integrity": "sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==",
439 | "cpu": [
440 | "arm"
441 | ],
442 | "optional": true,
443 | "os": [
444 | "linux"
445 | ]
446 | },
447 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
448 | "version": "4.21.1",
449 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz",
450 | "integrity": "sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==",
451 | "cpu": [
452 | "arm"
453 | ],
454 | "optional": true,
455 | "os": [
456 | "linux"
457 | ]
458 | },
459 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
460 | "version": "4.21.1",
461 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz",
462 | "integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==",
463 | "cpu": [
464 | "arm64"
465 | ],
466 | "optional": true,
467 | "os": [
468 | "linux"
469 | ]
470 | },
471 | "node_modules/@rollup/rollup-linux-arm64-musl": {
472 | "version": "4.21.1",
473 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz",
474 | "integrity": "sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==",
475 | "cpu": [
476 | "arm64"
477 | ],
478 | "optional": true,
479 | "os": [
480 | "linux"
481 | ]
482 | },
483 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
484 | "version": "4.21.1",
485 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz",
486 | "integrity": "sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==",
487 | "cpu": [
488 | "ppc64"
489 | ],
490 | "optional": true,
491 | "os": [
492 | "linux"
493 | ]
494 | },
495 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
496 | "version": "4.21.1",
497 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz",
498 | "integrity": "sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==",
499 | "cpu": [
500 | "riscv64"
501 | ],
502 | "optional": true,
503 | "os": [
504 | "linux"
505 | ]
506 | },
507 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
508 | "version": "4.21.1",
509 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz",
510 | "integrity": "sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==",
511 | "cpu": [
512 | "s390x"
513 | ],
514 | "optional": true,
515 | "os": [
516 | "linux"
517 | ]
518 | },
519 | "node_modules/@rollup/rollup-linux-x64-gnu": {
520 | "version": "4.21.1",
521 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz",
522 | "integrity": "sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==",
523 | "cpu": [
524 | "x64"
525 | ],
526 | "optional": true,
527 | "os": [
528 | "linux"
529 | ]
530 | },
531 | "node_modules/@rollup/rollup-linux-x64-musl": {
532 | "version": "4.21.1",
533 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz",
534 | "integrity": "sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==",
535 | "cpu": [
536 | "x64"
537 | ],
538 | "optional": true,
539 | "os": [
540 | "linux"
541 | ]
542 | },
543 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
544 | "version": "4.21.1",
545 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz",
546 | "integrity": "sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==",
547 | "cpu": [
548 | "arm64"
549 | ],
550 | "optional": true,
551 | "os": [
552 | "win32"
553 | ]
554 | },
555 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
556 | "version": "4.21.1",
557 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz",
558 | "integrity": "sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==",
559 | "cpu": [
560 | "ia32"
561 | ],
562 | "optional": true,
563 | "os": [
564 | "win32"
565 | ]
566 | },
567 | "node_modules/@rollup/rollup-win32-x64-msvc": {
568 | "version": "4.21.1",
569 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz",
570 | "integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==",
571 | "cpu": [
572 | "x64"
573 | ],
574 | "optional": true,
575 | "os": [
576 | "win32"
577 | ]
578 | },
579 | "node_modules/@tweenjs/tween.js": {
580 | "version": "23.1.3",
581 | "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
582 | "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
583 | "dev": true
584 | },
585 | "node_modules/@types/estree": {
586 | "version": "1.0.5",
587 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
588 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
589 | },
590 | "node_modules/@types/stats.js": {
591 | "version": "0.17.3",
592 | "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz",
593 | "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==",
594 | "dev": true
595 | },
596 | "node_modules/@types/three": {
597 | "version": "0.167.2",
598 | "resolved": "https://registry.npmjs.org/@types/three/-/three-0.167.2.tgz",
599 | "integrity": "sha512-onxnIUNYpXcZJ5DTiIsxfnr4F9kAWkkxAUWx5yqzz/u0a4IygCLCjMuOl2DEeCxyJdJ2nOJZvKpu48sBMqfmkQ==",
600 | "dev": true,
601 | "dependencies": {
602 | "@tweenjs/tween.js": "~23.1.2",
603 | "@types/stats.js": "*",
604 | "@types/webxr": "*",
605 | "fflate": "~0.8.2",
606 | "meshoptimizer": "~0.18.1"
607 | }
608 | },
609 | "node_modules/@types/webxr": {
610 | "version": "0.5.20",
611 | "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.20.tgz",
612 | "integrity": "sha512-JGpU6qiIJQKUuVSKx1GtQnHJGxRjtfGIhzO2ilq43VZZS//f1h1Sgexbdk+Lq+7569a6EYhOWrUpIruR/1Enmg==",
613 | "dev": true
614 | },
615 | "node_modules/esbuild": {
616 | "version": "0.21.5",
617 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
618 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
619 | "hasInstallScript": true,
620 | "bin": {
621 | "esbuild": "bin/esbuild"
622 | },
623 | "engines": {
624 | "node": ">=12"
625 | },
626 | "optionalDependencies": {
627 | "@esbuild/aix-ppc64": "0.21.5",
628 | "@esbuild/android-arm": "0.21.5",
629 | "@esbuild/android-arm64": "0.21.5",
630 | "@esbuild/android-x64": "0.21.5",
631 | "@esbuild/darwin-arm64": "0.21.5",
632 | "@esbuild/darwin-x64": "0.21.5",
633 | "@esbuild/freebsd-arm64": "0.21.5",
634 | "@esbuild/freebsd-x64": "0.21.5",
635 | "@esbuild/linux-arm": "0.21.5",
636 | "@esbuild/linux-arm64": "0.21.5",
637 | "@esbuild/linux-ia32": "0.21.5",
638 | "@esbuild/linux-loong64": "0.21.5",
639 | "@esbuild/linux-mips64el": "0.21.5",
640 | "@esbuild/linux-ppc64": "0.21.5",
641 | "@esbuild/linux-riscv64": "0.21.5",
642 | "@esbuild/linux-s390x": "0.21.5",
643 | "@esbuild/linux-x64": "0.21.5",
644 | "@esbuild/netbsd-x64": "0.21.5",
645 | "@esbuild/openbsd-x64": "0.21.5",
646 | "@esbuild/sunos-x64": "0.21.5",
647 | "@esbuild/win32-arm64": "0.21.5",
648 | "@esbuild/win32-ia32": "0.21.5",
649 | "@esbuild/win32-x64": "0.21.5"
650 | }
651 | },
652 | "node_modules/estree-walker": {
653 | "version": "2.0.2",
654 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
655 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
656 | },
657 | "node_modules/fflate": {
658 | "version": "0.8.2",
659 | "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
660 | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
661 | "dev": true
662 | },
663 | "node_modules/fsevents": {
664 | "version": "2.3.3",
665 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
666 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
667 | "hasInstallScript": true,
668 | "optional": true,
669 | "os": [
670 | "darwin"
671 | ],
672 | "engines": {
673 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
674 | }
675 | },
676 | "node_modules/lil-gui": {
677 | "version": "0.19.2",
678 | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.19.2.tgz",
679 | "integrity": "sha512-nU8j4ND702ouGfQZoaTN4dfXxacvGOAVK0DtmZBVcUYUAeYQXLQAjAN50igMHiba3T5jZyKEjXZU+Ntm1Qs6ZQ=="
680 | },
681 | "node_modules/meshoptimizer": {
682 | "version": "0.18.1",
683 | "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz",
684 | "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==",
685 | "dev": true
686 | },
687 | "node_modules/nanoid": {
688 | "version": "3.3.7",
689 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
690 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
691 | "funding": [
692 | {
693 | "type": "github",
694 | "url": "https://github.com/sponsors/ai"
695 | }
696 | ],
697 | "bin": {
698 | "nanoid": "bin/nanoid.cjs"
699 | },
700 | "engines": {
701 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
702 | }
703 | },
704 | "node_modules/picocolors": {
705 | "version": "1.0.1",
706 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
707 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
708 | },
709 | "node_modules/picomatch": {
710 | "version": "2.3.1",
711 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
712 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
713 | "engines": {
714 | "node": ">=8.6"
715 | },
716 | "funding": {
717 | "url": "https://github.com/sponsors/jonschlinkert"
718 | }
719 | },
720 | "node_modules/postcss": {
721 | "version": "8.4.41",
722 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
723 | "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
724 | "funding": [
725 | {
726 | "type": "opencollective",
727 | "url": "https://opencollective.com/postcss/"
728 | },
729 | {
730 | "type": "tidelift",
731 | "url": "https://tidelift.com/funding/github/npm/postcss"
732 | },
733 | {
734 | "type": "github",
735 | "url": "https://github.com/sponsors/ai"
736 | }
737 | ],
738 | "dependencies": {
739 | "nanoid": "^3.3.7",
740 | "picocolors": "^1.0.1",
741 | "source-map-js": "^1.2.0"
742 | },
743 | "engines": {
744 | "node": "^10 || ^12 || >=14"
745 | }
746 | },
747 | "node_modules/rollup": {
748 | "version": "4.21.1",
749 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.1.tgz",
750 | "integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==",
751 | "dependencies": {
752 | "@types/estree": "1.0.5"
753 | },
754 | "bin": {
755 | "rollup": "dist/bin/rollup"
756 | },
757 | "engines": {
758 | "node": ">=18.0.0",
759 | "npm": ">=8.0.0"
760 | },
761 | "optionalDependencies": {
762 | "@rollup/rollup-android-arm-eabi": "4.21.1",
763 | "@rollup/rollup-android-arm64": "4.21.1",
764 | "@rollup/rollup-darwin-arm64": "4.21.1",
765 | "@rollup/rollup-darwin-x64": "4.21.1",
766 | "@rollup/rollup-linux-arm-gnueabihf": "4.21.1",
767 | "@rollup/rollup-linux-arm-musleabihf": "4.21.1",
768 | "@rollup/rollup-linux-arm64-gnu": "4.21.1",
769 | "@rollup/rollup-linux-arm64-musl": "4.21.1",
770 | "@rollup/rollup-linux-powerpc64le-gnu": "4.21.1",
771 | "@rollup/rollup-linux-riscv64-gnu": "4.21.1",
772 | "@rollup/rollup-linux-s390x-gnu": "4.21.1",
773 | "@rollup/rollup-linux-x64-gnu": "4.21.1",
774 | "@rollup/rollup-linux-x64-musl": "4.21.1",
775 | "@rollup/rollup-win32-arm64-msvc": "4.21.1",
776 | "@rollup/rollup-win32-ia32-msvc": "4.21.1",
777 | "@rollup/rollup-win32-x64-msvc": "4.21.1",
778 | "fsevents": "~2.3.2"
779 | }
780 | },
781 | "node_modules/source-map-js": {
782 | "version": "1.2.0",
783 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
784 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
785 | "engines": {
786 | "node": ">=0.10.0"
787 | }
788 | },
789 | "node_modules/three": {
790 | "version": "0.167.1",
791 | "resolved": "https://registry.npmjs.org/three/-/three-0.167.1.tgz",
792 | "integrity": "sha512-gYTLJA/UQip6J/tJvl91YYqlZF47+D/kxiWrbTon35ZHlXEN0VOo+Qke2walF1/x92v55H6enomymg4Dak52kw=="
793 | },
794 | "node_modules/typescript": {
795 | "version": "5.5.4",
796 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
797 | "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
798 | "dev": true,
799 | "bin": {
800 | "tsc": "bin/tsc",
801 | "tsserver": "bin/tsserver"
802 | },
803 | "engines": {
804 | "node": ">=14.17"
805 | }
806 | },
807 | "node_modules/vite": {
808 | "version": "5.4.2",
809 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
810 | "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
811 | "dependencies": {
812 | "esbuild": "^0.21.3",
813 | "postcss": "^8.4.41",
814 | "rollup": "^4.20.0"
815 | },
816 | "bin": {
817 | "vite": "bin/vite.js"
818 | },
819 | "engines": {
820 | "node": "^18.0.0 || >=20.0.0"
821 | },
822 | "funding": {
823 | "url": "https://github.com/vitejs/vite?sponsor=1"
824 | },
825 | "optionalDependencies": {
826 | "fsevents": "~2.3.3"
827 | },
828 | "peerDependencies": {
829 | "@types/node": "^18.0.0 || >=20.0.0",
830 | "less": "*",
831 | "lightningcss": "^1.21.0",
832 | "sass": "*",
833 | "sass-embedded": "*",
834 | "stylus": "*",
835 | "sugarss": "*",
836 | "terser": "^5.4.0"
837 | },
838 | "peerDependenciesMeta": {
839 | "@types/node": {
840 | "optional": true
841 | },
842 | "less": {
843 | "optional": true
844 | },
845 | "lightningcss": {
846 | "optional": true
847 | },
848 | "sass": {
849 | "optional": true
850 | },
851 | "sass-embedded": {
852 | "optional": true
853 | },
854 | "stylus": {
855 | "optional": true
856 | },
857 | "sugarss": {
858 | "optional": true
859 | },
860 | "terser": {
861 | "optional": true
862 | }
863 | }
864 | },
865 | "node_modules/vite-plugin-glsl": {
866 | "version": "1.3.0",
867 | "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-1.3.0.tgz",
868 | "integrity": "sha512-SzEoLet9Bp5VSozjrhUiSc3xX1+u7rCTjXAsq4qWM3u8UjilI76A9ucX/T+CRGQCe25j50GSY+9mKSGUVPET1w==",
869 | "dependencies": {
870 | "@rollup/pluginutils": "^5.1.0"
871 | },
872 | "engines": {
873 | "node": ">= 16.15.1",
874 | "npm": ">= 8.11.0"
875 | },
876 | "peerDependencies": {
877 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
878 | }
879 | }
880 | }
881 | }
882 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "three-js-boilerplate",
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 | "@types/three": "^0.167.1",
13 | "typescript": "^5.2.2",
14 | "vite": "^5.3.4"
15 | },
16 | "dependencies": {
17 | "lil-gui": "^0.19.2",
18 | "three": "^0.167.0",
19 | "vite-plugin-glsl": "^1.3.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/public/LeePerrySmith/LeePerrySmith.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J0SUKE/ASCII-postprocessing/95bc63d0f69105538edca398382973f7cd3f8626/public/LeePerrySmith/LeePerrySmith.glb
--------------------------------------------------------------------------------
/public/LeePerrySmith/LeePerrySmith_License.txt:
--------------------------------------------------------------------------------
1 | Creative Commons Licence
2 | Infinite, 3D Head Scan by Lee Perry-Smith is licensed under a Creative Commons Attribution 3.0 Unported License.
3 | Based on a work at www.triplegangers.com.
4 | File named modified by Bruno SIMON to simplify importing.
5 | Permissions beyond the scope of this license may be available at http://www.ir-ltd.net/
6 | Please remember: Do what you want with the files, but always mention where you got them from...
7 |
--------------------------------------------------------------------------------
/public/LeePerrySmith/color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J0SUKE/ASCII-postprocessing/95bc63d0f69105538edca398382973f7cd3f8626/public/LeePerrySmith/color.jpg
--------------------------------------------------------------------------------
/public/LeePerrySmith/normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J0SUKE/ASCII-postprocessing/95bc63d0f69105538edca398382973f7cd3f8626/public/LeePerrySmith/normal.jpg
--------------------------------------------------------------------------------
/public/chars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J0SUKE/ASCII-postprocessing/95bc63d0f69105538edca398382973f7cd3f8626/public/chars.png
--------------------------------------------------------------------------------
/public/david_head/license.txt:
--------------------------------------------------------------------------------
1 | Model Information:
2 | * title: David Head
3 | * source: https://sketchfab.com/3d-models/david-head-39a4d01bef37495cac8d8f0009728871
4 | * author: 1d_inc (https://sketchfab.com/1d_inc)
5 |
6 | Model License:
7 | * license type: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
8 | * requirements: Author must be credited. Commercial use is allowed.
9 |
10 | If you use this 3D model in your project be sure to copy paste this credit wherever you share it:
11 | This work is based on "David Head" (https://sketchfab.com/3d-models/david-head-39a4d01bef37495cac8d8f0009728871) by 1d_inc (https://sketchfab.com/1d_inc) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
--------------------------------------------------------------------------------
/public/david_head/scene.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J0SUKE/ASCII-postprocessing/95bc63d0f69105538edca398382973f7cd3f8626/public/david_head/scene.bin
--------------------------------------------------------------------------------
/public/david_head/scene.gltf:
--------------------------------------------------------------------------------
1 | {
2 | "accessors": [
3 | {
4 | "bufferView": 2,
5 | "componentType": 5126,
6 | "count": 24011,
7 | "max": [
8 | 72.03296661376953,
9 | 120.36872863769531,
10 | 99.9263916015625
11 | ],
12 | "min": [
13 | -58.47863006591797,
14 | -30.07625961303711,
15 | -97.18975067138672
16 | ],
17 | "type": "VEC3"
18 | },
19 | {
20 | "bufferView": 2,
21 | "byteOffset": 288132,
22 | "componentType": 5126,
23 | "count": 24011,
24 | "max": [
25 | 0.9999601244926453,
26 | 0.9999906420707703,
27 | 0.9999125003814697
28 | ],
29 | "min": [
30 | -0.9999507069587708,
31 | -0.9999876618385315,
32 | -0.9999999403953552
33 | ],
34 | "type": "VEC3"
35 | },
36 | {
37 | "bufferView": 1,
38 | "componentType": 5126,
39 | "count": 24011,
40 | "max": [
41 | 0.9793000221252441,
42 | 0.999809980392456
43 | ],
44 | "min": [
45 | 0.0001900000061141327,
46 | 0.0001900000061141327
47 | ],
48 | "type": "VEC2"
49 | },
50 | {
51 | "bufferView": 0,
52 | "componentType": 5125,
53 | "count": 139992,
54 | "type": "SCALAR"
55 | }
56 | ],
57 | "asset": {
58 | "extras": {
59 | "author": "1d_inc (https://sketchfab.com/1d_inc)",
60 | "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)",
61 | "source": "https://sketchfab.com/3d-models/david-head-39a4d01bef37495cac8d8f0009728871",
62 | "title": "David Head"
63 | },
64 | "generator": "Sketchfab-15.33.0",
65 | "version": "2.0"
66 | },
67 | "bufferViews": [
68 | {
69 | "buffer": 0,
70 | "byteLength": 559968,
71 | "name": "floatBufferViews",
72 | "target": 34963
73 | },
74 | {
75 | "buffer": 0,
76 | "byteLength": 192088,
77 | "byteOffset": 559968,
78 | "byteStride": 8,
79 | "name": "floatBufferViews",
80 | "target": 34962
81 | },
82 | {
83 | "buffer": 0,
84 | "byteLength": 576264,
85 | "byteOffset": 752056,
86 | "byteStride": 12,
87 | "name": "floatBufferViews",
88 | "target": 34962
89 | }
90 | ],
91 | "buffers": [
92 | {
93 | "byteLength": 1328320,
94 | "uri": "scene.bin"
95 | }
96 | ],
97 | "materials": [
98 | {
99 | "doubleSided": true,
100 | "name": "Scene_-_Root",
101 | "pbrMetallicRoughness": {
102 | "baseColorFactor": [
103 | 0.539777445607042,
104 | 0.539777445607042,
105 | 0.539777445607042,
106 | 1.0
107 | ],
108 | "metallicFactor": 0.0,
109 | "roughnessFactor": 0.6
110 | }
111 | }
112 | ],
113 | "meshes": [
114 | {
115 | "name": "David head by 1D_0",
116 | "primitives": [
117 | {
118 | "attributes": {
119 | "NORMAL": 1,
120 | "POSITION": 0,
121 | "TEXCOORD_0": 2
122 | },
123 | "indices": 3,
124 | "material": 0,
125 | "mode": 4
126 | }
127 | ]
128 | }
129 | ],
130 | "nodes": [
131 | {
132 | "children": [
133 | 1
134 | ],
135 | "matrix": [
136 | 1.0,
137 | 0.0,
138 | 0.0,
139 | 0.0,
140 | 0.0,
141 | 2.220446049250313e-16,
142 | -1.0,
143 | 0.0,
144 | 0.0,
145 | 1.0,
146 | 2.220446049250313e-16,
147 | 0.0,
148 | 0.0,
149 | 0.0,
150 | 0.0,
151 | 1.0
152 | ],
153 | "name": "Sketchfab_model"
154 | },
155 | {
156 | "children": [
157 | 2
158 | ],
159 | "name": "Root"
160 | },
161 | {
162 | "children": [
163 | 3
164 | ],
165 | "matrix": [
166 | 1.0,
167 | 0.0,
168 | 0.0,
169 | 0.0,
170 | 0.0,
171 | 1.0,
172 | 0.0,
173 | 0.0,
174 | 0.0,
175 | 0.0,
176 | 1.0,
177 | 0.0,
178 | -0.24123000000000003,
179 | -29.320980000000002,
180 | 97.60269,
181 | 1.0
182 | ],
183 | "name": "David head by 1D"
184 | },
185 | {
186 | "mesh": 0,
187 | "name": "David head by 1D_0"
188 | }
189 | ],
190 | "scene": 0,
191 | "scenes": [
192 | {
193 | "name": "Sketchfab_Scene",
194 | "nodes": [
195 | 0
196 | ]
197 | }
198 | ]
199 | }
200 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/canvas.ts:
--------------------------------------------------------------------------------
1 | import * as THREE from 'three'
2 | import { Dimensions } from './types/types'
3 | import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
4 | import GUI from 'lil-gui'
5 | import Model from './components/model'
6 |
7 | import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
8 | import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'
9 | import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'
10 | import AsciiEffect from './utils/ascii-effect'
11 |
12 | export default class Canvas {
13 | element: HTMLCanvasElement
14 | scene: THREE.Scene
15 | camera: THREE.PerspectiveCamera
16 | renderer: THREE.WebGLRenderer
17 | dimensions: Dimensions
18 | time: number
19 | clock: THREE.Clock
20 | orbitControls: OrbitControls
21 | debug: GUI
22 | model: Model
23 | composer: EffectComposer
24 | asciiPass: AsciiEffect
25 | directionalLight: THREE.DirectionalLight
26 |
27 | constructor() {
28 | this.element = document.getElementById('webgl') as HTMLCanvasElement
29 | this.time = 0
30 | this.createClock()
31 | this.createScene()
32 | this.createCamera()
33 | this.createRenderer()
34 | this.createOrbitControls()
35 | this.addEventListeners()
36 | this.createLight()
37 | this.createModel()
38 | this.createPostProcessing()
39 | this.createDebug()
40 | this.render()
41 | }
42 |
43 | createScene() {
44 | this.scene = new THREE.Scene()
45 | }
46 |
47 | createCamera() {
48 | this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
49 | this.scene.add(this.camera)
50 | this.camera.position.z = 6
51 | this.camera.position.x = -2
52 | this.camera.position.y = 1
53 | }
54 |
55 | createOrbitControls() {
56 | this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement)
57 | }
58 |
59 | createRenderer() {
60 | this.dimensions = {
61 | width: window.innerWidth,
62 | height: window.innerHeight,
63 | pixelRatio: Math.min(2, window.devicePixelRatio),
64 | }
65 |
66 | this.renderer = new THREE.WebGLRenderer({ canvas: this.element, alpha: true })
67 | this.renderer.setSize(this.dimensions.width, this.dimensions.height)
68 | this.renderer.render(this.scene, this.camera)
69 |
70 | this.renderer.setPixelRatio(this.dimensions.pixelRatio)
71 | }
72 |
73 | createPostProcessing() {
74 | this.composer = new EffectComposer(this.renderer)
75 | const renderPass = new RenderPass(this.scene, this.camera)
76 | this.composer.addPass(renderPass)
77 |
78 | this.asciiPass = new AsciiEffect()
79 | this.composer.addPass(this.asciiPass.asciiPass)
80 |
81 | const outputPass = new OutputPass()
82 | this.composer.addPass(outputPass)
83 | }
84 |
85 | createDebug() {
86 | this.debug = new GUI()
87 |
88 | const obj = {
89 | bool: true,
90 | }
91 |
92 | this.debug
93 | .add(obj, 'bool')
94 | .onChange((val: boolean) => {
95 | if (val) {
96 | this.asciiPass.asciiPass.material.uniforms.uShowAscii.value = 1
97 | } else {
98 | this.asciiPass.asciiPass.material.uniforms.uShowAscii.value = 0
99 | }
100 | })
101 | .listen()
102 | .name('ASCII')
103 |
104 | this.debug.add(this.directionalLight, 'intensity').min(1).max(10).step(0.1).name('Light intensity')
105 | }
106 |
107 | createClock() {
108 | this.clock = new THREE.Clock()
109 | }
110 |
111 | addEventListeners() {
112 | window.addEventListener('resize', this.onResize.bind(this))
113 | }
114 |
115 | onResize() {
116 | this.dimensions = {
117 | width: window.innerWidth,
118 | height: window.innerHeight,
119 | pixelRatio: Math.min(2, window.devicePixelRatio),
120 | }
121 |
122 | this.camera.aspect = window.innerWidth / window.innerHeight
123 | this.camera.updateProjectionMatrix()
124 |
125 | this.renderer.setPixelRatio(this.dimensions.pixelRatio)
126 | this.renderer.setSize(this.dimensions.width, this.dimensions.height)
127 | }
128 |
129 | createLight() {
130 | this.directionalLight = new THREE.DirectionalLight('white', 1)
131 | this.directionalLight.position.x = 10
132 | this.directionalLight.position.z = 10
133 | this.directionalLight.position.y = 5
134 |
135 | this.scene.add(this.directionalLight)
136 | }
137 |
138 | createModel() {
139 | this.model = new Model({ scene: this.scene })
140 | }
141 |
142 | render() {
143 | this.time = this.clock.getElapsedTime()
144 |
145 | this.orbitControls.update()
146 |
147 | this.model.render(this.time)
148 |
149 | //this.renderer.render(this.scene, this.camera)
150 | this.composer.render()
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/components/model.ts:
--------------------------------------------------------------------------------
1 | import * as THREE from 'three'
2 | import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
3 |
4 | interface Props {
5 | scene: THREE.Scene
6 | }
7 |
8 | export default class Model {
9 | loader: GLTFLoader
10 | scene: THREE.Scene
11 | model: null | THREE.Group
12 | //material: CustomShaderMaterial
13 | material: THREE.MeshStandardMaterial
14 |
15 | constructor({ scene }: Props) {
16 | this.scene = scene
17 | this.loader = new GLTFLoader()
18 | this.model = null
19 | this.createMaterial()
20 | this.loadModel()
21 | }
22 |
23 | createMaterial() {
24 | this.material = new THREE.MeshStandardMaterial({
25 | color: 'white',
26 | })
27 | }
28 |
29 | loadModel() {
30 | this.loader.load(
31 | // resource URL
32 | '/LeePerrySmith/LeePerrySmith.glb',
33 | //'/david_head/scene.gltf',
34 | (gltf) => {
35 | console.log(gltf)
36 | this.model = gltf.scene
37 | //this.model.scale.set(0.05, 0.05, 0.05)
38 | //this.model.position.y -= 5
39 | const mesh = this.model.children[0] as THREE.Mesh
40 | mesh.material = this.material
41 | this.scene.add(this.model)
42 | }
43 | )
44 | }
45 |
46 | render(time: number) {
47 | if (this.model) {
48 | //this.model.rotation.y = time * 0.3
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import './style.css'
2 | import Canvas from './canvas'
3 |
4 | class App {
5 | canvas: Canvas
6 |
7 | constructor() {
8 | this.canvas = new Canvas()
9 |
10 | this.render()
11 | }
12 |
13 | render() {
14 | this.canvas.render()
15 | requestAnimationFrame(this.render.bind(this))
16 | }
17 | }
18 |
19 | export default new App()
20 |
--------------------------------------------------------------------------------
/src/shaders/ascii/ascii.glsl:
--------------------------------------------------------------------------------
1 | uniform float opacity;
2 |
3 | uniform sampler2D tDiffuse;
4 | uniform vec2 uResolution;
5 | varying vec2 vUv;
6 | uniform sampler2D uTexture;
7 | uniform vec2 uTextureResolution;
8 | uniform float uShowAscii;
9 | uniform float uSize;
10 |
11 | float random (vec2 st) {
12 | return fract(sin(dot(st.xy,
13 | vec2(12.9898,78.233)))*
14 | 43758.5453123);
15 | }
16 |
17 | void main() {
18 |
19 | float size = uSize;
20 |
21 | float aspectY = max(uResolution.y/uResolution.x,1.);
22 | float aspectX = max(uResolution.x/uResolution.y,1.);
23 |
24 | vec2 sceneUvs = vec2(
25 | floor(vUv.x * size*aspectX)/(size*aspectX),
26 | floor(vUv.y * size*aspectY)/(size*aspectY)
27 | );
28 | vec2 newUv = vec2(
29 | mod(vUv.x * size*aspectX,1.),
30 | mod(vUv.y * size*aspectY,1.)
31 | );
32 |
33 |
34 | vec2 finalUvs = newUv;
35 |
36 |
37 | vec4 baseTexel = texture2D(tDiffuse,vUv);
38 | vec4 texel = texture2D( tDiffuse, sceneUvs );
39 |
40 | float textureAspect = uTextureResolution.y/uTextureResolution.x;
41 | finalUvs.x*=textureAspect;
42 |
43 | //float offset = floor(texel.r*(1./textureAspect));
44 | float offset = floor(clamp(texel.r,0.,1.)*((1./textureAspect)-1.));
45 |
46 | finalUvs.x+=offset*textureAspect;
47 | vec4 char = texture2D(uTexture,finalUvs);
48 |
49 |
50 |
51 | gl_FragColor = (1.-step(0.5,uShowAscii))*baseTexel + (step(0.5,uShowAscii))*char;
52 |
53 | }
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | html,
2 | body,
3 | div,
4 | span,
5 | applet,
6 | object,
7 | iframe,
8 | h1,
9 | h2,
10 | h3,
11 | h4,
12 | h5,
13 | h6,
14 | p,
15 | blockquote,
16 | pre,
17 | a,
18 | abbr,
19 | acronym,
20 | address,
21 | big,
22 | cite,
23 | code,
24 | del,
25 | dfn,
26 | em,
27 | img,
28 | ins,
29 | kbd,
30 | q,
31 | s,
32 | samp,
33 | small,
34 | strike,
35 | strong,
36 | sub,
37 | sup,
38 | tt,
39 | var,
40 | b,
41 | u,
42 | i,
43 | center,
44 | dl,
45 | dt,
46 | dd,
47 | ol,
48 | ul,
49 | li,
50 | fieldset,
51 | form,
52 | label,
53 | legend,
54 | table,
55 | caption,
56 | tbody,
57 | tfoot,
58 | thead,
59 | tr,
60 | th,
61 | td,
62 | article,
63 | aside,
64 | canvas,
65 | details,
66 | embed,
67 | figure,
68 | figcaption,
69 | footer,
70 | header,
71 | hgroup,
72 | menu,
73 | nav,
74 | output,
75 | ruby,
76 | section,
77 | summary,
78 | time,
79 | mark,
80 | audio,
81 | video {
82 | margin: 0;
83 | padding: 0;
84 | border: 0;
85 | font-size: 100%;
86 | font: inherit;
87 | vertical-align: baseline;
88 | }
89 | /* HTML5 display-role reset for older browsers */
90 | article,
91 | aside,
92 | details,
93 | figcaption,
94 | figure,
95 | footer,
96 | header,
97 | hgroup,
98 | menu,
99 | nav,
100 | section {
101 | display: block;
102 | }
103 | body {
104 | line-height: 1;
105 | }
106 | ol,
107 | ul {
108 | list-style: none;
109 | }
110 | blockquote,
111 | q {
112 | quotes: none;
113 | }
114 | blockquote:before,
115 | blockquote:after,
116 | q:before,
117 | q:after {
118 | content: '';
119 | content: none;
120 | }
121 | table {
122 | border-collapse: collapse;
123 | border-spacing: 0;
124 | }
125 |
126 | #webgl {
127 | position: fixed;
128 | inset: 0;
129 | top: 0;
130 | left: 0;
131 | background: rgb(30, 30, 30);
132 | }
133 |
--------------------------------------------------------------------------------
/src/types/types.ts:
--------------------------------------------------------------------------------
1 | export interface Size {
2 | width: number
3 | height: number
4 | }
5 |
6 | export interface Dimensions {
7 | width: number
8 | height: number
9 | pixelRatio: number
10 | }
11 |
12 | export interface Position {
13 | x: number
14 | y: number
15 | }
16 |
--------------------------------------------------------------------------------
/src/utils/ascii-effect.ts:
--------------------------------------------------------------------------------
1 | import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'
2 | import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
3 | import asciiFragment from '../../src/shaders/ascii/ascii.glsl'
4 | import * as THREE from 'three'
5 |
6 | export default class AsciiEffect {
7 | composer: EffectComposer
8 | asciiPass: ShaderPass
9 | shader: {
10 | name: string
11 | uniforms: { [name: string]: { value: any } }
12 | vertexShader: string
13 | fragmentShader: string
14 | }
15 | canvas: HTMLCanvasElement
16 | ctx: CanvasRenderingContext2D
17 | characters: string
18 |
19 | constructor() {
20 | //provide a power of 2 number of characters
21 | //8
22 | //16
23 | //32
24 | //64
25 |
26 | //this.characters = " .`-,:;'_~^=+<>i!lI?/|()1{}[]rcvuxzjftnLYJCVoZUwXhkmOa*#MW&8%B@$" //64
27 | this.characters = " .-:'~=