├── .gitignore ├── license.md ├── package-lock.json ├── package.json ├── public ├── basis │ ├── README.md │ ├── basis_transcoder.js │ └── basis_transcoder.wasm ├── draco │ ├── README.md │ ├── draco_decoder.js │ ├── draco_decoder.wasm │ ├── draco_encoder.js │ ├── draco_wasm_wrapper.js │ └── gltf │ │ ├── draco_decoder.js │ │ ├── draco_decoder.wasm │ │ ├── draco_encoder.js │ │ └── draco_wasm_wrapper.js └── textures │ ├── bricksColor.jpg │ ├── bricksNormal.jpg │ ├── bricksSpecular.jpg │ ├── ground2Color.jpg │ ├── ground2Normal.jpg │ ├── ground2Specular.jpg │ ├── groundColor.jpg │ ├── groundNormal.jpg │ ├── groundSpecular.jpg │ ├── leatherColor.jpg │ ├── leatherNormal.jpg │ ├── leatherSpecular.jpg │ ├── woodColor.jpg │ ├── woodNormal.jpg │ └── woodSpecular.jpg ├── readme.md ├── sources ├── Experience │ ├── Camera │ │ ├── Camera.js │ │ ├── DebugCamera.js │ │ └── DefaultCamera.js │ ├── Debug │ │ ├── Debug.js │ │ ├── DebugStats.js │ │ └── DebugUI.js │ ├── EventEmitter.js │ ├── Experience.js │ ├── Lights.js │ ├── Materials │ │ ├── BlurMaterial.js │ │ ├── CompositionMaterial.js │ │ ├── DefaultMaterial.js │ │ ├── FinalMaterial.js │ │ ├── GlowMaterial.js │ │ └── PointLightMaterial.js │ ├── Renderer.js │ ├── Resources.js │ ├── Time.js │ ├── Utils │ │ ├── Loader.js │ │ └── MathUtils.js │ ├── Viewport.js │ ├── World.js │ ├── assets.js │ └── shaders │ │ ├── blur │ │ ├── fragment.glsl │ │ └── vertex.glsl │ │ ├── composition │ │ ├── fragment.glsl │ │ └── vertex.glsl │ │ ├── default │ │ ├── fragment.glsl │ │ └── vertex.glsl │ │ ├── final │ │ ├── fragment.glsl │ │ └── vertex.glsl │ │ ├── glow │ │ ├── fragment.glsl │ │ └── vertex.glsl │ │ └── pointLight │ │ ├── fragment.glsl │ │ └── vertex.glsl ├── index.html ├── index.js └── style │ └── main.styl └── 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 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Bruno SIMON 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scout", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "scout", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "lil-gui": "^0.16.1", 12 | "stats.js": "^0.17.0", 13 | "stylus": "^0.58.1", 14 | "three": "^0.141.0", 15 | "vite": "^2.9.12", 16 | "vite-plugin-glsl": "^0.1.2" 17 | } 18 | }, 19 | "node_modules/@rollup/pluginutils": { 20 | "version": "4.1.2", 21 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.2.tgz", 22 | "integrity": "sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==", 23 | "dependencies": { 24 | "estree-walker": "^2.0.1", 25 | "picomatch": "^2.2.2" 26 | }, 27 | "engines": { 28 | "node": ">= 8.0.0" 29 | } 30 | }, 31 | "node_modules/atob": { 32 | "version": "2.1.2", 33 | "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", 34 | "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", 35 | "bin": { 36 | "atob": "bin/atob.js" 37 | }, 38 | "engines": { 39 | "node": ">= 4.5.0" 40 | } 41 | }, 42 | "node_modules/balanced-match": { 43 | "version": "1.0.2", 44 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 45 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 46 | }, 47 | "node_modules/brace-expansion": { 48 | "version": "1.1.11", 49 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 50 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 51 | "dependencies": { 52 | "balanced-match": "^1.0.0", 53 | "concat-map": "0.0.1" 54 | } 55 | }, 56 | "node_modules/concat-map": { 57 | "version": "0.0.1", 58 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 59 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 60 | }, 61 | "node_modules/css": { 62 | "version": "3.0.0", 63 | "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", 64 | "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", 65 | "dependencies": { 66 | "inherits": "^2.0.4", 67 | "source-map": "^0.6.1", 68 | "source-map-resolve": "^0.6.0" 69 | } 70 | }, 71 | "node_modules/css/node_modules/source-map": { 72 | "version": "0.6.1", 73 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 74 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 75 | "engines": { 76 | "node": ">=0.10.0" 77 | } 78 | }, 79 | "node_modules/debug": { 80 | "version": "4.3.3", 81 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 82 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 83 | "dependencies": { 84 | "ms": "2.1.2" 85 | }, 86 | "engines": { 87 | "node": ">=6.0" 88 | }, 89 | "peerDependenciesMeta": { 90 | "supports-color": { 91 | "optional": true 92 | } 93 | } 94 | }, 95 | "node_modules/decode-uri-component": { 96 | "version": "0.2.0", 97 | "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", 98 | "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", 99 | "engines": { 100 | "node": ">=0.10" 101 | } 102 | }, 103 | "node_modules/esbuild": { 104 | "version": "0.14.43", 105 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.43.tgz", 106 | "integrity": "sha512-Uf94+kQmy/5jsFwKWiQB4hfo/RkM9Dh7b79p8yqd1tshULdr25G2szLz631NoH3s2ujnKEKVD16RmOxvCNKRFA==", 107 | "hasInstallScript": true, 108 | "bin": { 109 | "esbuild": "bin/esbuild" 110 | }, 111 | "engines": { 112 | "node": ">=12" 113 | }, 114 | "optionalDependencies": { 115 | "esbuild-android-64": "0.14.43", 116 | "esbuild-android-arm64": "0.14.43", 117 | "esbuild-darwin-64": "0.14.43", 118 | "esbuild-darwin-arm64": "0.14.43", 119 | "esbuild-freebsd-64": "0.14.43", 120 | "esbuild-freebsd-arm64": "0.14.43", 121 | "esbuild-linux-32": "0.14.43", 122 | "esbuild-linux-64": "0.14.43", 123 | "esbuild-linux-arm": "0.14.43", 124 | "esbuild-linux-arm64": "0.14.43", 125 | "esbuild-linux-mips64le": "0.14.43", 126 | "esbuild-linux-ppc64le": "0.14.43", 127 | "esbuild-linux-riscv64": "0.14.43", 128 | "esbuild-linux-s390x": "0.14.43", 129 | "esbuild-netbsd-64": "0.14.43", 130 | "esbuild-openbsd-64": "0.14.43", 131 | "esbuild-sunos-64": "0.14.43", 132 | "esbuild-windows-32": "0.14.43", 133 | "esbuild-windows-64": "0.14.43", 134 | "esbuild-windows-arm64": "0.14.43" 135 | } 136 | }, 137 | "node_modules/esbuild-android-64": { 138 | "version": "0.14.43", 139 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.43.tgz", 140 | "integrity": "sha512-kqFXAS72K6cNrB6RiM7YJ5lNvmWRDSlpi7ZuRZ1hu1S3w0zlwcoCxWAyM23LQUyZSs1PbjHgdbbfYAN8IGh6xg==", 141 | "cpu": [ 142 | "x64" 143 | ], 144 | "optional": true, 145 | "os": [ 146 | "android" 147 | ], 148 | "engines": { 149 | "node": ">=12" 150 | } 151 | }, 152 | "node_modules/esbuild-android-arm64": { 153 | "version": "0.14.43", 154 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.43.tgz", 155 | "integrity": "sha512-bKS2BBFh+7XZY9rpjiHGRNA7LvWYbZWP87pLehggTG7tTaCDvj8qQGOU/OZSjCSKDYbgY7Q+oDw8RlYQ2Jt2BA==", 156 | "cpu": [ 157 | "arm64" 158 | ], 159 | "optional": true, 160 | "os": [ 161 | "android" 162 | ], 163 | "engines": { 164 | "node": ">=12" 165 | } 166 | }, 167 | "node_modules/esbuild-darwin-64": { 168 | "version": "0.14.43", 169 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.43.tgz", 170 | "integrity": "sha512-/3PSilx011ttoieRGkSZ0XV8zjBf2C9enV4ScMMbCT4dpx0mFhMOpFnCHkOK0pWGB8LklykFyHrWk2z6DENVUg==", 171 | "cpu": [ 172 | "x64" 173 | ], 174 | "optional": true, 175 | "os": [ 176 | "darwin" 177 | ], 178 | "engines": { 179 | "node": ">=12" 180 | } 181 | }, 182 | "node_modules/esbuild-darwin-arm64": { 183 | "version": "0.14.43", 184 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.43.tgz", 185 | "integrity": "sha512-1HyFUKs8DMCBOvw1Qxpr5Vv/ThNcVIFb5xgXWK3pyT40WPvgYIiRTwJCvNs4l8i5qWF8/CK5bQxJVDjQvtv0Yw==", 186 | "cpu": [ 187 | "arm64" 188 | ], 189 | "optional": true, 190 | "os": [ 191 | "darwin" 192 | ], 193 | "engines": { 194 | "node": ">=12" 195 | } 196 | }, 197 | "node_modules/esbuild-freebsd-64": { 198 | "version": "0.14.43", 199 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.43.tgz", 200 | "integrity": "sha512-FNWc05TPHYgaXjbPZO5/rJKSBslfG6BeMSs8GhwnqAKP56eEhvmzwnIz1QcC9cRVyO+IKqWNfmHFkCa1WJTULA==", 201 | "cpu": [ 202 | "x64" 203 | ], 204 | "optional": true, 205 | "os": [ 206 | "freebsd" 207 | ], 208 | "engines": { 209 | "node": ">=12" 210 | } 211 | }, 212 | "node_modules/esbuild-freebsd-arm64": { 213 | "version": "0.14.43", 214 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.43.tgz", 215 | "integrity": "sha512-amrYopclz3VohqisOPR6hA3GOWA3LZC1WDLnp21RhNmoERmJ/vLnOpnrG2P/Zao+/erKTCUqmrCIPVtj58DRoA==", 216 | "cpu": [ 217 | "arm64" 218 | ], 219 | "optional": true, 220 | "os": [ 221 | "freebsd" 222 | ], 223 | "engines": { 224 | "node": ">=12" 225 | } 226 | }, 227 | "node_modules/esbuild-linux-32": { 228 | "version": "0.14.43", 229 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.43.tgz", 230 | "integrity": "sha512-KoxoEra+9O3AKVvgDFvDkiuddCds6q71owSQEYwjtqRV7RwbPzKxJa6+uyzUulHcyGVq0g15K0oKG5CFBcvYDw==", 231 | "cpu": [ 232 | "ia32" 233 | ], 234 | "optional": true, 235 | "os": [ 236 | "linux" 237 | ], 238 | "engines": { 239 | "node": ">=12" 240 | } 241 | }, 242 | "node_modules/esbuild-linux-64": { 243 | "version": "0.14.43", 244 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.43.tgz", 245 | "integrity": "sha512-EwINwGMyiJMgBby5/SbMqKcUhS5AYAZ2CpEBzSowsJPNBJEdhkCTtEjk757TN/wxgbu3QklqDM6KghY660QCUw==", 246 | "cpu": [ 247 | "x64" 248 | ], 249 | "optional": true, 250 | "os": [ 251 | "linux" 252 | ], 253 | "engines": { 254 | "node": ">=12" 255 | } 256 | }, 257 | "node_modules/esbuild-linux-arm": { 258 | "version": "0.14.43", 259 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.43.tgz", 260 | "integrity": "sha512-e6YzQUoDxxtyamuF12eVzzRC7bbEFSZohJ6igQB9tBqnNmIQY3fI6Cns3z2wxtbZ3f2o6idkD2fQnlvs2902Dg==", 261 | "cpu": [ 262 | "arm" 263 | ], 264 | "optional": true, 265 | "os": [ 266 | "linux" 267 | ], 268 | "engines": { 269 | "node": ">=12" 270 | } 271 | }, 272 | "node_modules/esbuild-linux-arm64": { 273 | "version": "0.14.43", 274 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.43.tgz", 275 | "integrity": "sha512-UlSpjMWllAc70zYbHxWuDS3FJytyuR/gHJYBr8BICcTNb/TSOYVBg6U7b3jZ3mILTrgzwJUHwhEwK18FZDouUQ==", 276 | "cpu": [ 277 | "arm64" 278 | ], 279 | "optional": true, 280 | "os": [ 281 | "linux" 282 | ], 283 | "engines": { 284 | "node": ">=12" 285 | } 286 | }, 287 | "node_modules/esbuild-linux-mips64le": { 288 | "version": "0.14.43", 289 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.43.tgz", 290 | "integrity": "sha512-f+v8cInPEL1/SDP//CfSYzcDNgE4CY3xgDV81DWm3KAPWzhvxARrKxB1Pstf5mB56yAslJDxu7ryBUPX207EZA==", 291 | "cpu": [ 292 | "mips64el" 293 | ], 294 | "optional": true, 295 | "os": [ 296 | "linux" 297 | ], 298 | "engines": { 299 | "node": ">=12" 300 | } 301 | }, 302 | "node_modules/esbuild-linux-ppc64le": { 303 | "version": "0.14.43", 304 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.43.tgz", 305 | "integrity": "sha512-5wZYMDGAL/K2pqkdIsW+I4IR41kyfHr/QshJcNpUfK3RjB3VQcPWOaZmc+74rm4ZjVirYrtz+jWw0SgxtxRanA==", 306 | "cpu": [ 307 | "ppc64" 308 | ], 309 | "optional": true, 310 | "os": [ 311 | "linux" 312 | ], 313 | "engines": { 314 | "node": ">=12" 315 | } 316 | }, 317 | "node_modules/esbuild-linux-riscv64": { 318 | "version": "0.14.43", 319 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.43.tgz", 320 | "integrity": "sha512-lYcAOUxp85hC7lSjycJUVSmj4/9oEfSyXjb/ua9bNl8afonaduuqtw7hvKMoKuYnVwOCDw4RSfKpcnIRDWq+Bw==", 321 | "cpu": [ 322 | "riscv64" 323 | ], 324 | "optional": true, 325 | "os": [ 326 | "linux" 327 | ], 328 | "engines": { 329 | "node": ">=12" 330 | } 331 | }, 332 | "node_modules/esbuild-linux-s390x": { 333 | "version": "0.14.43", 334 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.43.tgz", 335 | "integrity": "sha512-27e43ZhHvhFE4nM7HqtUbMRu37I/4eNSUbb8FGZWszV+uLzMIsHDwLoBiJmw7G9N+hrehNPeQ4F5Ujad0DrUKQ==", 336 | "cpu": [ 337 | "s390x" 338 | ], 339 | "optional": true, 340 | "os": [ 341 | "linux" 342 | ], 343 | "engines": { 344 | "node": ">=12" 345 | } 346 | }, 347 | "node_modules/esbuild-netbsd-64": { 348 | "version": "0.14.43", 349 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.43.tgz", 350 | "integrity": "sha512-2mH4QF6hHBn5zzAfxEI/2eBC0mspVsZ6UVo821LpAJKMvLJPBk3XJO5xwg7paDqSqpl7p6IRrAenW999AEfJhQ==", 351 | "cpu": [ 352 | "x64" 353 | ], 354 | "optional": true, 355 | "os": [ 356 | "netbsd" 357 | ], 358 | "engines": { 359 | "node": ">=12" 360 | } 361 | }, 362 | "node_modules/esbuild-openbsd-64": { 363 | "version": "0.14.43", 364 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.43.tgz", 365 | "integrity": "sha512-ZhQpiZjvqCqO8jKdGp9+8k9E/EHSA+zIWOg+grwZasI9RoblqJ1QiZqqi7jfd6ZrrG1UFBNGe4m0NFxCFbMVbg==", 366 | "cpu": [ 367 | "x64" 368 | ], 369 | "optional": true, 370 | "os": [ 371 | "openbsd" 372 | ], 373 | "engines": { 374 | "node": ">=12" 375 | } 376 | }, 377 | "node_modules/esbuild-sunos-64": { 378 | "version": "0.14.43", 379 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.43.tgz", 380 | "integrity": "sha512-DgxSi9DaHReL9gYuul2rrQCAapgnCJkh3LSHPKsY26zytYppG0HgkgVF80zjIlvEsUbGBP/GHQzBtrezj/Zq1Q==", 381 | "cpu": [ 382 | "x64" 383 | ], 384 | "optional": true, 385 | "os": [ 386 | "sunos" 387 | ], 388 | "engines": { 389 | "node": ">=12" 390 | } 391 | }, 392 | "node_modules/esbuild-windows-32": { 393 | "version": "0.14.43", 394 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.43.tgz", 395 | "integrity": "sha512-Ih3+2O5oExiqm0mY6YYE5dR0o8+AspccQ3vIAtRodwFvhuyGLjb0Hbmzun/F3Lw19nuhPMu3sW2fqIJ5xBxByw==", 396 | "cpu": [ 397 | "ia32" 398 | ], 399 | "optional": true, 400 | "os": [ 401 | "win32" 402 | ], 403 | "engines": { 404 | "node": ">=12" 405 | } 406 | }, 407 | "node_modules/esbuild-windows-64": { 408 | "version": "0.14.43", 409 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.43.tgz", 410 | "integrity": "sha512-8NsuNfI8xwFuJbrCuI+aBqNTYkrWErejFO5aYM+yHqyHuL8mmepLS9EPzAzk8rvfaJrhN0+RvKWAcymViHOKEw==", 411 | "cpu": [ 412 | "x64" 413 | ], 414 | "optional": true, 415 | "os": [ 416 | "win32" 417 | ], 418 | "engines": { 419 | "node": ">=12" 420 | } 421 | }, 422 | "node_modules/esbuild-windows-arm64": { 423 | "version": "0.14.43", 424 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.43.tgz", 425 | "integrity": "sha512-7ZlD7bo++kVRblJEoG+cepljkfP8bfuTPz5fIXzptwnPaFwGS6ahvfoYzY7WCf5v/1nX2X02HDraVItTgbHnKw==", 426 | "cpu": [ 427 | "arm64" 428 | ], 429 | "optional": true, 430 | "os": [ 431 | "win32" 432 | ], 433 | "engines": { 434 | "node": ">=12" 435 | } 436 | }, 437 | "node_modules/estree-walker": { 438 | "version": "2.0.2", 439 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 440 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" 441 | }, 442 | "node_modules/fs.realpath": { 443 | "version": "1.0.0", 444 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 445 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 446 | }, 447 | "node_modules/fsevents": { 448 | "version": "2.3.2", 449 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 450 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 451 | "hasInstallScript": true, 452 | "optional": true, 453 | "os": [ 454 | "darwin" 455 | ], 456 | "engines": { 457 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 458 | } 459 | }, 460 | "node_modules/function-bind": { 461 | "version": "1.1.1", 462 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 463 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 464 | }, 465 | "node_modules/glob": { 466 | "version": "7.2.0", 467 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 468 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 469 | "dependencies": { 470 | "fs.realpath": "^1.0.0", 471 | "inflight": "^1.0.4", 472 | "inherits": "2", 473 | "minimatch": "^3.0.4", 474 | "once": "^1.3.0", 475 | "path-is-absolute": "^1.0.0" 476 | }, 477 | "engines": { 478 | "node": "*" 479 | }, 480 | "funding": { 481 | "url": "https://github.com/sponsors/isaacs" 482 | } 483 | }, 484 | "node_modules/has": { 485 | "version": "1.0.3", 486 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 487 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 488 | "dependencies": { 489 | "function-bind": "^1.1.1" 490 | }, 491 | "engines": { 492 | "node": ">= 0.4.0" 493 | } 494 | }, 495 | "node_modules/inflight": { 496 | "version": "1.0.6", 497 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 498 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 499 | "dependencies": { 500 | "once": "^1.3.0", 501 | "wrappy": "1" 502 | } 503 | }, 504 | "node_modules/inherits": { 505 | "version": "2.0.4", 506 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 507 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 508 | }, 509 | "node_modules/is-core-module": { 510 | "version": "2.8.1", 511 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", 512 | "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", 513 | "dependencies": { 514 | "has": "^1.0.3" 515 | }, 516 | "funding": { 517 | "url": "https://github.com/sponsors/ljharb" 518 | } 519 | }, 520 | "node_modules/lil-gui": { 521 | "version": "0.16.1", 522 | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.16.1.tgz", 523 | "integrity": "sha512-6wnnfBvQxJYRhdLyIA+w5b8utwbuVxNmtpTXElm36OSgHa8lyKp00Xz/4AEx3kvodT0AJYgbfadCFWAM0Q8DgQ==" 524 | }, 525 | "node_modules/minimatch": { 526 | "version": "3.1.2", 527 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 528 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 529 | "dependencies": { 530 | "brace-expansion": "^1.1.7" 531 | }, 532 | "engines": { 533 | "node": "*" 534 | } 535 | }, 536 | "node_modules/ms": { 537 | "version": "2.1.2", 538 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 539 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 540 | }, 541 | "node_modules/nanoid": { 542 | "version": "3.3.4", 543 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", 544 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", 545 | "bin": { 546 | "nanoid": "bin/nanoid.cjs" 547 | }, 548 | "engines": { 549 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 550 | } 551 | }, 552 | "node_modules/once": { 553 | "version": "1.4.0", 554 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 555 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 556 | "dependencies": { 557 | "wrappy": "1" 558 | } 559 | }, 560 | "node_modules/path-is-absolute": { 561 | "version": "1.0.1", 562 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 563 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 564 | "engines": { 565 | "node": ">=0.10.0" 566 | } 567 | }, 568 | "node_modules/path-parse": { 569 | "version": "1.0.7", 570 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 571 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" 572 | }, 573 | "node_modules/picocolors": { 574 | "version": "1.0.0", 575 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 576 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" 577 | }, 578 | "node_modules/picomatch": { 579 | "version": "2.3.1", 580 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 581 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 582 | "engines": { 583 | "node": ">=8.6" 584 | }, 585 | "funding": { 586 | "url": "https://github.com/sponsors/jonschlinkert" 587 | } 588 | }, 589 | "node_modules/postcss": { 590 | "version": "8.4.14", 591 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", 592 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", 593 | "funding": [ 594 | { 595 | "type": "opencollective", 596 | "url": "https://opencollective.com/postcss/" 597 | }, 598 | { 599 | "type": "tidelift", 600 | "url": "https://tidelift.com/funding/github/npm/postcss" 601 | } 602 | ], 603 | "dependencies": { 604 | "nanoid": "^3.3.4", 605 | "picocolors": "^1.0.0", 606 | "source-map-js": "^1.0.2" 607 | }, 608 | "engines": { 609 | "node": "^10 || ^12 || >=14" 610 | } 611 | }, 612 | "node_modules/resolve": { 613 | "version": "1.22.0", 614 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", 615 | "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", 616 | "dependencies": { 617 | "is-core-module": "^2.8.1", 618 | "path-parse": "^1.0.7", 619 | "supports-preserve-symlinks-flag": "^1.0.0" 620 | }, 621 | "bin": { 622 | "resolve": "bin/resolve" 623 | }, 624 | "funding": { 625 | "url": "https://github.com/sponsors/ljharb" 626 | } 627 | }, 628 | "node_modules/rollup": { 629 | "version": "2.68.0", 630 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.68.0.tgz", 631 | "integrity": "sha512-XrMKOYK7oQcTio4wyTz466mucnd8LzkiZLozZ4Rz0zQD+HeX4nUK4B8GrTX/2EvN2/vBF/i2WnaXboPxo0JylA==", 632 | "bin": { 633 | "rollup": "dist/bin/rollup" 634 | }, 635 | "engines": { 636 | "node": ">=10.0.0" 637 | }, 638 | "optionalDependencies": { 639 | "fsevents": "~2.3.2" 640 | } 641 | }, 642 | "node_modules/sax": { 643 | "version": "1.2.4", 644 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 645 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 646 | }, 647 | "node_modules/source-map": { 648 | "version": "0.7.3", 649 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", 650 | "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", 651 | "engines": { 652 | "node": ">= 8" 653 | } 654 | }, 655 | "node_modules/source-map-js": { 656 | "version": "1.0.2", 657 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 658 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 659 | "engines": { 660 | "node": ">=0.10.0" 661 | } 662 | }, 663 | "node_modules/source-map-resolve": { 664 | "version": "0.6.0", 665 | "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", 666 | "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", 667 | "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", 668 | "dependencies": { 669 | "atob": "^2.1.2", 670 | "decode-uri-component": "^0.2.0" 671 | } 672 | }, 673 | "node_modules/stats.js": { 674 | "version": "0.17.0", 675 | "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", 676 | "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" 677 | }, 678 | "node_modules/stylus": { 679 | "version": "0.58.1", 680 | "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.58.1.tgz", 681 | "integrity": "sha512-AYiCHm5ogczdCPMfe9aeQa4NklB2gcf4D/IhzYPddJjTgPc+k4D/EVE0yfQbZD43MHP3lPy+8NZ9fcFxkrgs/w==", 682 | "dependencies": { 683 | "css": "^3.0.0", 684 | "debug": "^4.3.2", 685 | "glob": "^7.1.6", 686 | "sax": "~1.2.4", 687 | "source-map": "^0.7.3" 688 | }, 689 | "bin": { 690 | "stylus": "bin/stylus" 691 | }, 692 | "engines": { 693 | "node": "*" 694 | } 695 | }, 696 | "node_modules/supports-preserve-symlinks-flag": { 697 | "version": "1.0.0", 698 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 699 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 700 | "engines": { 701 | "node": ">= 0.4" 702 | }, 703 | "funding": { 704 | "url": "https://github.com/sponsors/ljharb" 705 | } 706 | }, 707 | "node_modules/three": { 708 | "version": "0.141.0", 709 | "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz", 710 | "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==" 711 | }, 712 | "node_modules/tslib": { 713 | "version": "2.3.1", 714 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", 715 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 716 | }, 717 | "node_modules/vite": { 718 | "version": "2.9.12", 719 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz", 720 | "integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==", 721 | "dependencies": { 722 | "esbuild": "^0.14.27", 723 | "postcss": "^8.4.13", 724 | "resolve": "^1.22.0", 725 | "rollup": "^2.59.0" 726 | }, 727 | "bin": { 728 | "vite": "bin/vite.js" 729 | }, 730 | "engines": { 731 | "node": ">=12.2.0" 732 | }, 733 | "optionalDependencies": { 734 | "fsevents": "~2.3.2" 735 | }, 736 | "peerDependencies": { 737 | "less": "*", 738 | "sass": "*", 739 | "stylus": "*" 740 | }, 741 | "peerDependenciesMeta": { 742 | "less": { 743 | "optional": true 744 | }, 745 | "sass": { 746 | "optional": true 747 | }, 748 | "stylus": { 749 | "optional": true 750 | } 751 | } 752 | }, 753 | "node_modules/vite-plugin-glsl": { 754 | "version": "0.1.2", 755 | "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-0.1.2.tgz", 756 | "integrity": "sha512-RFwoYn8EQFXp4YygIyt8Ex3bQE5/v5927AF0MAgrNfX4NRPlDAX12ciWlpVs4ObKLYro49fctnou4+fajO0FOg==", 757 | "dependencies": { 758 | "@rollup/pluginutils": "^4.1.2", 759 | "tslib": "^2.3.1" 760 | }, 761 | "engines": { 762 | "node": ">= 14.17.0", 763 | "npm": ">= 6.14.13" 764 | } 765 | }, 766 | "node_modules/wrappy": { 767 | "version": "1.0.2", 768 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 769 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 770 | } 771 | }, 772 | "dependencies": { 773 | "@rollup/pluginutils": { 774 | "version": "4.1.2", 775 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.1.2.tgz", 776 | "integrity": "sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==", 777 | "requires": { 778 | "estree-walker": "^2.0.1", 779 | "picomatch": "^2.2.2" 780 | } 781 | }, 782 | "atob": { 783 | "version": "2.1.2", 784 | "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", 785 | "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" 786 | }, 787 | "balanced-match": { 788 | "version": "1.0.2", 789 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 790 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 791 | }, 792 | "brace-expansion": { 793 | "version": "1.1.11", 794 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 795 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 796 | "requires": { 797 | "balanced-match": "^1.0.0", 798 | "concat-map": "0.0.1" 799 | } 800 | }, 801 | "concat-map": { 802 | "version": "0.0.1", 803 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 804 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 805 | }, 806 | "css": { 807 | "version": "3.0.0", 808 | "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", 809 | "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", 810 | "requires": { 811 | "inherits": "^2.0.4", 812 | "source-map": "^0.6.1", 813 | "source-map-resolve": "^0.6.0" 814 | }, 815 | "dependencies": { 816 | "source-map": { 817 | "version": "0.6.1", 818 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 819 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 820 | } 821 | } 822 | }, 823 | "debug": { 824 | "version": "4.3.3", 825 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 826 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 827 | "requires": { 828 | "ms": "2.1.2" 829 | } 830 | }, 831 | "decode-uri-component": { 832 | "version": "0.2.0", 833 | "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", 834 | "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" 835 | }, 836 | "esbuild": { 837 | "version": "0.14.43", 838 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.43.tgz", 839 | "integrity": "sha512-Uf94+kQmy/5jsFwKWiQB4hfo/RkM9Dh7b79p8yqd1tshULdr25G2szLz631NoH3s2ujnKEKVD16RmOxvCNKRFA==", 840 | "requires": { 841 | "esbuild-android-64": "0.14.43", 842 | "esbuild-android-arm64": "0.14.43", 843 | "esbuild-darwin-64": "0.14.43", 844 | "esbuild-darwin-arm64": "0.14.43", 845 | "esbuild-freebsd-64": "0.14.43", 846 | "esbuild-freebsd-arm64": "0.14.43", 847 | "esbuild-linux-32": "0.14.43", 848 | "esbuild-linux-64": "0.14.43", 849 | "esbuild-linux-arm": "0.14.43", 850 | "esbuild-linux-arm64": "0.14.43", 851 | "esbuild-linux-mips64le": "0.14.43", 852 | "esbuild-linux-ppc64le": "0.14.43", 853 | "esbuild-linux-riscv64": "0.14.43", 854 | "esbuild-linux-s390x": "0.14.43", 855 | "esbuild-netbsd-64": "0.14.43", 856 | "esbuild-openbsd-64": "0.14.43", 857 | "esbuild-sunos-64": "0.14.43", 858 | "esbuild-windows-32": "0.14.43", 859 | "esbuild-windows-64": "0.14.43", 860 | "esbuild-windows-arm64": "0.14.43" 861 | } 862 | }, 863 | "esbuild-android-64": { 864 | "version": "0.14.43", 865 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.43.tgz", 866 | "integrity": "sha512-kqFXAS72K6cNrB6RiM7YJ5lNvmWRDSlpi7ZuRZ1hu1S3w0zlwcoCxWAyM23LQUyZSs1PbjHgdbbfYAN8IGh6xg==", 867 | "optional": true 868 | }, 869 | "esbuild-android-arm64": { 870 | "version": "0.14.43", 871 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.43.tgz", 872 | "integrity": "sha512-bKS2BBFh+7XZY9rpjiHGRNA7LvWYbZWP87pLehggTG7tTaCDvj8qQGOU/OZSjCSKDYbgY7Q+oDw8RlYQ2Jt2BA==", 873 | "optional": true 874 | }, 875 | "esbuild-darwin-64": { 876 | "version": "0.14.43", 877 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.43.tgz", 878 | "integrity": "sha512-/3PSilx011ttoieRGkSZ0XV8zjBf2C9enV4ScMMbCT4dpx0mFhMOpFnCHkOK0pWGB8LklykFyHrWk2z6DENVUg==", 879 | "optional": true 880 | }, 881 | "esbuild-darwin-arm64": { 882 | "version": "0.14.43", 883 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.43.tgz", 884 | "integrity": "sha512-1HyFUKs8DMCBOvw1Qxpr5Vv/ThNcVIFb5xgXWK3pyT40WPvgYIiRTwJCvNs4l8i5qWF8/CK5bQxJVDjQvtv0Yw==", 885 | "optional": true 886 | }, 887 | "esbuild-freebsd-64": { 888 | "version": "0.14.43", 889 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.43.tgz", 890 | "integrity": "sha512-FNWc05TPHYgaXjbPZO5/rJKSBslfG6BeMSs8GhwnqAKP56eEhvmzwnIz1QcC9cRVyO+IKqWNfmHFkCa1WJTULA==", 891 | "optional": true 892 | }, 893 | "esbuild-freebsd-arm64": { 894 | "version": "0.14.43", 895 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.43.tgz", 896 | "integrity": "sha512-amrYopclz3VohqisOPR6hA3GOWA3LZC1WDLnp21RhNmoERmJ/vLnOpnrG2P/Zao+/erKTCUqmrCIPVtj58DRoA==", 897 | "optional": true 898 | }, 899 | "esbuild-linux-32": { 900 | "version": "0.14.43", 901 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.43.tgz", 902 | "integrity": "sha512-KoxoEra+9O3AKVvgDFvDkiuddCds6q71owSQEYwjtqRV7RwbPzKxJa6+uyzUulHcyGVq0g15K0oKG5CFBcvYDw==", 903 | "optional": true 904 | }, 905 | "esbuild-linux-64": { 906 | "version": "0.14.43", 907 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.43.tgz", 908 | "integrity": "sha512-EwINwGMyiJMgBby5/SbMqKcUhS5AYAZ2CpEBzSowsJPNBJEdhkCTtEjk757TN/wxgbu3QklqDM6KghY660QCUw==", 909 | "optional": true 910 | }, 911 | "esbuild-linux-arm": { 912 | "version": "0.14.43", 913 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.43.tgz", 914 | "integrity": "sha512-e6YzQUoDxxtyamuF12eVzzRC7bbEFSZohJ6igQB9tBqnNmIQY3fI6Cns3z2wxtbZ3f2o6idkD2fQnlvs2902Dg==", 915 | "optional": true 916 | }, 917 | "esbuild-linux-arm64": { 918 | "version": "0.14.43", 919 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.43.tgz", 920 | "integrity": "sha512-UlSpjMWllAc70zYbHxWuDS3FJytyuR/gHJYBr8BICcTNb/TSOYVBg6U7b3jZ3mILTrgzwJUHwhEwK18FZDouUQ==", 921 | "optional": true 922 | }, 923 | "esbuild-linux-mips64le": { 924 | "version": "0.14.43", 925 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.43.tgz", 926 | "integrity": "sha512-f+v8cInPEL1/SDP//CfSYzcDNgE4CY3xgDV81DWm3KAPWzhvxARrKxB1Pstf5mB56yAslJDxu7ryBUPX207EZA==", 927 | "optional": true 928 | }, 929 | "esbuild-linux-ppc64le": { 930 | "version": "0.14.43", 931 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.43.tgz", 932 | "integrity": "sha512-5wZYMDGAL/K2pqkdIsW+I4IR41kyfHr/QshJcNpUfK3RjB3VQcPWOaZmc+74rm4ZjVirYrtz+jWw0SgxtxRanA==", 933 | "optional": true 934 | }, 935 | "esbuild-linux-riscv64": { 936 | "version": "0.14.43", 937 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.43.tgz", 938 | "integrity": "sha512-lYcAOUxp85hC7lSjycJUVSmj4/9oEfSyXjb/ua9bNl8afonaduuqtw7hvKMoKuYnVwOCDw4RSfKpcnIRDWq+Bw==", 939 | "optional": true 940 | }, 941 | "esbuild-linux-s390x": { 942 | "version": "0.14.43", 943 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.43.tgz", 944 | "integrity": "sha512-27e43ZhHvhFE4nM7HqtUbMRu37I/4eNSUbb8FGZWszV+uLzMIsHDwLoBiJmw7G9N+hrehNPeQ4F5Ujad0DrUKQ==", 945 | "optional": true 946 | }, 947 | "esbuild-netbsd-64": { 948 | "version": "0.14.43", 949 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.43.tgz", 950 | "integrity": "sha512-2mH4QF6hHBn5zzAfxEI/2eBC0mspVsZ6UVo821LpAJKMvLJPBk3XJO5xwg7paDqSqpl7p6IRrAenW999AEfJhQ==", 951 | "optional": true 952 | }, 953 | "esbuild-openbsd-64": { 954 | "version": "0.14.43", 955 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.43.tgz", 956 | "integrity": "sha512-ZhQpiZjvqCqO8jKdGp9+8k9E/EHSA+zIWOg+grwZasI9RoblqJ1QiZqqi7jfd6ZrrG1UFBNGe4m0NFxCFbMVbg==", 957 | "optional": true 958 | }, 959 | "esbuild-sunos-64": { 960 | "version": "0.14.43", 961 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.43.tgz", 962 | "integrity": "sha512-DgxSi9DaHReL9gYuul2rrQCAapgnCJkh3LSHPKsY26zytYppG0HgkgVF80zjIlvEsUbGBP/GHQzBtrezj/Zq1Q==", 963 | "optional": true 964 | }, 965 | "esbuild-windows-32": { 966 | "version": "0.14.43", 967 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.43.tgz", 968 | "integrity": "sha512-Ih3+2O5oExiqm0mY6YYE5dR0o8+AspccQ3vIAtRodwFvhuyGLjb0Hbmzun/F3Lw19nuhPMu3sW2fqIJ5xBxByw==", 969 | "optional": true 970 | }, 971 | "esbuild-windows-64": { 972 | "version": "0.14.43", 973 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.43.tgz", 974 | "integrity": "sha512-8NsuNfI8xwFuJbrCuI+aBqNTYkrWErejFO5aYM+yHqyHuL8mmepLS9EPzAzk8rvfaJrhN0+RvKWAcymViHOKEw==", 975 | "optional": true 976 | }, 977 | "esbuild-windows-arm64": { 978 | "version": "0.14.43", 979 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.43.tgz", 980 | "integrity": "sha512-7ZlD7bo++kVRblJEoG+cepljkfP8bfuTPz5fIXzptwnPaFwGS6ahvfoYzY7WCf5v/1nX2X02HDraVItTgbHnKw==", 981 | "optional": true 982 | }, 983 | "estree-walker": { 984 | "version": "2.0.2", 985 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 986 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" 987 | }, 988 | "fs.realpath": { 989 | "version": "1.0.0", 990 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 991 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 992 | }, 993 | "fsevents": { 994 | "version": "2.3.2", 995 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 996 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 997 | "optional": true 998 | }, 999 | "function-bind": { 1000 | "version": "1.1.1", 1001 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1002 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 1003 | }, 1004 | "glob": { 1005 | "version": "7.2.0", 1006 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 1007 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 1008 | "requires": { 1009 | "fs.realpath": "^1.0.0", 1010 | "inflight": "^1.0.4", 1011 | "inherits": "2", 1012 | "minimatch": "^3.0.4", 1013 | "once": "^1.3.0", 1014 | "path-is-absolute": "^1.0.0" 1015 | } 1016 | }, 1017 | "has": { 1018 | "version": "1.0.3", 1019 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1020 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1021 | "requires": { 1022 | "function-bind": "^1.1.1" 1023 | } 1024 | }, 1025 | "inflight": { 1026 | "version": "1.0.6", 1027 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1028 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1029 | "requires": { 1030 | "once": "^1.3.0", 1031 | "wrappy": "1" 1032 | } 1033 | }, 1034 | "inherits": { 1035 | "version": "2.0.4", 1036 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1037 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1038 | }, 1039 | "is-core-module": { 1040 | "version": "2.8.1", 1041 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", 1042 | "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", 1043 | "requires": { 1044 | "has": "^1.0.3" 1045 | } 1046 | }, 1047 | "lil-gui": { 1048 | "version": "0.16.1", 1049 | "resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.16.1.tgz", 1050 | "integrity": "sha512-6wnnfBvQxJYRhdLyIA+w5b8utwbuVxNmtpTXElm36OSgHa8lyKp00Xz/4AEx3kvodT0AJYgbfadCFWAM0Q8DgQ==" 1051 | }, 1052 | "minimatch": { 1053 | "version": "3.1.2", 1054 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1055 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1056 | "requires": { 1057 | "brace-expansion": "^1.1.7" 1058 | } 1059 | }, 1060 | "ms": { 1061 | "version": "2.1.2", 1062 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1063 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1064 | }, 1065 | "nanoid": { 1066 | "version": "3.3.4", 1067 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", 1068 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" 1069 | }, 1070 | "once": { 1071 | "version": "1.4.0", 1072 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1073 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1074 | "requires": { 1075 | "wrappy": "1" 1076 | } 1077 | }, 1078 | "path-is-absolute": { 1079 | "version": "1.0.1", 1080 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1081 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1082 | }, 1083 | "path-parse": { 1084 | "version": "1.0.7", 1085 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1086 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" 1087 | }, 1088 | "picocolors": { 1089 | "version": "1.0.0", 1090 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1091 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" 1092 | }, 1093 | "picomatch": { 1094 | "version": "2.3.1", 1095 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1096 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" 1097 | }, 1098 | "postcss": { 1099 | "version": "8.4.14", 1100 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", 1101 | "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", 1102 | "requires": { 1103 | "nanoid": "^3.3.4", 1104 | "picocolors": "^1.0.0", 1105 | "source-map-js": "^1.0.2" 1106 | } 1107 | }, 1108 | "resolve": { 1109 | "version": "1.22.0", 1110 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", 1111 | "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", 1112 | "requires": { 1113 | "is-core-module": "^2.8.1", 1114 | "path-parse": "^1.0.7", 1115 | "supports-preserve-symlinks-flag": "^1.0.0" 1116 | } 1117 | }, 1118 | "rollup": { 1119 | "version": "2.68.0", 1120 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.68.0.tgz", 1121 | "integrity": "sha512-XrMKOYK7oQcTio4wyTz466mucnd8LzkiZLozZ4Rz0zQD+HeX4nUK4B8GrTX/2EvN2/vBF/i2WnaXboPxo0JylA==", 1122 | "requires": { 1123 | "fsevents": "~2.3.2" 1124 | } 1125 | }, 1126 | "sax": { 1127 | "version": "1.2.4", 1128 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 1129 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" 1130 | }, 1131 | "source-map": { 1132 | "version": "0.7.3", 1133 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", 1134 | "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" 1135 | }, 1136 | "source-map-js": { 1137 | "version": "1.0.2", 1138 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 1139 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" 1140 | }, 1141 | "source-map-resolve": { 1142 | "version": "0.6.0", 1143 | "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", 1144 | "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", 1145 | "requires": { 1146 | "atob": "^2.1.2", 1147 | "decode-uri-component": "^0.2.0" 1148 | } 1149 | }, 1150 | "stats.js": { 1151 | "version": "0.17.0", 1152 | "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", 1153 | "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" 1154 | }, 1155 | "stylus": { 1156 | "version": "0.58.1", 1157 | "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.58.1.tgz", 1158 | "integrity": "sha512-AYiCHm5ogczdCPMfe9aeQa4NklB2gcf4D/IhzYPddJjTgPc+k4D/EVE0yfQbZD43MHP3lPy+8NZ9fcFxkrgs/w==", 1159 | "requires": { 1160 | "css": "^3.0.0", 1161 | "debug": "^4.3.2", 1162 | "glob": "^7.1.6", 1163 | "sax": "~1.2.4", 1164 | "source-map": "^0.7.3" 1165 | } 1166 | }, 1167 | "supports-preserve-symlinks-flag": { 1168 | "version": "1.0.0", 1169 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1170 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" 1171 | }, 1172 | "three": { 1173 | "version": "0.141.0", 1174 | "resolved": "https://registry.npmjs.org/three/-/three-0.141.0.tgz", 1175 | "integrity": "sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==" 1176 | }, 1177 | "tslib": { 1178 | "version": "2.3.1", 1179 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", 1180 | "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" 1181 | }, 1182 | "vite": { 1183 | "version": "2.9.12", 1184 | "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz", 1185 | "integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==", 1186 | "requires": { 1187 | "esbuild": "^0.14.27", 1188 | "fsevents": "~2.3.2", 1189 | "postcss": "^8.4.13", 1190 | "resolve": "^1.22.0", 1191 | "rollup": "^2.59.0" 1192 | } 1193 | }, 1194 | "vite-plugin-glsl": { 1195 | "version": "0.1.2", 1196 | "resolved": "https://registry.npmjs.org/vite-plugin-glsl/-/vite-plugin-glsl-0.1.2.tgz", 1197 | "integrity": "sha512-RFwoYn8EQFXp4YygIyt8Ex3bQE5/v5927AF0MAgrNfX4NRPlDAX12ciWlpVs4ObKLYro49fctnou4+fajO0FOg==", 1198 | "requires": { 1199 | "@rollup/pluginutils": "^4.1.2", 1200 | "tslib": "^2.3.1" 1201 | } 1202 | }, 1203 | "wrappy": { 1204 | "version": "1.0.2", 1205 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1206 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1207 | } 1208 | } 1209 | } 1210 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webgl-three.js-deferred-rendering", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite serve --host", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "lil-gui": "^0.16.1", 12 | "stats.js": "^0.17.0", 13 | "stylus": "^0.58.1", 14 | "three": "^0.141.0", 15 | "vite": "^2.9.12", 16 | "vite-plugin-glsl": "^0.1.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/basis/README.md: -------------------------------------------------------------------------------- 1 | # Basis Universal GPU Texture Compression 2 | 3 | Basis Universal is a "[supercompressed](http://gamma.cs.unc.edu/GST/gst.pdf)" 4 | GPU texture and texture video compression system that outputs a highly 5 | compressed intermediate file format (.basis) that can be quickly transcoded to 6 | a wide variety of GPU texture compression formats. 7 | 8 | [GitHub](https://github.com/BinomialLLC/basis_universal) 9 | 10 | ## Transcoders 11 | 12 | Basis Universal texture data may be used in two different file formats: 13 | `.basis` and `.ktx2`, where `ktx2` is a standardized wrapper around basis texture data. 14 | 15 | For further documentation about the Basis compressor and transcoder, refer to 16 | the [Basis GitHub repository](https://github.com/BinomialLLC/basis_universal). 17 | 18 | The folder contains two files required for transcoding `.basis` or `.ktx2` textures: 19 | 20 | * `basis_transcoder.js` — JavaScript wrapper for the WebAssembly transcoder. 21 | * `basis_transcoder.wasm` — WebAssembly transcoder. 22 | 23 | Both are dependencies of `THREE.KTX2Loader` and `THREE.BasisTextureLoader`: 24 | 25 | ```js 26 | var ktx2Loader = new THREE.KTX2Loader(); 27 | ktx2Loader.setTranscoderPath( 'examples/js/libs/basis/' ); 28 | ktx2Loader.detectSupport( renderer ); 29 | ktx2Loader.load( 'diffuse.ktx2', function ( texture ) { 30 | 31 | var material = new THREE.MeshStandardMaterial( { map: texture } ); 32 | 33 | }, function () { 34 | 35 | console.log( 'onProgress' ); 36 | 37 | }, function ( e ) { 38 | 39 | console.error( e ); 40 | 41 | } ); 42 | ``` 43 | 44 | ## License 45 | 46 | [Apache License 2.0](https://github.com/BinomialLLC/basis_universal/blob/master/LICENSE) 47 | -------------------------------------------------------------------------------- /public/basis/basis_transcoder.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunosimon/webgl-three.js-deferred-rendering/a516c680d2c51bd386d9987b038cc631669d5f0e/public/basis/basis_transcoder.wasm -------------------------------------------------------------------------------- /public/draco/README.md: -------------------------------------------------------------------------------- 1 | # Draco 3D Data Compression 2 | 3 | Draco is an open-source library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics. 4 | 5 | [Website](https://google.github.io/draco/) | [GitHub](https://github.com/google/draco) 6 | 7 | ## Contents 8 | 9 | This folder contains three utilities: 10 | 11 | * `draco_decoder.js` — Emscripten-compiled decoder, compatible with any modern browser. 12 | * `draco_decoder.wasm` — WebAssembly decoder, compatible with newer browsers and devices. 13 | * `draco_wasm_wrapper.js` — JavaScript wrapper for the WASM decoder. 14 | 15 | Each file is provided in two variations: 16 | 17 | * **Default:** Latest stable builds, tracking the project's [master branch](https://github.com/google/draco). 18 | * **glTF:** Builds targeted by the [glTF mesh compression extension](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression), tracking the [corresponding Draco branch](https://github.com/google/draco/tree/gltf_2.0_draco_extension). 19 | 20 | Either variation may be used with `THREE.DRACOLoader`: 21 | 22 | ```js 23 | var dracoLoader = new THREE.DRACOLoader(); 24 | dracoLoader.setDecoderPath('path/to/decoders/'); 25 | dracoLoader.setDecoderConfig({type: 'js'}); // (Optional) Override detection of WASM support. 26 | ``` 27 | 28 | Further [documentation on GitHub](https://github.com/google/draco/tree/master/javascript/example#static-loading-javascript-decoder). 29 | 30 | ## License 31 | 32 | [Apache License 2.0](https://github.com/google/draco/blob/master/LICENSE) 33 | -------------------------------------------------------------------------------- /public/draco/draco_decoder.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunosimon/webgl-three.js-deferred-rendering/a516c680d2c51bd386d9987b038cc631669d5f0e/public/draco/draco_decoder.wasm -------------------------------------------------------------------------------- /public/draco/draco_wasm_wrapper.js: -------------------------------------------------------------------------------- 1 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(f){var m=0;return function(){return m=d);)++b;if(16k?d+=String.fromCharCode(k):(k-=65536,d+=String.fromCharCode(55296|k>>10,56320|k&1023))}}else d+=String.fromCharCode(k)}return d}function X(a,c){return a?h(ca,a,c):""}function e(a,c){0=d&&(d=65536+((d&1023)<<10)|a.charCodeAt(++b)&1023);127>=d?++c:c=2047>=d?c+2:65535>=d?c+3:c+4}c=Array(c+1);b=0;d=c.length;if(0=e){var f=a.charCodeAt(++k);e=65536+((e&1023)<<10)|f&1023}if(127>=e){if(b>=d)break;c[b++]=e}else{if(2047>=e){if(b+1>=d)break;c[b++]=192|e>>6}else{if(65535>=e){if(b+2>=d)break;c[b++]=224|e>>12}else{if(b+3>=d)break;c[b++]=240|e>>18;c[b++]=128|e>>12&63}c[b++]=128|e>>6&63}c[b++]=128| 18 | e&63}}c[b]=0}a=n.alloc(c,T);n.copy(c,T,a)}return a}function x(){throw"cannot construct a Status, no constructor in IDL";}function A(){this.ptr=Oa();u(A)[this.ptr]=this}function B(){this.ptr=Pa();u(B)[this.ptr]=this}function C(){this.ptr=Qa();u(C)[this.ptr]=this}function D(){this.ptr=Ra();u(D)[this.ptr]=this}function E(){this.ptr=Sa();u(E)[this.ptr]=this}function q(){this.ptr=Ta();u(q)[this.ptr]=this}function J(){this.ptr=Ua();u(J)[this.ptr]=this}function w(){this.ptr=Va();u(w)[this.ptr]=this}function F(){this.ptr= 19 | Wa();u(F)[this.ptr]=this}function r(){this.ptr=Xa();u(r)[this.ptr]=this}function G(){this.ptr=Ya();u(G)[this.ptr]=this}function H(){this.ptr=Za();u(H)[this.ptr]=this}function O(){this.ptr=$a();u(O)[this.ptr]=this}function K(){this.ptr=ab();u(K)[this.ptr]=this}function g(){this.ptr=bb();u(g)[this.ptr]=this}function y(){this.ptr=cb();u(y)[this.ptr]=this}function Q(){throw"cannot construct a VoidPtr, no constructor in IDL";}function I(){this.ptr=db();u(I)[this.ptr]=this}function L(){this.ptr=eb();u(L)[this.ptr]= 20 | this}m=m||{};var a="undefined"!==typeof m?m:{},Ga=!1,Ha=!1;a.onRuntimeInitialized=function(){Ga=!0;if(Ha&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Ha=!0;if(Ga&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(a){if("string"!==typeof a)return!1;a=a.split(".");return 2>a.length||3=a[1]?!0:0!=a[0]||10>2]},getStr:function(){return X(R.get())}, 26 | get64:function(){var a=R.get();R.get();return a},getZero:function(){R.get()}},Ka={__cxa_allocate_exception:function(a){return ib(a)},__cxa_throw:function(a,c,b){"uncaught_exception"in ta?ta.uncaught_exceptions++:ta.uncaught_exceptions=1;throw a;},abort:function(){z()},emscripten_get_sbrk_ptr:function(){return 18416},emscripten_memcpy_big:function(a,c,b){ca.set(ca.subarray(c,c+b),a)},emscripten_resize_heap:function(a){if(2147418112= 27 | c?e(2*c,65536):Math.min(e((3*c+2147483648)/4,65536),2147418112);a:{try{ia.grow(c-ka.byteLength+65535>>16);l(ia.buffer);var b=1;break a}catch(d){}b=void 0}return b?!0:!1},environ_get:function(a,c){var b=0;ba().forEach(function(d,e){var f=c+b;e=P[a+4*e>>2]=f;for(f=0;f>0]=d.charCodeAt(f);T[e>>0]=0;b+=d.length+1});return 0},environ_sizes_get:function(a,c){var b=ba();P[a>>2]=b.length;var d=0;b.forEach(function(a){d+=a.length+1});P[c>>2]=d;return 0},fd_close:function(a){return 0},fd_seek:function(a, 28 | c,b,d,e){return 0},fd_write:function(a,c,b,d){try{for(var e=0,f=0;f>2],k=P[c+(8*f+4)>>2],h=0;h>2]=e;return 0}catch(ua){return"undefined"!==typeof FS&&ua instanceof FS.ErrnoError||z(ua),ua.errno}},memory:ia,setTempRet0:function(a){},table:gb},La=function(){function e(c,b){a.asm=c.exports;aa--;a.monitorRunDependencies&&a.monitorRunDependencies(aa);0==aa&&(null!==sa&&(clearInterval(sa),sa=null),ja&&(c=ja,ja=null,c()))}function c(a){e(a.instance)} 29 | function b(a){return Ma().then(function(a){return WebAssembly.instantiate(a,d)}).then(a,function(a){Y("failed to asynchronously prepare wasm: "+a);z(a)})}var d={env:Ka,wasi_unstable:Ka};aa++;a.monitorRunDependencies&&a.monitorRunDependencies(aa);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(Na){return Y("Module.instantiateWasm callback failed with error: "+Na),!1}(function(){if(da||"function"!==typeof WebAssembly.instantiateStreaming||va(U)||"function"!==typeof fetch)return b(c);fetch(U, 30 | {credentials:"same-origin"}).then(function(a){return WebAssembly.instantiateStreaming(a,d).then(c,function(a){Y("wasm streaming compile failed: "+a);Y("falling back to ArrayBuffer instantiation");b(c)})})})();return{}}();a.asm=La;var hb=a.___wasm_call_ctors=function(){return a.asm.__wasm_call_ctors.apply(null,arguments)},jb=a._emscripten_bind_Status_code_0=function(){return a.asm.emscripten_bind_Status_code_0.apply(null,arguments)},kb=a._emscripten_bind_Status_ok_0=function(){return a.asm.emscripten_bind_Status_ok_0.apply(null, 31 | arguments)},lb=a._emscripten_bind_Status_error_msg_0=function(){return a.asm.emscripten_bind_Status_error_msg_0.apply(null,arguments)},mb=a._emscripten_bind_Status___destroy___0=function(){return a.asm.emscripten_bind_Status___destroy___0.apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return a.asm.emscripten_bind_DracoUInt16Array_DracoUInt16Array_0.apply(null,arguments)},nb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoUInt16Array_GetValue_1.apply(null, 32 | arguments)},ob=a._emscripten_bind_DracoUInt16Array_size_0=function(){return a.asm.emscripten_bind_DracoUInt16Array_size_0.apply(null,arguments)},pb=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return a.asm.emscripten_bind_DracoUInt16Array___destroy___0.apply(null,arguments)},Pa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return a.asm.emscripten_bind_PointCloud_PointCloud_0.apply(null,arguments)},qb=a._emscripten_bind_PointCloud_num_attributes_0=function(){return a.asm.emscripten_bind_PointCloud_num_attributes_0.apply(null, 33 | arguments)},rb=a._emscripten_bind_PointCloud_num_points_0=function(){return a.asm.emscripten_bind_PointCloud_num_points_0.apply(null,arguments)},sb=a._emscripten_bind_PointCloud___destroy___0=function(){return a.asm.emscripten_bind_PointCloud___destroy___0.apply(null,arguments)},Qa=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return a.asm.emscripten_bind_DracoUInt8Array_DracoUInt8Array_0.apply(null,arguments)},tb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoUInt8Array_GetValue_1.apply(null, 34 | arguments)},ub=a._emscripten_bind_DracoUInt8Array_size_0=function(){return a.asm.emscripten_bind_DracoUInt8Array_size_0.apply(null,arguments)},vb=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return a.asm.emscripten_bind_DracoUInt8Array___destroy___0.apply(null,arguments)},Ra=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return a.asm.emscripten_bind_DracoUInt32Array_DracoUInt32Array_0.apply(null,arguments)},wb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoUInt32Array_GetValue_1.apply(null, 35 | arguments)},xb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return a.asm.emscripten_bind_DracoUInt32Array_size_0.apply(null,arguments)},yb=a._emscripten_bind_DracoUInt32Array___destroy___0=function(){return a.asm.emscripten_bind_DracoUInt32Array___destroy___0.apply(null,arguments)},Sa=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return a.asm.emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0.apply(null,arguments)},zb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1= 36 | function(){return a.asm.emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1.apply(null,arguments)},Ab=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return a.asm.emscripten_bind_AttributeOctahedronTransform_quantization_bits_0.apply(null,arguments)},Bb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return a.asm.emscripten_bind_AttributeOctahedronTransform___destroy___0.apply(null,arguments)},Ta=a._emscripten_bind_PointAttribute_PointAttribute_0= 37 | function(){return a.asm.emscripten_bind_PointAttribute_PointAttribute_0.apply(null,arguments)},Cb=a._emscripten_bind_PointAttribute_size_0=function(){return a.asm.emscripten_bind_PointAttribute_size_0.apply(null,arguments)},Db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=function(){return a.asm.emscripten_bind_PointAttribute_GetAttributeTransformData_0.apply(null,arguments)},Eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return a.asm.emscripten_bind_PointAttribute_attribute_type_0.apply(null, 38 | arguments)},Fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return a.asm.emscripten_bind_PointAttribute_data_type_0.apply(null,arguments)},Gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return a.asm.emscripten_bind_PointAttribute_num_components_0.apply(null,arguments)},Hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return a.asm.emscripten_bind_PointAttribute_normalized_0.apply(null,arguments)},Ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return a.asm.emscripten_bind_PointAttribute_byte_stride_0.apply(null, 39 | arguments)},Jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return a.asm.emscripten_bind_PointAttribute_byte_offset_0.apply(null,arguments)},Kb=a._emscripten_bind_PointAttribute_unique_id_0=function(){return a.asm.emscripten_bind_PointAttribute_unique_id_0.apply(null,arguments)},Lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return a.asm.emscripten_bind_PointAttribute___destroy___0.apply(null,arguments)},Ua=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0= 40 | function(){return a.asm.emscripten_bind_AttributeTransformData_AttributeTransformData_0.apply(null,arguments)},Mb=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return a.asm.emscripten_bind_AttributeTransformData_transform_type_0.apply(null,arguments)},Nb=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return a.asm.emscripten_bind_AttributeTransformData___destroy___0.apply(null,arguments)},Va=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0= 41 | function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0.apply(null,arguments)},Ob=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1.apply(null,arguments)},Pb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_quantization_bits_0.apply(null,arguments)}, 42 | Qb=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_min_value_1.apply(null,arguments)},Rb=a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_range_0.apply(null,arguments)},Sb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform___destroy___0.apply(null,arguments)}, 43 | Wa=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return a.asm.emscripten_bind_DracoInt8Array_DracoInt8Array_0.apply(null,arguments)},Tb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoInt8Array_GetValue_1.apply(null,arguments)},Ub=a._emscripten_bind_DracoInt8Array_size_0=function(){return a.asm.emscripten_bind_DracoInt8Array_size_0.apply(null,arguments)},Vb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return a.asm.emscripten_bind_DracoInt8Array___destroy___0.apply(null, 44 | arguments)},Xa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return a.asm.emscripten_bind_MetadataQuerier_MetadataQuerier_0.apply(null,arguments)},Wb=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_HasEntry_2.apply(null,arguments)},Xb=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetIntEntry_2.apply(null,arguments)},Yb=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3= 45 | function(){return a.asm.emscripten_bind_MetadataQuerier_GetIntEntryArray_3.apply(null,arguments)},Zb=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetDoubleEntry_2.apply(null,arguments)},$b=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetStringEntry_2.apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return a.asm.emscripten_bind_MetadataQuerier_NumEntries_1.apply(null, 46 | arguments)},bc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetEntryName_2.apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return a.asm.emscripten_bind_MetadataQuerier___destroy___0.apply(null,arguments)},Ya=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return a.asm.emscripten_bind_DracoInt16Array_DracoInt16Array_0.apply(null,arguments)},dc=a._emscripten_bind_DracoInt16Array_GetValue_1= 47 | function(){return a.asm.emscripten_bind_DracoInt16Array_GetValue_1.apply(null,arguments)},ec=a._emscripten_bind_DracoInt16Array_size_0=function(){return a.asm.emscripten_bind_DracoInt16Array_size_0.apply(null,arguments)},fc=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return a.asm.emscripten_bind_DracoInt16Array___destroy___0.apply(null,arguments)},Za=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return a.asm.emscripten_bind_DracoFloat32Array_DracoFloat32Array_0.apply(null, 48 | arguments)},gc=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoFloat32Array_GetValue_1.apply(null,arguments)},hc=a._emscripten_bind_DracoFloat32Array_size_0=function(){return a.asm.emscripten_bind_DracoFloat32Array_size_0.apply(null,arguments)},ic=a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return a.asm.emscripten_bind_DracoFloat32Array___destroy___0.apply(null,arguments)},$a=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return a.asm.emscripten_bind_GeometryAttribute_GeometryAttribute_0.apply(null, 49 | arguments)},jc=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return a.asm.emscripten_bind_GeometryAttribute___destroy___0.apply(null,arguments)},ab=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=function(){return a.asm.emscripten_bind_DecoderBuffer_DecoderBuffer_0.apply(null,arguments)},kc=a._emscripten_bind_DecoderBuffer_Init_2=function(){return a.asm.emscripten_bind_DecoderBuffer_Init_2.apply(null,arguments)},lc=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return a.asm.emscripten_bind_DecoderBuffer___destroy___0.apply(null, 50 | arguments)},bb=a._emscripten_bind_Decoder_Decoder_0=function(){return a.asm.emscripten_bind_Decoder_Decoder_0.apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetEncodedGeometryType_1=function(){return a.asm.emscripten_bind_Decoder_GetEncodedGeometryType_1.apply(null,arguments)},nc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return a.asm.emscripten_bind_Decoder_DecodeBufferToPointCloud_2.apply(null,arguments)},oc=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return a.asm.emscripten_bind_Decoder_DecodeBufferToMesh_2.apply(null, 51 | arguments)},pc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeId_2.apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeIdByName_2.apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3.apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetAttribute_2= 52 | function(){return a.asm.emscripten_bind_Decoder_GetAttribute_2.apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeByUniqueId_2.apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return a.asm.emscripten_bind_Decoder_GetMetadata_1.apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeMetadata_2.apply(null, 53 | arguments)},wc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=function(){return a.asm.emscripten_bind_Decoder_GetFaceFromMesh_3.apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return a.asm.emscripten_bind_Decoder_GetTriangleStripsFromMesh_2.apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return a.asm.emscripten_bind_Decoder_GetTrianglesUInt16Array_3.apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3= 54 | function(){return a.asm.emscripten_bind_Decoder_GetTrianglesUInt32Array_3.apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeFloat_3.apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3.apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeIntForAllPoints_3.apply(null, 55 | arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3.apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3.apply(null,arguments)},Fc=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3.apply(null,arguments)}, 56 | Gc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3.apply(null,arguments)},Hc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3.apply(null,arguments)},Ic=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3.apply(null,arguments)},Jc= 57 | a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return a.asm.emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5.apply(null,arguments)},Kc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return a.asm.emscripten_bind_Decoder_SkipAttributeTransform_1.apply(null,arguments)},Lc=a._emscripten_bind_Decoder___destroy___0=function(){return a.asm.emscripten_bind_Decoder___destroy___0.apply(null,arguments)},cb=a._emscripten_bind_Mesh_Mesh_0=function(){return a.asm.emscripten_bind_Mesh_Mesh_0.apply(null, 58 | arguments)},Mc=a._emscripten_bind_Mesh_num_faces_0=function(){return a.asm.emscripten_bind_Mesh_num_faces_0.apply(null,arguments)},Nc=a._emscripten_bind_Mesh_num_attributes_0=function(){return a.asm.emscripten_bind_Mesh_num_attributes_0.apply(null,arguments)},Oc=a._emscripten_bind_Mesh_num_points_0=function(){return a.asm.emscripten_bind_Mesh_num_points_0.apply(null,arguments)},Pc=a._emscripten_bind_Mesh___destroy___0=function(){return a.asm.emscripten_bind_Mesh___destroy___0.apply(null,arguments)}, 59 | Qc=a._emscripten_bind_VoidPtr___destroy___0=function(){return a.asm.emscripten_bind_VoidPtr___destroy___0.apply(null,arguments)},db=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=function(){return a.asm.emscripten_bind_DracoInt32Array_DracoInt32Array_0.apply(null,arguments)},Rc=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoInt32Array_GetValue_1.apply(null,arguments)},Sc=a._emscripten_bind_DracoInt32Array_size_0=function(){return a.asm.emscripten_bind_DracoInt32Array_size_0.apply(null, 60 | arguments)},Tc=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return a.asm.emscripten_bind_DracoInt32Array___destroy___0.apply(null,arguments)},eb=a._emscripten_bind_Metadata_Metadata_0=function(){return a.asm.emscripten_bind_Metadata_Metadata_0.apply(null,arguments)},Uc=a._emscripten_bind_Metadata___destroy___0=function(){return a.asm.emscripten_bind_Metadata___destroy___0.apply(null,arguments)},Vc=a._emscripten_enum_draco_StatusCode_OK=function(){return a.asm.emscripten_enum_draco_StatusCode_OK.apply(null, 61 | arguments)},Wc=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return a.asm.emscripten_enum_draco_StatusCode_DRACO_ERROR.apply(null,arguments)},Xc=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return a.asm.emscripten_enum_draco_StatusCode_IO_ERROR.apply(null,arguments)},Yc=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=function(){return a.asm.emscripten_enum_draco_StatusCode_INVALID_PARAMETER.apply(null,arguments)},Zc=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION= 62 | function(){return a.asm.emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION.apply(null,arguments)},$c=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return a.asm.emscripten_enum_draco_StatusCode_UNKNOWN_VERSION.apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return a.asm.emscripten_enum_draco_DataType_DT_INVALID.apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT8=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT8.apply(null, 63 | arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT8=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT8.apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT16=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT16.apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT16.apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT32.apply(null, 64 | arguments)},gd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT32.apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT64.apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT64.apply(null,arguments)},jd=a._emscripten_enum_draco_DataType_DT_FLOAT32=function(){return a.asm.emscripten_enum_draco_DataType_DT_FLOAT32.apply(null, 65 | arguments)},kd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return a.asm.emscripten_enum_draco_DataType_DT_FLOAT64.apply(null,arguments)},ld=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return a.asm.emscripten_enum_draco_DataType_DT_BOOL.apply(null,arguments)},md=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return a.asm.emscripten_enum_draco_DataType_DT_TYPES_COUNT.apply(null,arguments)},nd=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return a.asm.emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE.apply(null, 66 | arguments)},od=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return a.asm.emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD.apply(null,arguments)},pd=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return a.asm.emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH.apply(null,arguments)},qd=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM.apply(null, 67 | arguments)},rd=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM.apply(null,arguments)},sd=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM.apply(null,arguments)},td=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM.apply(null, 68 | arguments)},ud=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_INVALID.apply(null,arguments)},vd=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_POSITION.apply(null,arguments)},wd=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_NORMAL.apply(null,arguments)},xd=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR= 69 | function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_COLOR.apply(null,arguments)},yd=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD.apply(null,arguments)},zd=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_GENERIC.apply(null,arguments)};a._setThrew=function(){return a.asm.setThrew.apply(null,arguments)};var ta=a.__ZSt18uncaught_exceptionv= 70 | function(){return a.asm._ZSt18uncaught_exceptionv.apply(null,arguments)};a._free=function(){return a.asm.free.apply(null,arguments)};var ib=a._malloc=function(){return a.asm.malloc.apply(null,arguments)};a.stackSave=function(){return a.asm.stackSave.apply(null,arguments)};a.stackAlloc=function(){return a.asm.stackAlloc.apply(null,arguments)};a.stackRestore=function(){return a.asm.stackRestore.apply(null,arguments)};a.__growWasmMemory=function(){return a.asm.__growWasmMemory.apply(null,arguments)}; 71 | a.dynCall_ii=function(){return a.asm.dynCall_ii.apply(null,arguments)};a.dynCall_vi=function(){return a.asm.dynCall_vi.apply(null,arguments)};a.dynCall_iii=function(){return a.asm.dynCall_iii.apply(null,arguments)};a.dynCall_vii=function(){return a.asm.dynCall_vii.apply(null,arguments)};a.dynCall_iiii=function(){return a.asm.dynCall_iiii.apply(null,arguments)};a.dynCall_v=function(){return a.asm.dynCall_v.apply(null,arguments)};a.dynCall_viii=function(){return a.asm.dynCall_viii.apply(null,arguments)}; 72 | a.dynCall_viiii=function(){return a.asm.dynCall_viiii.apply(null,arguments)};a.dynCall_iiiiiii=function(){return a.asm.dynCall_iiiiiii.apply(null,arguments)};a.dynCall_iidiiii=function(){return a.asm.dynCall_iidiiii.apply(null,arguments)};a.dynCall_jiji=function(){return a.asm.dynCall_jiji.apply(null,arguments)};a.dynCall_viiiiii=function(){return a.asm.dynCall_viiiiii.apply(null,arguments)};a.dynCall_viiiii=function(){return a.asm.dynCall_viiiii.apply(null,arguments)};a.asm=La;var fa;a.then=function(e){if(fa)e(a); 73 | else{var c=a.onRuntimeInitialized;a.onRuntimeInitialized=function(){c&&c();e(a)}}return a};ja=function c(){fa||ma();fa||(ja=c)};a.run=ma;if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0=n.size?(t(0>=1;break;case 4:d>>=2;break;case 8:d>>=3}for(var c=0;c 89 | { 90 | if(this.mode === 'defaultCamera') 91 | { 92 | this.debugCamera.deactivate() 93 | this.defaultCamera.activate() 94 | } 95 | else 96 | { 97 | this.defaultCamera.deactivate() 98 | this.debugCamera.activate() 99 | } 100 | }) 101 | } 102 | 103 | resize() 104 | { 105 | this.instance.aspect = this.viewport.elementWidth / this.viewport.elementHeight 106 | this.instance.updateProjectionMatrix() 107 | } 108 | 109 | update() 110 | { 111 | this.debugCamera.update() 112 | 113 | this.instance.position.copy(this[this.mode].instance.position) 114 | this.instance.quaternion.copy(this[this.mode].instance.quaternion) 115 | this.instance.updateMatrixWorld() // To be used in projection 116 | } 117 | 118 | destroy() 119 | { 120 | this.defaultCamera.destroy() 121 | this.debugCamera.destroy() 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /sources/Experience/Camera/DebugCamera.js: -------------------------------------------------------------------------------- 1 | import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' 2 | 3 | export default class DebugCamera 4 | { 5 | constructor(_options) 6 | { 7 | this.time = _options.time 8 | this.baseInstance = _options.baseInstance 9 | this.domElement = _options.domElement 10 | 11 | this.active = false 12 | this.instance = this.baseInstance.clone() 13 | this.instance.position.set(20, 15, 20) 14 | // this.instance.position.multiplyScalar(1.35) 15 | 16 | this.orbitControls = new OrbitControls(this.instance, this.domElement) 17 | this.orbitControls.enabled = this.active 18 | this.orbitControls.screenSpacePanning = true 19 | this.orbitControls.enableKeys = false 20 | this.orbitControls.zoomSpeed = 0.25 21 | this.orbitControls.enableDamping = true 22 | this.orbitControls.update() 23 | } 24 | 25 | update() 26 | { 27 | if(!this.active) 28 | { 29 | return 30 | } 31 | 32 | this.orbitControls.update() 33 | } 34 | 35 | activate() 36 | { 37 | this.active = true 38 | this.orbitControls.enabled = true 39 | } 40 | 41 | deactivate() 42 | { 43 | this.active = false 44 | this.orbitControls.enabled = false 45 | } 46 | 47 | destroy() 48 | { 49 | this.orbitControls.dispose() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sources/Experience/Camera/DefaultCamera.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | export default class DefaultCamera 4 | { 5 | constructor(_options) 6 | { 7 | this.time = _options.time 8 | this.baseInstance = _options.baseInstance 9 | 10 | this.active = false 11 | 12 | this.instance = this.baseInstance.clone() 13 | this.instance.position.set(15, 15, 15) 14 | this.instance.rotation.reorder('YXZ') 15 | } 16 | 17 | activate() 18 | { 19 | this.active = true 20 | } 21 | 22 | deactivate() 23 | { 24 | this.active = false 25 | } 26 | 27 | destroy() 28 | { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /sources/Experience/Debug/Debug.js: -------------------------------------------------------------------------------- 1 | import DebugUI from '@/Debug/DebugUI.js' 2 | import DebugStats from '@/Debug/DebugStats.js' 3 | 4 | export default class Debug 5 | { 6 | constructor() 7 | { 8 | this.active = window.location.hash === '#debug' 9 | 10 | if(this.active) 11 | { 12 | this.ui = new DebugUI() 13 | this.stats = new DebugStats() 14 | } 15 | } 16 | 17 | update() 18 | { 19 | if(!this.active) 20 | return 21 | 22 | this.stats.update() 23 | } 24 | } -------------------------------------------------------------------------------- /sources/Experience/Debug/DebugStats.js: -------------------------------------------------------------------------------- 1 | import StatsJs from 'stats.js' 2 | 3 | export default class DebugStats 4 | { 5 | constructor() 6 | { 7 | this.instance = new StatsJs() 8 | this.instance.showPanel(3) 9 | 10 | this.active = false 11 | this.max = 120 12 | this.ignoreMaxed = true 13 | 14 | this.activate() 15 | } 16 | 17 | activate() 18 | { 19 | this.active = true 20 | 21 | document.body.appendChild(this.instance.dom) 22 | } 23 | 24 | deactivate() 25 | { 26 | this.active = false 27 | 28 | document.body.removeChild(this.instance.dom) 29 | } 30 | 31 | setRenderPanel(_context) 32 | { 33 | this.experience = {} 34 | this.experience.context = _context 35 | this.experience.extension = this.experience.context.getExtension('EXT_disjoint_timer_query_webgl2') 36 | this.experience.panel = this.instance.addPanel(new StatsJs.Panel('Render (ms)', '#f8f', '#212')) 37 | 38 | const webGL2 = typeof WebGL2RenderingContext !== 'undefined' && _context instanceof WebGL2RenderingContext 39 | 40 | if(!webGL2 || !this.experience.extension) 41 | { 42 | this.deactivate() 43 | } 44 | } 45 | 46 | beforeRender() 47 | { 48 | if(!this.active) 49 | { 50 | return 51 | } 52 | 53 | // Setup 54 | this.queryCreated = false 55 | let queryResultAvailable = false 56 | 57 | // Test if query result available 58 | if(this.experience.query) 59 | { 60 | queryResultAvailable = this.experience.context.getQueryParameter(this.experience.query, this.experience.context.QUERY_RESULT_AVAILABLE) 61 | const disjoint = this.experience.context.getParameter(this.experience.extension.GPU_DISJOINT_EXT) 62 | 63 | if(queryResultAvailable && !disjoint) 64 | { 65 | const elapsedNanos = this.experience.context.getQueryParameter(this.experience.query, this.experience.context.QUERY_RESULT) 66 | const panelValue = Math.min(elapsedNanos / 1000 / 1000, this.max) 67 | 68 | if(panelValue === this.max && this.ignoreMaxed) 69 | { 70 | 71 | } 72 | else 73 | { 74 | this.experience.panel.update(panelValue, this.max) 75 | } 76 | } 77 | } 78 | 79 | // If query result available or no query yet 80 | if(queryResultAvailable || !this.experience.query) 81 | { 82 | // Create new query 83 | this.queryCreated = true 84 | this.experience.query = this.experience.context.createQuery() 85 | this.experience.context.beginQuery(this.experience.extension.TIME_ELAPSED_EXT, this.experience.query) 86 | } 87 | 88 | } 89 | 90 | afterRender() 91 | { 92 | if(!this.active) 93 | { 94 | return 95 | } 96 | 97 | // End the query (result will be available "later") 98 | if(this.queryCreated) 99 | { 100 | this.experience.context.endQuery(this.experience.extension.TIME_ELAPSED_EXT) 101 | } 102 | } 103 | 104 | update() 105 | { 106 | if(!this.active) 107 | { 108 | return 109 | } 110 | 111 | this.instance.update() 112 | } 113 | 114 | destroy() 115 | { 116 | this.deactivate() 117 | } 118 | } -------------------------------------------------------------------------------- /sources/Experience/Debug/DebugUI.js: -------------------------------------------------------------------------------- 1 | import * as dat from 'lil-gui' 2 | 3 | export default class DebugUI 4 | { 5 | constructor() 6 | { 7 | this.instance = new dat.GUI({ width: 320, title: 'debug' }) 8 | 9 | const sheet = window.document.styleSheets[0] 10 | sheet.insertRule(` 11 | .lil-gui .lil-gui > .children 12 | { 13 | border: none; 14 | margin-left: var(--folder-indent); 15 | border-left: 2px solid var(--widget-color); 16 | } 17 | `, sheet.cssRules.length) 18 | sheet.insertRule(` 19 | .lil-gui.root > .children > .lil-gui > .title 20 | { 21 | border-width: 1px 0 0 0; 22 | } 23 | `, sheet.cssRules.length) 24 | 25 | this.tree = {} 26 | this.tree.folder = this.instance 27 | this.tree.children = {} 28 | } 29 | 30 | getFolder(path) 31 | { 32 | const parts = path.split('/') 33 | 34 | let branch = this.tree 35 | 36 | for(const part of parts) 37 | { 38 | let newBranch = branch.children[part] 39 | 40 | if(!newBranch) 41 | { 42 | newBranch = {} 43 | newBranch.folder = branch.folder.addFolder(part) 44 | newBranch.folder.close() 45 | newBranch.children = {} 46 | } 47 | 48 | branch.children[part] = newBranch 49 | branch = newBranch 50 | } 51 | 52 | return branch.folder 53 | } 54 | } -------------------------------------------------------------------------------- /sources/Experience/EventEmitter.js: -------------------------------------------------------------------------------- 1 | export default class EventEmitter 2 | { 3 | /** 4 | * Constructor 5 | */ 6 | constructor() 7 | { 8 | this.callbacks = {} 9 | this.callbacks.base = {} 10 | } 11 | 12 | /** 13 | * On 14 | */ 15 | on(_names, callback) 16 | { 17 | const that = this 18 | 19 | // Errors 20 | if(typeof _names === 'undefined' || _names === '') 21 | { 22 | console.warn('wrong names') 23 | return false 24 | } 25 | 26 | if(typeof callback === 'undefined') 27 | { 28 | console.warn('wrong callback') 29 | return false 30 | } 31 | 32 | // Resolve names 33 | const names = this.resolveNames(_names) 34 | 35 | // Each name 36 | names.forEach(function(_name) 37 | { 38 | // Resolve name 39 | const name = that.resolveName(_name) 40 | 41 | // Create namespace if not exist 42 | if(!(that.callbacks[ name.namespace ] instanceof Object)) 43 | that.callbacks[ name.namespace ] = {} 44 | 45 | // Create callback if not exist 46 | if(!(that.callbacks[ name.namespace ][ name.value ] instanceof Array)) 47 | that.callbacks[ name.namespace ][ name.value ] = [] 48 | 49 | // Add callback 50 | that.callbacks[ name.namespace ][ name.value ].push(callback) 51 | }) 52 | 53 | return this 54 | } 55 | 56 | /** 57 | * Off 58 | */ 59 | off(_names) 60 | { 61 | const that = this 62 | 63 | // Errors 64 | if(typeof _names === 'undefined' || _names === '') 65 | { 66 | console.warn('wrong name') 67 | return false 68 | } 69 | 70 | // Resolve names 71 | const names = this.resolveNames(_names) 72 | 73 | // Each name 74 | names.forEach(function(_name) 75 | { 76 | // Resolve name 77 | const name = that.resolveName(_name) 78 | 79 | // Remove namespace 80 | if(name.namespace !== 'base' && name.value === '') 81 | { 82 | delete that.callbacks[ name.namespace ] 83 | } 84 | 85 | // Remove specific callback in namespace 86 | else 87 | { 88 | // Default 89 | if(name.namespace === 'base') 90 | { 91 | // Try to remove from each namespace 92 | for(const namespace in that.callbacks) 93 | { 94 | if(that.callbacks[ namespace ] instanceof Object && that.callbacks[ namespace ][ name.value ] instanceof Array) 95 | { 96 | delete that.callbacks[ namespace ][ name.value ] 97 | 98 | // Remove namespace if empty 99 | if(Object.keys(that.callbacks[ namespace ]).length === 0) 100 | delete that.callbacks[ namespace ] 101 | } 102 | } 103 | } 104 | 105 | // Specified namespace 106 | else if(that.callbacks[ name.namespace ] instanceof Object && that.callbacks[ name.namespace ][ name.value ] instanceof Array) 107 | { 108 | delete that.callbacks[ name.namespace ][ name.value ] 109 | 110 | // Remove namespace if empty 111 | if(Object.keys(that.callbacks[ name.namespace ]).length === 0) 112 | delete that.callbacks[ name.namespace ] 113 | } 114 | } 115 | }) 116 | 117 | return this 118 | } 119 | 120 | /** 121 | * Trigger 122 | */ 123 | trigger(_name, _args) 124 | { 125 | // Errors 126 | if(typeof _name === 'undefined' || _name === '') 127 | { 128 | console.warn('wrong name') 129 | return false 130 | } 131 | 132 | const that = this 133 | let finalResult = null 134 | let result = null 135 | 136 | // Default args 137 | const args = !(_args instanceof Array) ? [] : _args 138 | 139 | // Resolve names (should on have one event) 140 | let name = this.resolveNames(_name) 141 | 142 | // Resolve name 143 | name = this.resolveName(name[ 0 ]) 144 | 145 | // Default namespace 146 | if(name.namespace === 'base') 147 | { 148 | // Try to find callback in each namespace 149 | for(const namespace in that.callbacks) 150 | { 151 | if(that.callbacks[ namespace ] instanceof Object && that.callbacks[ namespace ][ name.value ] instanceof Array) 152 | { 153 | that.callbacks[ namespace ][ name.value ].forEach(function(callback) 154 | { 155 | result = callback.apply(that, args) 156 | 157 | if(typeof finalResult === 'undefined') 158 | { 159 | finalResult = result 160 | } 161 | }) 162 | } 163 | } 164 | } 165 | 166 | // Specified namespace 167 | else if(this.callbacks[ name.namespace ] instanceof Object) 168 | { 169 | if(name.value === '') 170 | { 171 | console.warn('wrong name') 172 | return this 173 | } 174 | 175 | that.callbacks[ name.namespace ][ name.value ].forEach(function(callback) 176 | { 177 | result = callback.apply(that, args) 178 | 179 | if(typeof finalResult === 'undefined') 180 | finalResult = result 181 | }) 182 | } 183 | 184 | return finalResult 185 | } 186 | 187 | /** 188 | * Resolve names 189 | */ 190 | resolveNames(_names) 191 | { 192 | let names = _names 193 | names = names.replace(/[^a-zA-Z0-9 ,/.]/g, '') 194 | names = names.replace(/[,/]+/g, ' ') 195 | names = names.split(' ') 196 | 197 | return names 198 | } 199 | 200 | /** 201 | * Resolve name 202 | */ 203 | resolveName(name) 204 | { 205 | const newName = {} 206 | const parts = name.split('.') 207 | 208 | newName.original = name 209 | newName.value = parts[ 0 ] 210 | newName.namespace = 'base' // Base namespace 211 | 212 | // Specified namespace 213 | if(parts.length > 1 && parts[ 1 ] !== '') 214 | { 215 | newName.namespace = parts[ 1 ] 216 | } 217 | 218 | return newName 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /sources/Experience/Experience.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import Debug from '@/Debug/Debug.js' 4 | import Resources from '@/Resources.js' 5 | import assets from '@/assets.js' 6 | import EventEmitter from '@/EventEmitter.js' 7 | import Viewport from '@/Viewport.js' 8 | import Time from '@/Time.js' 9 | import Camera from '@/Camera/Camera.js' 10 | import Renderer from '@/Renderer.js' 11 | import World from './World.js' 12 | 13 | export default class Experience extends EventEmitter 14 | { 15 | static instance 16 | 17 | constructor(_options) 18 | { 19 | super() 20 | 21 | // Singleton 22 | if(Experience.instance) 23 | { 24 | return Experience.instance 25 | } 26 | Experience.instance = this 27 | 28 | // Options 29 | this.domElement = _options.domElement 30 | 31 | // Setup 32 | this.debug = new Debug() 33 | this.viewport = new Viewport({ 34 | domElement: this.domElement 35 | }) 36 | this.scenes = { 37 | deferred: new THREE.Scene(), 38 | forward: new THREE.Scene() 39 | } 40 | this.camera = new Camera() 41 | this.time = new Time() 42 | this.rendererInstance = new THREE.WebGLRenderer({ 43 | stencil: false, 44 | // alpha: true, 45 | // antialias: true, 46 | powerPreference: 'high-performance' 47 | }) 48 | this.renderer = new Renderer() 49 | this.resources = new Resources(this.rendererInstance, assets) 50 | 51 | this.resources.on('end', () => 52 | { 53 | this.world = new World() 54 | }) 55 | 56 | window.addEventListener('resize', () => 57 | { 58 | this.resize() 59 | }) 60 | 61 | this.update() 62 | } 63 | 64 | update() 65 | { 66 | this.debug.update() 67 | this.camera.update() 68 | this.renderer.update() 69 | 70 | if(this.world) 71 | this.world.update() 72 | 73 | window.requestAnimationFrame(() => 74 | { 75 | this.update() 76 | }) 77 | } 78 | 79 | resize() 80 | { 81 | this.viewport.resize() 82 | this.camera.resize() 83 | this.renderer.resize() 84 | 85 | if(this.world) 86 | this.world.resize() 87 | } 88 | } -------------------------------------------------------------------------------- /sources/Experience/Lights.js: -------------------------------------------------------------------------------- 1 | import Experience from '@/Experience.js' 2 | import * as THREE from 'three' 3 | import PointLightMaterial from './Materials/PointLightMaterial.js' 4 | 5 | export default class Lights 6 | { 7 | constructor() 8 | { 9 | this.experience = new Experience() 10 | this.camera = this.experience.camera 11 | this.scenes = this.experience.scenes 12 | this.debug = this.experience.debug 13 | this.renderer = this.experience.renderer 14 | this.viewport = this.experience.viewport 15 | 16 | this.setAmbient() 17 | this.setHemi() 18 | this.setPoints() 19 | } 20 | 21 | setAmbient() 22 | { 23 | this.ambient = {} 24 | this.ambient.color = new THREE.Color('white') 25 | this.ambient.intensity = 0 26 | this.ambient.updateUniforms = () => 27 | { 28 | this.renderer.composition.material.uniforms.uAmbientLight.value.color = this.ambient.color 29 | this.renderer.composition.material.uniforms.uAmbientLight.value.intensity = this.ambient.intensity 30 | } 31 | this.ambient.updateUniforms() 32 | 33 | if(this.debug.active) 34 | { 35 | const folder = this.debug.ui.getFolder('lights/ambient') 36 | 37 | folder.addColor(this.ambient, 'color').onChange(this.ambient.updateUniforms) 38 | folder.add(this.ambient, 'intensity').min(0).max(2).step(0.01).onChange(this.ambient.updateUniforms) 39 | } 40 | } 41 | 42 | setHemi() 43 | { 44 | this.hemi = {} 45 | this.hemi.groundColor = new THREE.Color('#3300ff') 46 | this.hemi.skyColor = new THREE.Color('#ff6600') 47 | this.hemi.intensity = 0.4 48 | this.hemi.direction = new THREE.Vector3(-0.2, 0.2, 0.09) 49 | this.hemi.updateUniforms = () => 50 | { 51 | this.renderer.composition.material.uniforms.uHemiLight.value.groundColor = this.hemi.groundColor 52 | this.renderer.composition.material.uniforms.uHemiLight.value.skyColor = this.hemi.skyColor 53 | this.renderer.composition.material.uniforms.uHemiLight.value.intensity = this.hemi.intensity 54 | this.renderer.composition.material.uniforms.uHemiLight.value.direction = this.hemi.direction 55 | } 56 | this.hemi.updateUniforms() 57 | 58 | if(this.debug.active) 59 | { 60 | const folder = this.debug.ui.getFolder('lights/hemi') 61 | 62 | folder.addColor(this.hemi, 'groundColor').onChange(this.hemi.updateUniforms) 63 | folder.addColor(this.hemi, 'skyColor').onChange(this.hemi.updateUniforms) 64 | folder.add(this.hemi, 'intensity').min(0).max(2).step(0.01).onChange(this.hemi.updateUniforms) 65 | folder.add(this.hemi.direction, 'x').min(-1).max(1).step(0.01).onChange(this.hemi.updateUniforms) 66 | folder.add(this.hemi.direction, 'y').min(-1).max(1).step(0.01).onChange(this.hemi.updateUniforms) 67 | folder.add(this.hemi.direction, 'z').min(-1).max(1).step(0.01).onChange(this.hemi.updateUniforms) 68 | } 69 | } 70 | 71 | setPoints() 72 | { 73 | this.points = {} 74 | this.points.max = 100 75 | this.points.items = [] 76 | this.points.needsUpdate = false 77 | this.points.geometry = new THREE.IcosahedronGeometry(1, 1) 78 | this.points.commonUniforms = { 79 | uResolution: { value: new THREE.Vector2(this.viewport.elementWidth * this.viewport.clampedPixelRatio, this.viewport.elementHeight * this.viewport.clampedPixelRatio) }, 80 | uViewPosition: { value: new THREE.Vector3(this.camera.instance.position.x, this.camera.instance.position.y, this.camera.instance.position.z) } 81 | } 82 | // this.points.material = new PointLightMaterial(this.renderer.composition.renderTarget) 83 | 84 | this.points.create = (_parameters = {}) => 85 | { 86 | const point = {} 87 | 88 | // Position 89 | if(typeof _parameters.position === 'undefined' || !(_parameters.position instanceof THREE.Vector3)) 90 | point.position = new THREE.Vector3() 91 | else 92 | point.position = _parameters.position 93 | 94 | // Color 95 | if(typeof _parameters.color === 'undefined') 96 | point.color = new THREE.Color(0xffffff) 97 | else if(_parameters.color instanceof THREE.Color) 98 | { 99 | point.color = _parameters.color 100 | } 101 | else 102 | { 103 | point.color = new THREE.Color(_parameters.color) 104 | } 105 | 106 | // Intensity 107 | if(typeof _parameters.intensity === 'number') 108 | point.intensity = _parameters.intensity 109 | else 110 | point.intensity = 3 111 | 112 | // Amplitude 113 | if(typeof _parameters.amplitude === 'number') 114 | point.amplitude = _parameters.amplitude 115 | else 116 | point.amplitude = 5 117 | 118 | // Concentration 119 | if(typeof _parameters.concentration === 'number') 120 | point.concentration = _parameters.concentration 121 | else 122 | point.concentration = 5 123 | 124 | // Sphere 125 | point.sphere = new THREE.Mesh( 126 | this.points.geometry, 127 | new PointLightMaterial(this.renderer.deferred.renderTarget) 128 | // new THREE.MeshBasicMaterial({ color: 'red' }) 129 | ) 130 | point.sphere.scale.set(point.amplitude, point.amplitude, point.amplitude) 131 | point.sphere.material.uniforms.uPointLight.value = point 132 | point.sphere.material.uniforms.uResolution = this.points.commonUniforms.uResolution 133 | point.sphere.material.uniforms.uViewPosition = this.points.commonUniforms.uViewPosition 134 | this.scenes.forward.add(point.sphere) 135 | 136 | this.points.items.push(point) 137 | 138 | // Update 139 | this.points.needsUpdate = true 140 | 141 | // Return 142 | return point 143 | } 144 | 145 | this.points.updateUniforms = () => 146 | { 147 | // // Count 148 | // this.renderer.composition.material.uniforms.uPointLightsCount.value = this.points.items.length 149 | 150 | // // Lights 151 | // const uPointLights = [...this.points.items] 152 | 153 | // const dummyLight = { 154 | // position: new THREE.Vector3(0, 0, 0), 155 | // color: new THREE.Color(), 156 | // intensity: 0, 157 | // amplitude: 0, 158 | // concentration: 0 159 | // } 160 | 161 | // // Fill with dummy lights 162 | // for(let i = this.points.items.length; i < this.points.max; i++) 163 | // uPointLights.push(dummyLight) 164 | // this.renderer.composition.material.uniforms.uPointLights.value = uPointLights 165 | 166 | // // Max changed 167 | // if(this.points.max !== this.renderer.composition.material.defines.MAX_LIGHTS) 168 | // { 169 | // this.renderer.composition.material.defines.MAX_LIGHTS = this.points.max 170 | // this.renderer.composition.material.needsUpdate = true 171 | // } 172 | } 173 | } 174 | 175 | resize() 176 | { 177 | this.points.commonUniforms.uResolution.value.set(this.viewport.elementWidth * this.viewport.clampedPixelRatio, this.viewport.elementHeight * this.viewport.clampedPixelRatio) 178 | } 179 | 180 | update() 181 | { 182 | if(this.points.needsUpdate) 183 | { 184 | this.points.needsUpdate = false 185 | this.points.updateUniforms() 186 | } 187 | 188 | this.points.commonUniforms.uViewPosition.value.copy(this.camera.instance.position) 189 | for(const _point of this.points.items) 190 | { 191 | _point.sphere.position.copy(_point.position) 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /sources/Experience/Materials/BlurMaterial.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import vertexShader from '../shaders/blur/vertex.glsl' 4 | import fragmentShader from '../shaders/blur/fragment.glsl' 5 | 6 | export default function(_renderTarget, _blurFunction = 0) 7 | { 8 | const uniforms = {} 9 | const defines = {} 10 | 11 | // Buffers 12 | uniforms.uColor = { value: typeof _renderTarget.texture === 'array' ? _renderTarget.texture[0] : _renderTarget.texture } 13 | 14 | // Resolution 15 | uniforms.uResolution = { value: new THREE.Vector2(1280, 1024) } 16 | 17 | // Direction 18 | uniforms.uDirection = { value: new THREE.Vector2(1, 0) } 19 | 20 | // Direction 21 | uniforms.uThreshold = { value: 1 } 22 | 23 | defines.BLUR_FUNCTION = _blurFunction 24 | 25 | // Final material 26 | const material = new THREE.RawShaderMaterial({ 27 | glslVersion: THREE.GLSL3, 28 | depthWrite: false, 29 | depthTest: false, 30 | // transparent: true, 31 | uniforms, 32 | defines, 33 | vertexShader, 34 | fragmentShader 35 | } ) 36 | 37 | return material 38 | } -------------------------------------------------------------------------------- /sources/Experience/Materials/CompositionMaterial.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import vertexShader from '../shaders/composition/vertex.glsl' 4 | import fragmentShader from '../shaders/composition/fragment.glsl' 5 | 6 | export default function(_deferredRenderTarget, _bloomRenderTarget, debug = false) 7 | { 8 | const uniforms = {} 9 | const defines = {} 10 | 11 | // Buffers 12 | uniforms.uColor = { value: _deferredRenderTarget.texture[0] } 13 | uniforms.uPosition = { value: _deferredRenderTarget.texture[1] } 14 | uniforms.uNormal = { value: _deferredRenderTarget.texture[2] } 15 | uniforms.uSpecular = { value: _deferredRenderTarget.texture[3] } 16 | uniforms.uBloom = { value: _bloomRenderTarget.texture } 17 | 18 | // Ambient light 19 | uniforms.uAmbientLight = { 20 | value: 21 | { 22 | color: new THREE.Color('white'), 23 | intensity: 1 24 | } 25 | } 26 | 27 | // Hemi light 28 | uniforms.uHemiLight = { 29 | value: 30 | { 31 | groundColor: new THREE.Color('green'), 32 | skyColor: new THREE.Color('orange'), 33 | intensity: 1, 34 | direction: new THREE.Vector3(1.0, 1.0, 1.0) 35 | } 36 | } 37 | 38 | // // Point lights 39 | // uniforms.uPointLights = { 40 | // value: 41 | // [ 42 | // { 43 | // position: new THREE.Vector3(1, 0.1, - 2), 44 | // color: new THREE.Color('orange'), 45 | // intensity: 3, 46 | // amplitude: 5, 47 | // concentration: 5 48 | // }, 49 | // { 50 | // position: new THREE.Vector3(- 2, 0.1, - 2), 51 | // color: new THREE.Color('cyan'), 52 | // intensity: 3, 53 | // amplitude: 5, 54 | // concentration: 5 55 | // }, 56 | // { 57 | // position: new THREE.Vector3(- 1.5, 0.1, 2), 58 | // color: new THREE.Color('red'), 59 | // intensity: 3, 60 | // amplitude: 5, 61 | // concentration: 5 62 | // } 63 | // ] 64 | // } 65 | // uniforms.uPointLightsCount = { value: 3 } 66 | // defines.MAX_LIGHTS = 3 67 | 68 | // View 69 | uniforms.uViewPosition = { value: new THREE.Vector3(5, 5, -5) } 70 | 71 | // Debug 72 | if(debug) 73 | defines.USE_DEBUG = '' 74 | 75 | // Final material 76 | const material = new THREE.RawShaderMaterial({ 77 | glslVersion: THREE.GLSL3, 78 | depthWrite: false, 79 | depthTest: false, 80 | // transparent: true, 81 | uniforms, 82 | defines, 83 | vertexShader, 84 | fragmentShader 85 | } ) 86 | 87 | return material 88 | } -------------------------------------------------------------------------------- /sources/Experience/Materials/DefaultMaterial.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import vertexShader from '../shaders/default/vertex.glsl' 4 | import fragmentShader from '../shaders/default/fragment.glsl' 5 | 6 | export default function(_parameters = {}) 7 | { 8 | const uniforms = {} 9 | const defines = {} 10 | 11 | // Color 12 | const color = typeof _parameters.color === 'undefined' ? new THREE.Color(0xffffff) : (_parameters.color instanceof THREE.Color ? _parameters.color : new THREE.Color(_parameters.color)) 13 | uniforms.uColor = { value: color } 14 | 15 | // Map color 16 | if(typeof _parameters.mapColor !== 'undefined') 17 | { 18 | defines.USE_MAPCOLOR = '' 19 | 20 | uniforms.uMapColor = { value: _parameters.mapColor } 21 | } 22 | 23 | // Specular 24 | const specular = typeof _parameters.specular === 'undefined' ? (typeof _parameters.mapSpecular !== 'undefined' ? 1 : 0) : _parameters.specular 25 | uniforms.uSpecular = { value: specular } 26 | 27 | // Shininess 28 | const shininess = typeof _parameters.shininess === 'undefined' ? 32 : _parameters.shininess 29 | uniforms.uShininess = { value: shininess } 30 | 31 | // Map specular 32 | if(typeof _parameters.mapSpecular !== 'undefined') 33 | { 34 | defines.USE_MAPSPECULAR = '' 35 | 36 | uniforms.uMapSpecular = { value: _parameters.mapSpecular } 37 | } 38 | 39 | // Map normal 40 | if(typeof _parameters.mapNormal !== 'undefined') 41 | { 42 | defines.USE_MAPNORMAL = '' 43 | 44 | uniforms.uMapNormal = { value: _parameters.mapNormal } 45 | 46 | const mapNormalMultiplier = typeof _parameters.mapNormalMultiplier === 'undefined' ? 1 : _parameters.mapNormalMultiplier 47 | uniforms.uMapNormalMultiplier = { value: mapNormalMultiplier } 48 | } 49 | 50 | // Final material 51 | const material = new THREE.RawShaderMaterial({ 52 | glslVersion: THREE.GLSL3, 53 | // transparent: true, 54 | // depthTest: false, 55 | uniforms, 56 | defines, 57 | vertexShader, 58 | fragmentShader 59 | }) 60 | 61 | return material 62 | } -------------------------------------------------------------------------------- /sources/Experience/Materials/FinalMaterial.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import vertexShader from '../shaders/final/vertex.glsl' 4 | import fragmentShader from '../shaders/final/fragment.glsl' 5 | 6 | export default function(_renderTarget) 7 | { 8 | const uniforms = {} 9 | const defines = {} 10 | 11 | // Buffers 12 | uniforms.uDiffuse = { value: _renderTarget.texture } 13 | 14 | // Final material 15 | const material = new THREE.RawShaderMaterial({ 16 | glslVersion: THREE.GLSL3, 17 | depthWrite: false, 18 | depthTest: false, 19 | // transparent: true, 20 | uniforms, 21 | defines, 22 | vertexShader, 23 | fragmentShader 24 | } ) 25 | 26 | return material 27 | } -------------------------------------------------------------------------------- /sources/Experience/Materials/GlowMaterial.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import vertexShader from '../shaders/glow/vertex.glsl' 4 | import fragmentShader from '../shaders/glow/fragment.glsl' 5 | 6 | export default function(_parameters = {}) 7 | { 8 | const uniforms = {} 9 | const defines = {} 10 | 11 | // Color 12 | const color = typeof _parameters.color === 'undefined' ? new THREE.Color(0xffffff) : (_parameters.color instanceof THREE.Color ? _parameters.color : new THREE.Color(_parameters.color)) 13 | uniforms.uColor = { value: color } 14 | 15 | // Map color 16 | if(typeof _parameters.mapColor !== 'undefined') 17 | { 18 | defines.USE_MAPCOLOR = '' 19 | 20 | uniforms.uMapColor = { value: _parameters.mapColor } 21 | } 22 | 23 | // Intensity 24 | const intensity = typeof _parameters.intensity === 'undefined' ? 1 : _parameters.intensity 25 | uniforms.uIntensity = { value: intensity } 26 | 27 | // Final material 28 | const material = new THREE.RawShaderMaterial({ 29 | glslVersion: THREE.GLSL3, 30 | // transparent: true, 31 | // depthTest: false, 32 | uniforms, 33 | defines, 34 | vertexShader, 35 | fragmentShader 36 | }) 37 | 38 | return material 39 | } -------------------------------------------------------------------------------- /sources/Experience/Materials/PointLightMaterial.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import vertexShader from '../shaders/pointLight/vertex.glsl' 4 | import fragmentShader from '../shaders/pointLight/fragment.glsl' 5 | 6 | export default function(_renderTarget) 7 | { 8 | const uniforms = {} 9 | const defines = {} 10 | 11 | // Buffers 12 | uniforms.uColor = { value: _renderTarget.texture[0] } 13 | uniforms.uPosition = { value: _renderTarget.texture[1] } 14 | uniforms.uNormal = { value: _renderTarget.texture[2] } 15 | uniforms.uSpecular = { value: _renderTarget.texture[3] } 16 | 17 | // Point lights 18 | uniforms.uPointLight = { 19 | value: 20 | { 21 | position: new THREE.Vector3(1, 0.1, - 2), 22 | color: new THREE.Color('orange'), 23 | intensity: 3, 24 | amplitude: 5, 25 | concentration: 5 26 | } 27 | } 28 | 29 | // View 30 | uniforms.uViewPosition = { value: new THREE.Vector3(5, 5, -5) } 31 | uniforms.uResolution = { value: new THREE.Vector2(1280, 1024) } 32 | 33 | // Final material 34 | const material = new THREE.RawShaderMaterial({ 35 | glslVersion: THREE.GLSL3, 36 | depthWrite: false, 37 | depthTest: false, 38 | side: THREE.BackSide, 39 | depthFunc: THREE.GreaterDepth, 40 | blending: THREE.AdditiveBlending, 41 | // transparent: true, 42 | uniforms, 43 | defines, 44 | vertexShader, 45 | fragmentShader 46 | } ) 47 | 48 | return material 49 | } -------------------------------------------------------------------------------- /sources/Experience/Renderer.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import Experience from '@/Experience.js' 4 | import CompositionMaterial from './Materials/CompositionMaterial.js' 5 | import BlurMaterial from './Materials/BlurMaterial.js' 6 | import FinalMaterial from './Materials/FinalMaterial.js' 7 | 8 | export default class Renderer 9 | { 10 | constructor(_options = {}) 11 | { 12 | this.experience = Experience.instance 13 | this.scenes = this.experience.scenes 14 | this.rendererInstance = this.experience.rendererInstance 15 | this.domElement = this.experience.domElement 16 | this.viewport = this.experience.viewport 17 | this.debug = this.experience.debug 18 | this.time = this.experience.time 19 | this.camera = this.experience.camera 20 | 21 | this.setInstance() 22 | this.setDeferred() 23 | this.setBloom() 24 | this.setComposition() 25 | this.setFinal() 26 | } 27 | 28 | setInstance() 29 | { 30 | this.clearColor = '#000000' 31 | 32 | // Renderer 33 | this.instance = this.rendererInstance 34 | this.instance.sortObjects = false 35 | 36 | this.instance.domElement.style.position = 'absolute' 37 | this.instance.domElement.style.top = 0 38 | this.instance.domElement.style.left = 0 39 | this.instance.domElement.style.width = '100%' 40 | this.instance.domElement.style.height = '100%' 41 | 42 | this.instance.setClearColor(this.clearColor, 0) 43 | this.instance.setClearAlpha(0) 44 | this.instance.setSize(this.viewport.elementWidth, this.viewport.elementHeight) 45 | this.instance.setPixelRatio(this.viewport.clampedPixelRatio) 46 | 47 | this.context = this.instance.getContext() 48 | 49 | this.domElement.appendChild(this.instance.domElement) 50 | 51 | // Add stats panel 52 | if(this.debug.stats) 53 | { 54 | this.debug.stats.setRenderPanel(this.context) 55 | } 56 | 57 | // Debug 58 | if(this.debug.active) 59 | { 60 | const folder = this.debug.ui.getFolder('renderer') 61 | // folder.open() 62 | 63 | folder 64 | .addColor(this, 'clearColor') 65 | .name('clearColor') 66 | .onChange(() => 67 | { 68 | this.instance.setClearColor(this.clearColor) 69 | }) 70 | } 71 | } 72 | 73 | setDeferred() 74 | { 75 | this.deferred = {} 76 | 77 | this.deferred.depthTexture = new THREE.DepthTexture(this.viewport.elementWidth, this.viewport.elementHeight) 78 | this.deferred.renderTarget = new THREE.WebGLMultipleRenderTargets( 79 | this.viewport.elementWidth, 80 | this.viewport.elementHeight, 81 | 4, 82 | { 83 | minFilter: THREE.NearestFilter, 84 | magFilter: THREE.NearestFilter, 85 | // generateMipmaps: false, 86 | // encoding: THREE.sRGBEncoding 87 | } 88 | ) 89 | 90 | this.deferred.renderTarget.depthTexture = this.deferred.depthTexture 91 | 92 | this.deferred.renderTarget.texture[0].name = 'position' 93 | this.deferred.renderTarget.texture[0].type = THREE.FloatType 94 | 95 | this.deferred.renderTarget.texture[1].name = 'color' 96 | this.deferred.renderTarget.texture[1].type = THREE.FloatType 97 | 98 | this.deferred.renderTarget.texture[2].name = 'normal' 99 | this.deferred.renderTarget.texture[2].type = THREE.FloatType 100 | 101 | this.deferred.renderTarget.texture[3].name = 'specular' 102 | this.deferred.renderTarget.texture[3].type = THREE.UnsignedByteType 103 | this.deferred.renderTarget.texture[3].format = THREE.RGFormat 104 | } 105 | 106 | setBloom() 107 | { 108 | this.bloom = {} 109 | this.bloom.debug = true 110 | this.bloom.distance = 3 111 | this.bloom.blurFunction = 2 112 | this.bloom.iterations = 3 113 | 114 | // Render targets 115 | this.bloom.renderTargetA = new THREE.WebGLRenderTarget( 116 | this.viewport.elementWidth, 117 | this.viewport.elementHeight, 118 | { 119 | minFilter: THREE.NearestFilter, 120 | magFilter: THREE.NearestFilter, 121 | type: THREE.FloatType 122 | } 123 | ) 124 | 125 | this.bloom.renderTargetB = this.bloom.renderTargetA.clone() 126 | 127 | // Scene 128 | this.bloom.material = new BlurMaterial(this.deferred.renderTarget, this.bloom.blurFunction) 129 | this.bloom.material.uniforms.uResolution.value.set(this.viewport.elementWidth * this.viewport.clampedPixelRatio, this.viewport.elementHeight * this.viewport.clampedPixelRatio) 130 | this.bloom.plane = new THREE.Mesh( 131 | new THREE.PlaneGeometry(2, 2), 132 | this.bloom.material 133 | ) 134 | this.bloom.plane.frustumCulled = false 135 | this.bloom.scene = new THREE.Scene() 136 | this.bloom.scene.add(this.bloom.plane) 137 | 138 | // Debug 139 | if(this.debug.active) 140 | { 141 | const folder = this.debug.ui.getFolder('renderer/bloom') 142 | folder.open() 143 | 144 | folder.add(this.bloom, 'distance').min(0).max(10).step(0.01) 145 | folder 146 | .add(this.bloom, 'blurFunction').min(0).max(2).step(1) 147 | .onChange(() => 148 | { 149 | this.bloom.material.defines.BLUR_FUNCTION = this.bloom.blurFunction 150 | this.bloom.material.needsUpdate = true 151 | }) 152 | folder.add(this.bloom, 'iterations').min(1).max(10).step(1) 153 | } 154 | } 155 | 156 | setComposition() 157 | { 158 | this.composition = {} 159 | this.composition.debug = false 160 | 161 | // Render targets 162 | this.composition.renderTarget = new THREE.WebGLRenderTarget( 163 | this.viewport.elementWidth, 164 | this.viewport.elementHeight, 165 | { 166 | minFilter: THREE.NearestFilter, 167 | magFilter: THREE.NearestFilter, 168 | type: THREE.FloatType, 169 | // generateMipmaps: false, 170 | // encoding: THREE.sRGBEncoding 171 | } 172 | ) 173 | this.composition.renderTarget.depthTexture = this.deferred.depthTexture 174 | 175 | // Scene 176 | this.composition.material = new CompositionMaterial(this.deferred.renderTarget, this.bloom.renderTargetA, this.composition.debug) 177 | this.composition.plane = new THREE.Mesh( 178 | new THREE.PlaneGeometry(2, 2), 179 | this.composition.material 180 | ) 181 | this.composition.plane.frustumCulled = false 182 | this.composition.scene = new THREE.Scene() 183 | this.composition.scene.add(this.composition.plane) 184 | 185 | // Debug 186 | if(this.debug.active) 187 | { 188 | const folder = this.debug.ui.getFolder('renderer/composition') 189 | // folder.open() 190 | 191 | folder 192 | .add(this.composition, 'debug') 193 | .onChange(() => 194 | { 195 | if(this.composition.debug) 196 | this.composition.material.defines.USE_DEBUG = '' 197 | else 198 | delete this.composition.material.defines.USE_DEBUG 199 | 200 | this.composition.material.needsUpdate = true 201 | }) 202 | } 203 | } 204 | 205 | setFinal() 206 | { 207 | this.final = {} 208 | this.final.material = new FinalMaterial(this.composition.renderTarget) 209 | this.final.plane = new THREE.Mesh( 210 | new THREE.PlaneGeometry(2, 2), 211 | this.final.material 212 | ) 213 | this.final.plane.frustumCulled = false 214 | this.final.scene = new THREE.Scene() 215 | this.final.scene.add(this.final.plane) 216 | } 217 | 218 | resize() 219 | { 220 | const bounding = this.domElement.getBoundingClientRect() 221 | this.viewport.elementWidth = bounding.width 222 | this.viewport.elementHeight = bounding.height 223 | 224 | // Instance 225 | this.instance.setSize(this.viewport.elementWidth, this.viewport.elementHeight) 226 | this.instance.setPixelRatio(this.viewport.clampedPixelRatio) 227 | 228 | // Bloom 229 | this.bloom.material.uniforms.uResolution.value.set(this.viewport.elementWidth * this.viewport.clampedPixelRatio, this.viewport.elementHeight * this.viewport.clampedPixelRatio) 230 | 231 | // Composition 232 | this.composition.renderTarget.setSize(this.viewport.elementWidth * this.viewport.clampedPixelRatio, this.viewport.elementHeight * this.viewport.clampedPixelRatio) 233 | 234 | // Final 235 | this.deferred.renderTarget.setSize(this.viewport.elementWidth * this.viewport.clampedPixelRatio, this.viewport.elementHeight * this.viewport.clampedPixelRatio) 236 | } 237 | 238 | update() 239 | { 240 | // Stats 241 | if(this.debug.stats) 242 | this.debug.stats.beforeRender() 243 | 244 | // Deferred render 245 | this.instance.setRenderTarget(this.deferred.renderTarget) 246 | this.instance.autoClear = true 247 | this.instance.render(this.scenes.deferred, this.camera.instance) 248 | 249 | // Bloom 250 | for(let i = 0; i < this.bloom.iterations; i++) 251 | { 252 | const distance = this.bloom.distance * Math.pow((i + 1) / (this.bloom.iterations), 2) 253 | // console.log(distance) 254 | 255 | this.bloom.material.uniforms.uColor.value = i === 0 ? this.deferred.renderTarget.texture[0] : this.bloom.renderTargetA.texture 256 | this.bloom.material.uniforms.uDirection.value.set(distance, 0) 257 | this.bloom.material.uniforms.uThreshold.value = i === 0 ? 1 : 0 258 | this.instance.setRenderTarget(this.bloom.renderTargetB) 259 | this.instance.render(this.bloom.scene, this.camera.instance) 260 | 261 | this.bloom.material.uniforms.uColor.value = this.bloom.renderTargetB.texture 262 | this.bloom.material.uniforms.uDirection.value.set(0, distance) 263 | this.bloom.material.uniforms.uThreshold.value = 0 264 | this.instance.setRenderTarget(this.bloom.renderTargetA) 265 | this.instance.render(this.bloom.scene, this.camera.instance) 266 | } 267 | 268 | // Composition render 269 | this.composition.material.uniforms.uViewPosition.value.copy(this.camera.instance.position) 270 | this.instance.setRenderTarget(this.composition.renderTarget) 271 | this.instance.autoClear = false 272 | this.instance.render(this.composition.scene, this.camera.instance) 273 | 274 | // Forward render 275 | this.instance.autoClear = false 276 | this.instance.render(this.scenes.forward, this.camera.instance) 277 | 278 | // Final render 279 | this.instance.setRenderTarget(null) 280 | this.instance.autoClear = true 281 | this.instance.render(this.final.scene, this.camera.instance) 282 | 283 | // Stats 284 | if(this.debug.stats) 285 | this.debug.stats.afterRender() 286 | } 287 | 288 | destroy() 289 | { 290 | this.instance.renderLists.dispose() 291 | this.instance.dispose() 292 | this.experienceTarget.dispose() 293 | } 294 | } -------------------------------------------------------------------------------- /sources/Experience/Resources.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | 3 | import EventEmitter from '@/EventEmitter.js' 4 | import Loader from '@/Utils/Loader.js' 5 | 6 | export default class Resources extends EventEmitter 7 | { 8 | constructor(_rendererInstance, _assets) 9 | { 10 | super() 11 | 12 | // Items (will contain every resources) 13 | this.items = {} 14 | 15 | // Loader 16 | this.loader = new Loader(_rendererInstance) 17 | 18 | this.groups = {} 19 | this.groups.assets = [..._assets] 20 | this.groups.loaded = [] 21 | this.groups.current = null 22 | this.loadNextGroup() 23 | 24 | // Loader file end event 25 | this.loader.on('fileEnd', (_resource, _data) => 26 | { 27 | let data = _data 28 | 29 | // Convert to texture 30 | if(_resource.type === 'texture') 31 | { 32 | if(!(data instanceof THREE.Texture)) 33 | { 34 | data = new THREE.Texture(_data) 35 | } 36 | data.needsUpdate = true 37 | } 38 | 39 | this.items[_resource.name] = data 40 | this.groups.current.items[_resource.name] = data 41 | 42 | // Progress and event 43 | this.groups.current.loaded++ 44 | this.trigger('progress', [this.groups.current, _resource, data]) 45 | }) 46 | 47 | // Loader all end event 48 | this.loader.on('end', () => 49 | { 50 | this.groups.loaded.push(this.groups.current) 51 | 52 | // Trigger 53 | this.trigger('groupEnd', [this.groups.current]) 54 | 55 | if(this.groups.assets.length > 0) 56 | { 57 | this.loadNextGroup() 58 | } 59 | else 60 | { 61 | this.trigger('end') 62 | } 63 | }) 64 | } 65 | 66 | loadNextGroup() 67 | { 68 | this.groups.current = this.groups.assets.shift() 69 | this.groups.current.toLoad = this.groups.current.itemsToLoad.length 70 | this.groups.current.loaded = 0 71 | this.groups.current.items = {} 72 | 73 | this.loader.load(this.groups.current.itemsToLoad) 74 | } 75 | 76 | createInstancedMeshes(_children, _groups) 77 | { 78 | // Groups 79 | const groups = [] 80 | 81 | for(const _group of _groups) 82 | { 83 | groups.push({ 84 | name: _group.name, 85 | regex: _group.regex, 86 | meshesGroups: [], 87 | instancedMeshes: [] 88 | }) 89 | } 90 | 91 | // Result 92 | const result = {} 93 | 94 | for(const _group of groups) 95 | { 96 | result[_group.name] = _group.instancedMeshes 97 | } 98 | 99 | return result 100 | } 101 | 102 | destroy() 103 | { 104 | for(const _itemKey in this.items) 105 | { 106 | const item = this.items[_itemKey] 107 | if(item instanceof THREE.Texture) 108 | { 109 | item.dispose() 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /sources/Experience/Time.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from '@/EventEmitter.js' 2 | 3 | export default class Time extends EventEmitter 4 | { 5 | /** 6 | * Constructor 7 | */ 8 | constructor() 9 | { 10 | super() 11 | 12 | this.start = Date.now() / 1000 13 | this.current = this.start 14 | this.elapsed = 0 15 | this.delta = 16 / 1000 16 | this.playing = true 17 | 18 | this.tick = this.tick.bind(this) 19 | this.tick() 20 | } 21 | 22 | play() 23 | { 24 | this.playing = true 25 | } 26 | 27 | pause() 28 | { 29 | this.playing = false 30 | } 31 | 32 | /** 33 | * Tick 34 | */ 35 | tick() 36 | { 37 | this.ticker = window.requestAnimationFrame(this.tick) 38 | 39 | const current = Date.now() / 1000 40 | 41 | this.delta = current - this.current 42 | this.elapsed += this.playing ? this.delta : 0 43 | this.current = current 44 | 45 | if(this.delta > 60 / 1000) 46 | { 47 | this.delta = 60 / 1000 48 | } 49 | 50 | if(this.playing) 51 | { 52 | this.trigger('tick') 53 | } 54 | } 55 | 56 | /** 57 | * Stop 58 | */ 59 | stop() 60 | { 61 | window.cancelAnimationFrame(this.ticker) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sources/Experience/Utils/Loader.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from '@/EventEmitter.js' 2 | import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' 3 | import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js' 4 | import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' 5 | import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js' 6 | import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js' 7 | import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js' 8 | 9 | export default class Resources extends EventEmitter 10 | { 11 | /** 12 | * Constructor 13 | */ 14 | constructor(_rendererInstance) 15 | { 16 | super() 17 | 18 | this.rendererInstance = _rendererInstance 19 | 20 | this.setLoaders() 21 | 22 | this.toLoad = 0 23 | this.loaded = 0 24 | this.items = {} 25 | } 26 | 27 | /** 28 | * Set loaders 29 | */ 30 | setLoaders() 31 | { 32 | this.loaders = [] 33 | 34 | // Images 35 | this.loaders.push({ 36 | extensions: ['jpg', 'png'], 37 | action: (_resource) => 38 | { 39 | const image = new Image() 40 | 41 | image.addEventListener('load', () => 42 | { 43 | this.fileLoadEnd(_resource, image) 44 | }) 45 | 46 | image.addEventListener('error', () => 47 | { 48 | this.fileLoadEnd(_resource, image) 49 | }) 50 | 51 | image.src = _resource.source 52 | } 53 | }) 54 | 55 | // // Basis images 56 | // const ktx2Loader = new KTX2Loader() 57 | // ktx2Loader.setTranscoderPath('basis/') 58 | // ktx2Loader.detectSupport(this.rendererInstance) 59 | 60 | // this.loaders.push({ 61 | // extensions: ['basis', 'ktx2'], 62 | // action: (_resource) => 63 | // { 64 | // ktx2Loader.load(_resource.source, (_data) => 65 | // { 66 | // console.log(_data) 67 | // this.fileLoadEnd(_resource, _data) 68 | // }) 69 | // } 70 | // }) 71 | 72 | // Draco 73 | const dracoLoader = new DRACOLoader() 74 | dracoLoader.setDecoderPath('draco/') 75 | dracoLoader.setDecoderConfig({ type: 'js' }) 76 | 77 | this.loaders.push({ 78 | extensions: ['drc'], 79 | action: (_resource) => 80 | { 81 | dracoLoader.load(_resource.source, (_data) => 82 | { 83 | this.fileLoadEnd(_resource, _data) 84 | 85 | DRACOLoader.releaseDecoderModule() 86 | }) 87 | } 88 | }) 89 | 90 | // GLTF 91 | const gltfLoader = new GLTFLoader() 92 | gltfLoader.setDRACOLoader(dracoLoader) 93 | 94 | this.loaders.push({ 95 | extensions: ['glb', 'gltf'], 96 | action: (_resource) => 97 | { 98 | gltfLoader.load(_resource.source, (_data) => 99 | { 100 | this.fileLoadEnd(_resource, _data) 101 | }) 102 | } 103 | }) 104 | 105 | // FBX 106 | const fbxLoader = new FBXLoader() 107 | 108 | this.loaders.push({ 109 | extensions: ['fbx'], 110 | action: (_resource) => 111 | { 112 | fbxLoader.load(_resource.source, (_data) => 113 | { 114 | this.fileLoadEnd(_resource, _data) 115 | }) 116 | } 117 | }) 118 | 119 | // RGBE | HDR 120 | const rgbeLoader = new RGBELoader() 121 | 122 | this.loaders.push({ 123 | extensions: ['hdr'], 124 | action: (_resource) => 125 | { 126 | rgbeLoader.load(_resource.source, (_data) => 127 | { 128 | this.fileLoadEnd(_resource, _data) 129 | }) 130 | } 131 | }) 132 | 133 | // EXR 134 | const exrLoader = new EXRLoader() 135 | 136 | this.loaders.push({ 137 | extensions: ['exr'], 138 | action: (_resource) => 139 | { 140 | exrLoader.load(_resource.source, (_data) => 141 | { 142 | this.fileLoadEnd(_resource, _data) 143 | }) 144 | } 145 | }) 146 | } 147 | 148 | /** 149 | * Load 150 | */ 151 | load(_resources = []) 152 | { 153 | for(const _resource of _resources) 154 | { 155 | this.toLoad++ 156 | const extensionMatch = _resource.source.match(/\.([a-z0-9]+)$/) 157 | 158 | if(typeof extensionMatch[1] !== 'undefined') 159 | { 160 | const extension = extensionMatch[1] 161 | const loader = this.loaders.find((_loader) => _loader.extensions.find((_extension) => _extension === extension)) 162 | 163 | if(loader) 164 | { 165 | loader.action(_resource) 166 | } 167 | else 168 | { 169 | console.warn(`Cannot found loader for ${_resource}`) 170 | } 171 | } 172 | else 173 | { 174 | console.warn(`Cannot found extension of ${_resource}`) 175 | } 176 | } 177 | } 178 | 179 | /** 180 | * File load end 181 | */ 182 | fileLoadEnd(_resource, _data) 183 | { 184 | this.loaded++ 185 | this.items[_resource.name] = _data 186 | 187 | this.trigger('fileEnd', [_resource, _data]) 188 | 189 | if(this.loaded === this.toLoad) 190 | { 191 | this.trigger('end') 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /sources/Experience/Utils/MathUtils.js: -------------------------------------------------------------------------------- 1 | export default class MathUtils 2 | { 3 | distance(aX, aY, bX, bY) 4 | { 5 | return Math.hypot(aX - bX, aY - bY) 6 | } 7 | } -------------------------------------------------------------------------------- /sources/Experience/Viewport.js: -------------------------------------------------------------------------------- 1 | export default class Viewport 2 | { 3 | constructor(_options) 4 | { 5 | this.domElement = _options.domElement 6 | this.width = null 7 | this.height = null 8 | this.smallestSide = null 9 | this.biggestSide = null 10 | this.pixelRatio = null 11 | this.clampedPixelRatio = null 12 | this.vertical = null 13 | 14 | const bounding = this.domElement.getBoundingClientRect() 15 | this.elementWidth = bounding.width 16 | this.elementHeight = bounding.height 17 | 18 | this.resize() 19 | } 20 | 21 | resize() 22 | { 23 | this.width = window.innerWidth 24 | this.height = window.innerHeight 25 | this.smallestSide = this.width < this.height ? this.width : this.height 26 | this.biggestSide = this.width > this.height ? this.width : this.height 27 | this.pixelRatio = window.devicePixelRatio 28 | this.clampedPixelRatio = Math.min(this.pixelRatio, 1) 29 | this.vertical = this.width / this.height < 0.8 30 | 31 | if(this.vertical) 32 | document.documentElement.classList.add('is-vertical') 33 | else 34 | document.documentElement.classList.remove('is-vertical') 35 | 36 | const bounding = this.domElement.getBoundingClientRect() 37 | this.elementWidth = bounding.width 38 | this.elementHeight = bounding.height 39 | } 40 | } -------------------------------------------------------------------------------- /sources/Experience/World.js: -------------------------------------------------------------------------------- 1 | import Experience from '@/Experience.js' 2 | import DefaultMaterial from '@/Materials/DefaultMaterial.js' 3 | import GlowMaterial from '@/Materials/GlowMaterial.js' 4 | import * as THREE from 'three' 5 | import Lights from './Lights' 6 | 7 | export default class World 8 | { 9 | constructor() 10 | { 11 | this.experience = new Experience() 12 | this.renderer = this.experience.renderer 13 | this.resources = this.experience.resources 14 | this.scenes = this.experience.scenes 15 | this.debug = this.experience.debug 16 | this.time = this.experience.time 17 | 18 | this.setLights() 19 | this.setFloor() 20 | this.setCube() 21 | this.setTorusKnot() 22 | this.setSphere() 23 | } 24 | 25 | setLights() 26 | { 27 | this.lights = new Lights() 28 | 29 | this.pointLights = [] 30 | 31 | for(let i = 0; i < 60; i++) 32 | { 33 | const point = {} 34 | 35 | const color = `hsl(${Math.random() * 360}, 100%, 60%)` 36 | 37 | point.light = this.lights.points.create({ 38 | position: new THREE.Vector3(0, 0.01 + Math.random() * 0.5, 0), 39 | color, 40 | amplitude: 2, 41 | intensity: 5, 42 | concentration: 5 43 | }) 44 | 45 | point.angle = Math.random() * Math.PI * 2 46 | point.distance = (1 - Math.pow(1 - Math.random(), 2)) * 5 47 | point.speed = Math.random() * 1 48 | point.timeOffset = Math.random() * Math.PI * 2 49 | 50 | point.sphere = new THREE.Mesh( 51 | new THREE.IcosahedronGeometry(0.02, 1), 52 | new GlowMaterial({ color: color, intensity: 5 }) 53 | ) 54 | this.scenes.deferred.add(point.sphere) 55 | 56 | this.pointLights.push(point) 57 | } 58 | 59 | this.mainLight = {} 60 | this.mainLight.color = '#ff8833' 61 | this.mainLight.intensity = 10 62 | this.mainLight.position = new THREE.Vector3(0, 0.5, 0) 63 | this.mainLight.light = this.lights.points.create({ 64 | position: new THREE.Vector3(0, 0.5, 0), 65 | color: this.mainLight.color, 66 | amplitude: 5, 67 | intensity: this.mainLight.intensity, 68 | concentration: 2 69 | }) 70 | 71 | this.mainLight.sphere = new THREE.Mesh( 72 | new THREE.IcosahedronGeometry(0.25, 3), 73 | new GlowMaterial({ color: this.mainLight.color, intensity: this.mainLight.intensity }) 74 | ) 75 | this.scenes.deferred.add(this.mainLight.sphere) 76 | 77 | 78 | if(this.debug.active) 79 | { 80 | const folder = this.debug.ui.getFolder('world/mainLight') 81 | 82 | folder 83 | .addColor(this.mainLight, 'color') 84 | .onChange(() => 85 | { 86 | this.mainLight.sphere.material.uniforms.uColor.value.set(this.mainLight.color) 87 | this.mainLight.light.color.set(this.mainLight.color) 88 | }) 89 | 90 | folder 91 | .add(this.mainLight, 'intensity').min(1).max(50).step(0.1) 92 | .onChange(() => 93 | { 94 | this.mainLight.sphere.material.uniforms.uIntensity.value = this.mainLight.intensity 95 | this.mainLight.light.intensity = this.mainLight.intensity 96 | }) 97 | // folder.add(this.floor.material.uniforms.uShininess, 'value').min(0).max(256).step(1).name('shininess') 98 | // folder.add(this.floor.material.uniforms.uMapNormalMultiplier, 'value').min(0).max(2).step(0.001).name('mapNormalMultiplier') 99 | } 100 | } 101 | 102 | setFloor() 103 | { 104 | this.floor = {} 105 | this.resources.items.groundColor.encoding = THREE.sRGBEncoding 106 | this.floor.geometry = new THREE.PlaneGeometry(10, 10) 107 | this.floor.geometry.computeTangents() 108 | this.floor.material = new DefaultMaterial({ 109 | shininess: 32, 110 | // color: 'red', 111 | mapColor: this.resources.items.groundColor, 112 | specular: 1, 113 | mapSpecular: this.resources.items.groundSpecular, 114 | mapNormal: this.resources.items.groundNormal, 115 | mapNormalMultiplier: 1 116 | }) 117 | this.floor.mesh = new THREE.Mesh(this.floor.geometry, this.floor.material) 118 | this.floor.mesh.rotation.x = - Math.PI * 0.5 119 | this.scenes.deferred.add(this.floor.mesh) 120 | 121 | if(this.debug.active) 122 | { 123 | const folder = this.debug.ui.getFolder('world/floor') 124 | 125 | folder.add(this.floor.material.uniforms.uSpecular, 'value').min(0).max(1).step(0.001).name('specular') 126 | folder.add(this.floor.material.uniforms.uShininess, 'value').min(0).max(256).step(1).name('shininess') 127 | folder.add(this.floor.material.uniforms.uMapNormalMultiplier, 'value').min(0).max(2).step(0.001).name('mapNormalMultiplier') 128 | } 129 | } 130 | 131 | setCube() 132 | { 133 | this.cube = {} 134 | this.cube.geometry = new THREE.BoxGeometry(1, 1, 1) 135 | this.cube.geometry.computeTangents() 136 | this.cube.material = new DefaultMaterial({ 137 | specular: 0.25, 138 | shininess: 64, 139 | mapColor: this.resources.items.bricksColor, 140 | mapSpecular: this.resources.items.bricksSpecular, 141 | mapNormal: this.resources.items.bricksNormal 142 | }) 143 | this.cube.mesh = new THREE.Mesh(this.cube.geometry, this.cube.material) 144 | this.cube.mesh.position.y = 0.5 145 | this.scenes.deferred.add(this.cube.mesh) 146 | 147 | if(this.debug.active) 148 | { 149 | const folder = this.debug.ui.getFolder('world/cube') 150 | 151 | folder.add(this.cube.material.uniforms.uSpecular, 'value').min(0).max(1).step(0.001).name('specular') 152 | folder.add(this.cube.material.uniforms.uShininess, 'value').min(0).max(256).step(1).name('shininess') 153 | folder.addColor(this.cube.material.uniforms.uColor, 'value').name('color') 154 | } 155 | } 156 | 157 | setTorusKnot() 158 | { 159 | this.torusKnot = {} 160 | this.torusKnot.geometry = new THREE.TorusKnotGeometry(0.5, 0.22, 128, 32) 161 | this.torusKnot.geometry.computeTangents() 162 | this.torusKnot.material = new DefaultMaterial({ 163 | specular: 1, 164 | shininess: 256, 165 | // color: new THREE.Color('#ffffff') 166 | }) 167 | this.torusKnot.mesh = new THREE.Mesh(this.torusKnot.geometry, this.torusKnot.material) 168 | this.torusKnot.mesh.position.y = 0.5 169 | this.torusKnot.mesh.position.x = 2 170 | this.scenes.deferred.add(this.torusKnot.mesh) 171 | 172 | if(this.debug.active) 173 | { 174 | const folder = this.debug.ui.getFolder('world/torusKnot') 175 | 176 | folder.add(this.torusKnot.material.uniforms.uSpecular, 'value').min(0).max(1).step(0.001).name('specular') 177 | folder.add(this.torusKnot.material.uniforms.uShininess, 'value').min(0).max(256).step(1).name('shininess') 178 | folder.addColor(this.torusKnot.material.uniforms.uColor, 'value').name('color') 179 | } 180 | } 181 | 182 | setSphere() 183 | { 184 | this.sphere = {} 185 | this.sphere.geometry = new THREE.SphereGeometry(0.75, 32, 32) 186 | this.sphere.geometry.computeTangents() 187 | this.sphere.material = new DefaultMaterial({ 188 | // color: '#ff6666', 189 | // intensity: 2, 190 | specular: 0.25, 191 | shininess: 128, 192 | mapColor: this.resources.items.woodColor, 193 | mapSpecular: this.resources.items.woodSpecular, 194 | mapNormal: this.resources.items.woodNormal 195 | }) 196 | this.sphere.mesh = new THREE.Mesh(this.sphere.geometry, this.sphere.material) 197 | this.sphere.mesh.position.y = 0.5 198 | this.sphere.mesh.position.x = -2 199 | this.scenes.deferred.add(this.sphere.mesh) 200 | } 201 | 202 | resize() 203 | { 204 | this.lights.resize() 205 | } 206 | 207 | update() 208 | { 209 | this.lights.update() 210 | 211 | for(const _point of this.pointLights) 212 | { 213 | _point.angle = _point.timeOffset + this.time.elapsed * 0.4 * _point.speed 214 | _point.light.position.x = Math.sin(_point.angle) * _point.distance 215 | _point.light.position.z = Math.cos(_point.angle) * _point.distance 216 | _point.light.position.y = Math.sin(_point.timeOffset + this.time.elapsed * 2) * 0.5 + 0.51 217 | 218 | _point.sphere.position.copy(_point.light.position) 219 | } 220 | 221 | this.mainLight.position.x = Math.sin(this.time.elapsed * 0.2) * 3.5 222 | this.mainLight.position.z = Math.cos(this.time.elapsed * 0.2) * 3.5 223 | 224 | this.mainLight.light.position.copy(this.mainLight.position) 225 | this.mainLight.sphere.position.copy(this.mainLight.position) 226 | } 227 | } -------------------------------------------------------------------------------- /sources/Experience/assets.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | name: 'test', 4 | itemsToLoad: 5 | [ 6 | { name: 'groundColor', source: 'textures/ground2Color.jpg', type: 'texture' }, 7 | { name: 'groundNormal', source: 'textures/ground2Normal.jpg', type: 'texture' }, 8 | { name: 'groundSpecular', source: 'textures/ground2Specular.jpg', type: 'texture' }, 9 | 10 | { name: 'bricksColor', source: 'textures/bricksColor.jpg', type: 'texture' }, 11 | { name: 'bricksNormal', source: 'textures/bricksNormal.jpg', type: 'texture' }, 12 | { name: 'bricksSpecular', source: 'textures/bricksSpecular.jpg', type: 'texture' }, 13 | 14 | { name: 'woodColor', source: 'textures/woodColor.jpg', type: 'texture' }, 15 | { name: 'woodNormal', source: 'textures/woodNormal.jpg', type: 'texture' }, 16 | { name: 'woodSpecular', source: 'textures/woodSpecular.jpg', type: 'texture' }, 17 | 18 | { name: 'leatherColor', source: 'textures/leatherColor.jpg', type: 'texture' }, 19 | { name: 'leatherNormal', source: 'textures/leatherNormal.jpg', type: 'texture' }, 20 | { name: 'leatherSpecular', source: 'textures/leatherSpecular.jpg', type: 'texture' } 21 | ] 22 | } 23 | ] -------------------------------------------------------------------------------- /sources/Experience/shaders/blur/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | in vec2 vUv; 5 | 6 | uniform sampler2D uColor; 7 | uniform vec2 uResolution; 8 | uniform vec2 uDirection; 9 | uniform float uThreshold; 10 | 11 | layout(location = 0) out vec4 pc_FragColor; 12 | 13 | #if (BLUR_FUNCTION == 0) 14 | vec4 blur5(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) 15 | { 16 | vec4 color = vec4(0.0); 17 | vec2 off1 = vec2(1.3333333333333333) * direction; 18 | color += texture(image, uv) * 0.29411764705882354; 19 | color += texture(image, uv + (off1 / resolution)) * 0.35294117647058826; 20 | color += texture(image, uv - (off1 / resolution)) * 0.35294117647058826; 21 | return color; 22 | } 23 | #endif 24 | 25 | #if (BLUR_FUNCTION == 1) 26 | vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) 27 | { 28 | vec4 color = vec4(0.0); 29 | vec2 off1 = vec2(1.3846153846) * direction; 30 | vec2 off2 = vec2(3.2307692308) * direction; 31 | color += texture(image, uv) * 0.2270270270; 32 | color += texture(image, uv + (off1 / resolution)) * 0.3162162162; 33 | color += texture(image, uv - (off1 / resolution)) * 0.3162162162; 34 | color += texture(image, uv + (off2 / resolution)) * 0.0702702703; 35 | color += texture(image, uv - (off2 / resolution)) * 0.0702702703; 36 | return color; 37 | } 38 | #endif 39 | 40 | #if (BLUR_FUNCTION == 2) 41 | vec4 blur13(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) 42 | { 43 | vec4 color = vec4(0.0); 44 | vec2 off1 = vec2(1.411764705882353) * direction; 45 | vec2 off2 = vec2(3.2941176470588234) * direction; 46 | vec2 off3 = vec2(5.176470588235294) * direction; 47 | color += texture(image, uv) * 0.1964825501511404; 48 | color += texture(image, uv + (off1 / resolution)) * 0.2969069646728344; 49 | color += texture(image, uv - (off1 / resolution)) * 0.2969069646728344; 50 | color += texture(image, uv + (off2 / resolution)) * 0.09447039785044732; 51 | color += texture(image, uv - (off2 / resolution)) * 0.09447039785044732; 52 | color += texture(image, uv + (off3 / resolution)) * 0.010381362401148057; 53 | color += texture(image, uv - (off3 / resolution)) * 0.010381362401148057; 54 | return color; 55 | } 56 | #endif 57 | 58 | void main() 59 | { 60 | vec3 color = vec3(0.0); 61 | 62 | // Buffers 63 | #if (BLUR_FUNCTION == 0) 64 | color = blur5(uColor, vUv, uResolution, uDirection).rgb - uThreshold; 65 | #elif (BLUR_FUNCTION == 1) 66 | color = blur9(uColor, vUv, uResolution, uDirection).rgb - uThreshold; 67 | #elif (BLUR_FUNCTION == 2) 68 | color = blur13(uColor, vUv, uResolution, uDirection).rgb - uThreshold; 69 | #endif 70 | 71 | color = max(vec3(0.0), color); 72 | 73 | pc_FragColor = vec4(color, 1.0); 74 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/blur/vertex.glsl: -------------------------------------------------------------------------------- 1 | in vec3 position; 2 | in vec2 uv; 3 | 4 | out vec2 vUv; 5 | 6 | void main() 7 | { 8 | vUv = uv; 9 | gl_Position = vec4(position, 1.0); 10 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/composition/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | struct AmbientLight { 5 | vec3 color; 6 | float intensity; 7 | }; 8 | 9 | struct HemiLight { 10 | vec3 groundColor; 11 | vec3 skyColor; 12 | float intensity; 13 | vec3 direction; 14 | }; 15 | 16 | // struct PointLight { 17 | // vec3 position; 18 | // vec3 color; 19 | // float intensity; 20 | // float amplitude; 21 | // float concentration; 22 | // }; 23 | 24 | in vec2 vUv; 25 | 26 | uniform sampler2D uColor; 27 | uniform sampler2D uPosition; 28 | uniform sampler2D uNormal; 29 | uniform sampler2D uSpecular; 30 | uniform sampler2D uBloom; 31 | uniform AmbientLight uAmbientLight; 32 | uniform HemiLight uHemiLight; 33 | uniform vec3 uViewPosition; 34 | 35 | // #if (MAX_LIGHTS > 0) 36 | // uniform int uPointLightsCount; 37 | // uniform PointLight uPointLights[MAX_LIGHTS]; 38 | // #endif 39 | 40 | layout(location = 0) out vec4 pc_FragColor; 41 | 42 | float inverseLerp(float v, float minValue, float maxValue) 43 | { 44 | return (v - minValue) / (maxValue - minValue); 45 | } 46 | 47 | float remap(float v, float inMin, float inMax, float outMin, float outMax) 48 | { 49 | float t = inverseLerp(v, inMin, inMax); 50 | return mix(outMin, outMax, t); 51 | } 52 | 53 | float blendAdd(float base, float blend) 54 | { 55 | return min(base+blend,1.0); 56 | } 57 | 58 | vec3 blendAdd(vec3 base, vec3 blend) 59 | { 60 | return min(base+blend,vec3(1.0)); 61 | } 62 | 63 | vec3 blendAdd(vec3 base, vec3 blend, float opacity) 64 | { 65 | return (blendAdd(base, blend) * opacity + base * (1.0 - opacity)); 66 | } 67 | 68 | void main() 69 | { 70 | // Buffers 71 | vec3 position = texture(uPosition, vUv).rgb; 72 | vec3 color = texture(uColor, vUv).rgb; 73 | vec3 normal = texture(uNormal, vUv).rgb; 74 | vec2 specularShininess = texture(uSpecular, vUv).rg; 75 | float specular = specularShininess.r; 76 | float shininess = specularShininess.g; 77 | vec3 bloom = texture(uBloom, vUv).rgb; 78 | 79 | vec3 viewDirection = normalize(uViewPosition - position); 80 | 81 | /** 82 | * Lights 83 | */ 84 | vec3 light; 85 | vec3 specularLight = vec3(0.0); 86 | 87 | // Ambient 88 | vec3 ambientLightColor = uAmbientLight.color * uAmbientLight.intensity; 89 | 90 | // Hemi 91 | vec3 hemiLightDirection = normalize(uHemiLight.direction); 92 | float hemiLightMix = remap(dot(hemiLightDirection, normal), -1.0, 1.0, 0.0, 1.0); 93 | vec3 hemiLightColor = mix(uHemiLight.groundColor, uHemiLight.skyColor, hemiLightMix) * uHemiLight.intensity; 94 | 95 | light = ambientLightColor + hemiLightColor; 96 | vec3 outColor = color * light; 97 | 98 | // outColor += max(vec3(0.0), color - 1.0); 99 | 100 | // // Points 101 | // #if (MAX_LIGHTS > 0) 102 | // for(int i = 0; i < uPointLightsCount; ++i) 103 | // { 104 | // vec3 light = vec3(0.0); 105 | // vec3 specularLight = vec3(0.0); 106 | 107 | // float lightDistance = distance(position, uPointLights[i].position); 108 | 109 | // float lightIntensity = 1.0 - clamp(inverseLerp(lightDistance, 0.0, uPointLights[i].amplitude), 0.0, 1.0); 110 | // lightIntensity = pow(lightIntensity, uPointLights[i].concentration); 111 | // lightIntensity *= uPointLights[i].intensity; 112 | 113 | // vec3 lightDirection = normalize(uPointLights[i].position - position); 114 | 115 | // light += max(dot(normal, lightDirection), 0.0) * lightIntensity * uPointLights[i].color; 116 | 117 | // vec3 reflection = normalize(reflect(- lightDirection, normal)); 118 | // float specularIntensity = max(0.0, dot(viewDirection, reflection)); 119 | // specularIntensity = pow(specularIntensity, 1.0 + shininess * 256.0 * specular); 120 | // specularIntensity *= lightIntensity; 121 | // specularLight += specularIntensity * uPointLights[i].color * specular; 122 | 123 | // vec3 temp = color * light + specularLight; 124 | // // temp = pow(temp, vec3(1.0 / 2.2)); 125 | // outColor += temp; 126 | // } 127 | // #endif 128 | 129 | // Bloom 130 | outColor.rgb = blendAdd(outColor.rgb, bloom.rgb); 131 | 132 | /** 133 | * Final color 134 | */ 135 | 136 | // // Gamma corection 137 | // outColor.rgb = pow(outColor.rgb, vec3(1.0 / 2.2)); 138 | 139 | // Debug 140 | #ifdef USE_DEBUG 141 | outColor.rgb = mix(outColor.rgb, color, step(0.5, 1.0 - vUv.y)); 142 | outColor.rgb = mix(outColor.rgb, position, step(0.25, vUv.x) * step(0.5, 1.0 - vUv.y)); 143 | outColor.rgb = mix(outColor.rgb, normal, step(0.5, vUv.x) * step(0.5, 1.0 - vUv.y)); 144 | outColor.rgb = mix(outColor.rgb, vec3(specularShininess, 0.0), step(0.75, vUv.x) * step(0.5, 1.0 - vUv.y)); 145 | #endif 146 | 147 | pc_FragColor = vec4(outColor, 1.0); 148 | // pc_FragColor = vec4(bloom.rgb, 1.0); 149 | // pc_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 150 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/composition/vertex.glsl: -------------------------------------------------------------------------------- 1 | in vec3 position; 2 | in vec2 uv; 3 | 4 | out vec2 vUv; 5 | 6 | void main() 7 | { 8 | vUv = uv; 9 | gl_Position = vec4(position, 1.0); 10 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/default/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | layout(location = 0) out vec4 outColor; 5 | layout(location = 1) out vec4 outPosition; 6 | layout(location = 2) out vec4 outNormal; 7 | layout(location = 3) out vec2 outSpecular; 8 | 9 | #ifdef USE_MAPCOLOR 10 | uniform sampler2D uMapColor; 11 | #endif 12 | 13 | #ifdef USE_MAPSPECULAR 14 | uniform sampler2D uMapSpecular; 15 | #endif 16 | 17 | in vec3 vNormal; 18 | #ifdef USE_MAPNORMAL 19 | uniform sampler2D uMapNormal; 20 | uniform float uMapNormalMultiplier; 21 | in mat3 vTBN; 22 | #endif 23 | 24 | uniform vec3 uColor; 25 | uniform float uSpecular; 26 | uniform float uShininess; 27 | 28 | in vec3 vPosition; 29 | in vec2 vUv; 30 | 31 | void main() 32 | { 33 | // Position 34 | outPosition = vec4(vPosition, 1.0); 35 | 36 | // Color 37 | outColor = vec4(uColor, 1.0); 38 | 39 | #ifdef USE_MAPCOLOR 40 | outColor *= texture(uMapColor, vUv); 41 | #endif 42 | 43 | // Specular 44 | outSpecular = vec2(uSpecular, uShininess / 256.0); 45 | 46 | #ifdef USE_MAPSPECULAR 47 | outSpecular.r *= texture(uMapSpecular, vUv).r; 48 | #endif 49 | 50 | // Normal 51 | #ifdef USE_MAPNORMAL 52 | outNormal.rgb = texture(uMapNormal, vUv).rgb * 2.0 - 1.0; 53 | outNormal.rgb = normalize(vTBN * outNormal.rgb); 54 | outNormal.rgb = mix(vNormal.rgb, outNormal.rgb, uMapNormalMultiplier); 55 | // outNormal.rgb = normalize(outNormal.rgb); 56 | #else 57 | outNormal = vec4(normalize(vNormal), 0.0); 58 | #endif 59 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/default/vertex.glsl: -------------------------------------------------------------------------------- 1 | in vec3 position; 2 | in vec3 normal; 3 | in vec3 tangent; 4 | in vec2 uv; 5 | 6 | out vec3 vPosition; 7 | out vec3 vNormal; 8 | out vec2 vUv; 9 | 10 | #ifdef USE_MAPNORMAL 11 | out mat3 vTBN; 12 | #endif 13 | 14 | uniform mat4 modelMatrix; 15 | uniform mat4 viewMatrix; 16 | uniform mat4 projectionMatrix; 17 | uniform mat3 normalMatrix; 18 | 19 | void main() 20 | { 21 | // Position 22 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 23 | gl_Position = projectionMatrix * viewMatrix * modelPosition; 24 | vPosition = modelPosition.xyz; 25 | 26 | // Normal 27 | vec4 modelNormal = modelMatrix * vec4(normal, 0.0); 28 | vNormal = modelNormal.xyz; 29 | 30 | #ifdef USE_MAPNORMAL 31 | // vec3 bitangent = cross(normal, tangent); 32 | vec3 T = normalize(vec3(modelMatrix * vec4(tangent, 0.0))); 33 | vec3 N = normalize(vec3(modelMatrix * vec4(normal, 0.0))); 34 | T = normalize(T - dot(T, N) * N); 35 | vec3 B = cross(N, T); 36 | mat3 TBN = mat3(T, B, N); 37 | vTBN = TBN; 38 | #endif 39 | 40 | // UV 41 | vUv = uv; 42 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/final/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | in vec2 vUv; 5 | 6 | uniform sampler2D uDiffuse; 7 | 8 | layout(location = 0) out vec4 pc_FragColor; 9 | 10 | void main() 11 | { 12 | pc_FragColor = texture(uDiffuse, vUv); 13 | 14 | // Gamma corection 15 | pc_FragColor.rgb = pow(pc_FragColor.rgb, vec3(1.0 / 2.2)); 16 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/final/vertex.glsl: -------------------------------------------------------------------------------- 1 | in vec3 position; 2 | in vec2 uv; 3 | 4 | out vec2 vUv; 5 | 6 | void main() 7 | { 8 | vUv = uv; 9 | gl_Position = vec4(position, 1.0); 10 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/glow/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | layout(location = 0) out vec4 outColor; 5 | layout(location = 1) out vec4 outPosition; 6 | layout(location = 2) out vec4 outNormal; 7 | layout(location = 3) out vec2 outSpecular; 8 | 9 | #ifdef USE_MAPCOLOR 10 | uniform sampler2D uMapColor; 11 | #endif 12 | 13 | uniform vec3 uColor; 14 | uniform float uIntensity; 15 | 16 | in vec3 vPosition; 17 | in vec2 vUv; 18 | 19 | void main() 20 | { 21 | // Position 22 | outPosition = vec4(vPosition, 1.0); 23 | 24 | // Color 25 | outColor = vec4(uColor, 1.0) * uIntensity; 26 | 27 | #ifdef USE_MAPCOLOR 28 | outColor *= texture(uMapColor, vUv); 29 | #endif 30 | 31 | // Specular 32 | outSpecular = vec2(0.0, 0.0); 33 | 34 | // Normal 35 | outNormal = vec4(0.0); 36 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/glow/vertex.glsl: -------------------------------------------------------------------------------- 1 | in vec3 position; 2 | in vec3 normal; 3 | in vec3 tangent; 4 | in vec2 uv; 5 | 6 | out vec3 vPosition; 7 | out vec2 vUv; 8 | 9 | uniform mat4 modelMatrix; 10 | uniform mat4 viewMatrix; 11 | uniform mat4 projectionMatrix; 12 | uniform mat3 normalMatrix; 13 | 14 | void main() 15 | { 16 | // Position 17 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 18 | gl_Position = projectionMatrix * viewMatrix * modelPosition; 19 | vPosition = modelPosition.xyz; 20 | 21 | // UV 22 | vUv = uv; 23 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/pointLight/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | struct PointLight { 5 | vec3 position; 6 | vec3 color; 7 | float intensity; 8 | float amplitude; 9 | float concentration; 10 | }; 11 | 12 | uniform sampler2D uPosition; 13 | uniform sampler2D uColor; 14 | uniform sampler2D uNormal; 15 | uniform sampler2D uSpecular; 16 | uniform vec3 uViewPosition; 17 | uniform vec2 uResolution; 18 | 19 | uniform PointLight uPointLight; 20 | 21 | layout(location = 0) out vec4 pc_FragColor; 22 | 23 | float inverseLerp(float v, float minValue, float maxValue) 24 | { 25 | return (v - minValue) / (maxValue - minValue); 26 | } 27 | 28 | float remap(float v, float inMin, float inMax, float outMin, float outMax) 29 | { 30 | float t = inverseLerp(v, inMin, inMax); 31 | return mix(outMin, outMax, t); 32 | } 33 | 34 | void main() 35 | { 36 | vec2 uv = gl_FragCoord.xy / uResolution; 37 | 38 | // Buffers 39 | vec3 position = texture(uPosition, uv).rgb; 40 | vec3 color = texture(uColor, uv).rgb; 41 | vec3 normal = texture(uNormal, uv).rgb; 42 | 43 | vec2 specularShininess = texture(uSpecular, uv).rg; 44 | float specular = specularShininess.r; 45 | float shininess = specularShininess.g; 46 | 47 | vec3 viewDirection = normalize(uViewPosition - position); 48 | 49 | /** 50 | * Lights 51 | */ 52 | vec3 light; 53 | vec3 specularLight = vec3(0.0); 54 | 55 | // Points 56 | float lightDistance = distance(position, uPointLight.position); 57 | 58 | float lightIntensity = 1.0 - clamp(inverseLerp(lightDistance, 0.0, uPointLight.amplitude), 0.0, 1.0); 59 | lightIntensity = pow(lightIntensity, uPointLight.concentration); 60 | lightIntensity *= uPointLight.intensity; 61 | 62 | vec3 lightDirection = normalize(uPointLight.position - position); 63 | 64 | light += max(dot(normal, lightDirection), 0.0) * lightIntensity * uPointLight.color; 65 | 66 | vec3 reflection = normalize(reflect(- lightDirection, normal)); 67 | float specularIntensity = max(0.0, dot(viewDirection, reflection)); 68 | specularIntensity = pow(specularIntensity, 1.0 + shininess * 256.0 * specular); 69 | specularIntensity *= lightIntensity; 70 | specularLight += specularIntensity * uPointLight.color * specular; 71 | 72 | /** 73 | * Final color 74 | */ 75 | vec3 outColor = color * light + specularLight; 76 | 77 | pc_FragColor = vec4(outColor, 1.0); 78 | // pc_FragColor = vec4(0.0); 79 | // pc_FragColor = vec4(texture(uColor, uv).rgb, 1.0); 80 | } -------------------------------------------------------------------------------- /sources/Experience/shaders/pointLight/vertex.glsl: -------------------------------------------------------------------------------- 1 | in vec3 position; 2 | in vec2 uv; 3 | 4 | // out vec2 vUv; 5 | 6 | uniform mat4 projectionMatrix; 7 | uniform mat4 modelViewMatrix; 8 | 9 | void main() 10 | { 11 | // vUv = uv; 12 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 13 | } -------------------------------------------------------------------------------- /sources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | WebGL (Three.js) Deferred Rendering 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /sources/index.js: -------------------------------------------------------------------------------- 1 | import Experience from '@/Experience.js' 2 | 3 | window.experience = new Experience({ 4 | domElement: document.querySelector('.experience') 5 | }) -------------------------------------------------------------------------------- /sources/style/main.styl: -------------------------------------------------------------------------------- 1 | .experience 2 | position fixed 3 | top 0 4 | left 0 5 | width 100vw 6 | height 100vh -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import glsl from 'vite-plugin-glsl'; 2 | import { defineConfig } from 'vite' 3 | import path from 'path' 4 | 5 | const dirname = path.resolve() 6 | 7 | export default defineConfig({ 8 | root: 'sources', 9 | publicDir: '../public', 10 | build: 11 | { 12 | outDir: '../dist', 13 | emptyOutDir: true, 14 | sourcemap: true 15 | }, 16 | plugins: [glsl()], 17 | resolve: 18 | { 19 | alias: 20 | { 21 | '@' : path.resolve(dirname, './sources/Experience') 22 | } 23 | } 24 | }) --------------------------------------------------------------------------------