Huggingface.js documentation
@huggingface/usd-web-viewer
@huggingface/usd-web-viewer
OpenUSD๋ฅผ ๋ธ๋ผ์ฐ์ ์์: openusd(์์ Rust) ๊ธฐ๋ฐ์ WebAssembly์์ USD ๊ตฌ์ฑ์ ์ฒ๋ฆฌํ๊ณ , three.js๋ก ๋ ๋๋งํฉ๋๋ค. .usd, .usda, .usdc, .usdz ํ์ผ์ ์ฝ์ผ๋ฉฐ, ๋ก๋ฉ์ Web Worker์์ ์คํ๋ฉ๋๋ค.
npm install @huggingface/usd-web-viewer three
์ฌ์ฉ
์ค๋น๋ ๋ทฐ์ด(๋ ๋๋ฌ, ์กฐ๋ช , ์ค๋น ์ปจํธ๋กค):
import { createViewer } from '@huggingface/usd-web-viewer';
const viewer = createViewer(document.getElementById('viewer')); // a container element
const { info } = await viewer.load(
'https://huggingface.co/datasets/Robotiq-Official/simready-assets/resolve/main/Robotiq_2F_85/simready_usd/Robotiq_2F_85.usda',
);๋๋ ์์ฒด three.js ์ฅ๋ฉด ์ ์ถ๊ฐ ํ ์ ๋ ์์ต๋๋ค:
import { loadUsd } from '@huggingface/usd-web-viewer';
const { root, complete, dispose } = await loadUsd(url);
scene.add(root); // a THREE.Group, Y-up, in meters
await complete; // textures stream in after the geometry์ต์
loadUsd(url, options)์ viewer.load(url, options)๋ ๋ค์์ ๋ฐ์ต๋๋ค:
| ์ต์ | ๊ธฐ๋ณธ๊ฐ | |
|---|---|---|
textures | 'preview' | 'none', 'preview' (๊ธฐ๋ณธ ์์, ์์ ๋ฐ์ดํฐ ๋งต, ๋
ธ๋ฉ ๋งต ์์) ๋๋ 'full' |
maxTextureSize | 1024 | ๋์ฝ๋ฉ๋ ํ ์ค์ฒ์ ๊ธด ๋ณ ๊ธธ์ด(ํฝ์ ) |
signal | AbortSignal; ๋ก๋๊ฐ aborted ์ฝ๋์ UsdLoadError๋ก ๊ฑฐ๋ถ๋ฉ๋๋ค | |
onProgress | stage์ 0์์ 1 ์ฌ์ด์ ์ ์ฒด fraction์ ์ธ์๋ก ํธ์ถ๋ฉ๋๋ค | |
files | ๋คํธ์ํฌ ๋์ ๋๋กญํ๊ฑฐ๋ ์ ํํ ํ์ผ์ ๋ก๋ํฉ๋๋ค(์๋ ์ฐธ์กฐ) | |
wasmUrl, workerUrl | ํจํค์ง ์์ | WASM ๋ฐ์ด๋๋ฆฌ์ ์์ปค ์คํฌ๋ฆฝํธ๊ฐ ์๋น๋๋ ์์น |
maxConcurrentFetches | 16 | ๋์์ ์งํ ์ค์ธ ์์ฒญ |
maxLayerBytes, maxLayers | 768 MiB, 1024 | ๋ ์ด์ด ๋ค์ด๋ก๋ ์ ํ |
maxTextureBytes | 512 MiB | ํ ์ค์ฒ ๋ค์ด๋ก๋ ์ ํ |
maxTriangles, maxInstances | 20M, 100,000 | ์ต๋ ๋ช ๊ฐ๊ฐ ๊ทธ๋ ค์ง๋์ง |
createViewer(container, options)๋ background(๊ธฐ๋ณธ๊ฐ์ ํฌ๋ช
), onContextLost, onContextRestored(๋ง์ง๋ง์ผ๋ก ํ์๋ ๋ชจ๋ธ์ ์ฌ๋ก๋ฉ๊ณผ ํจ๊ป ํธ์ถ๋จ)๋ฅผ ๋ฐ์ต๋๋ค.
์คํจ๋ code๊ฐ ํฌํจ๋ UsdLoadError์
๋๋ค(aborted, fetch, compose, worker, webgl). ์ถฉ์คํ ํ์ํ ์ ์์๋ ํญ๋ชฉ์ ๋ชจ๋ info.warnings์ ๋์ด๋ฉ๋๋ค. ๋ชจ๋ ์ต์
, ์ค๋ฅ ๋ฐ ๊ฒฝ๊ณ ๋ ํ์
์ด ์ง์ ๋์ด ์์ต๋๋ค.
์ ๋ขฐํ ์ ์๋ ํ์ผ ๋ก๋
- ์์ฒญ์
<model-viewer>์ ๋์ผํ๊ฒ ์ ์ก๋ฉ๋๋ค: ์ฟ ํค๋ ํ์ด์ง ์์ฒด์ origin(credentials: 'same-origin')์ผ๋ก๋ง ์ ์ก๋๋ฉฐ, ์ปค์คํ ํค๋์ referrer๋ ํฌํจ๋์ง ์์ต๋๋ค. - ๋ ์ด์ด์ ํ ์ค์ฒ๋ http(s)๋ฅผ ํตํด์๋ง ๊ฐ์ ธ์ต๋๋ค.
- Web Worker์์ WebAssembly๋ก ์ปดํ์ผ๋ Rust๋ก ํ์ฑ์ด ์คํ๋ฉ๋๋ค.
- ๊ฐ ๋ก๋์๋ ํ๋๊ฐ ์์ต๋๋ค:
maxLayerBytes(768 MiB),maxLayers(1024),maxTextureBytes(512 MiB),maxTriangles(20M),maxInstances(100,000); ์ด๋ฏธ์ง๋ ํ ๋ณ ์ต๋ 16384 px, ๋ฉด์ ์ต๋ 8192 x 8192 px; ํ๋ฆฌ๋ฏธํฐ๋ธ๋ ์ต๋ 256๋จ๊ณ๊น์ง ์ค์ฒฉ ๊ฐ๋ฅ;.usdzํญ๋ชฉ์ ๊ฐ๊ฐ ์ต๋ 512 MiB, ์ ์ฒด ์ต๋ 1 GiB์ด๋ฉฐ ์์ถ๋์ง ์์ ์ํ๋ก ์ ์ฅ๋ฉ๋๋ค. - ์๋ชป๋ ํ์์ ํ์ผ์
UsdLoadError์ ํจ๊ป ๋ก๋ ์คํจํฉ๋๋ค.
๋ก์ปฌ ํ์ผ
<input type="file" webkitdirectory>๋ฅผ ์ฌ์ฉํ์ฌ ์ ํํ๊ฑฐ๋ ํ์ด์ง์ ๋๋กญํ ํ์ผ์ ํ์ํ๋ ค๋ฉด, ํจํค์ง ๋ด ๊ฒฝ๋ก๋ก ํค๋ฅผ ์ง์ ํ์ฌ files๋ก ์ ๋ฌํ๊ณ ๋ฃจํธ ๋ ์ด์ด์ ํค๋ฅผ ๋ก๋ํ์ธ์. ํ์ผ ๋ด ์๋ ๊ฒฝ๋ก๋ ์๋ก๋ฅผ ๊ธฐ์ค์ผ๋ก ํด์๋๋ฉฐ, ์ด๋ฅผ ์ํด ๋ณ๋๋ก ๊ฐ์ ธ์ค๊ธฐ(fetch)๊ฐ ์ํ๋์ง ์์ต๋๋ค.
const files = new Map([...input.files].map((file) => [file.webkitRelativePath || file.name, file]));
await viewer.load('chair/simready_usd/sm_chair.usd', { files });๋ฒ๋ค๋ฌ
worker์ WASM ๋ฐ์ด๋๋ฆฌ๋ new URL(..., import.meta.url)๋ก ์ฐพ์ผ๋ฉฐ, Vite, webpack ๋ฐ ๊ธฐํ ๋ฒ๋ค๋ฌ๊ฐ ์ด๋ฅผ ํด์ํ๊ณ ์ถ๋ ฅํฉ๋๋ค. Vite ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํด๋น ํจํค์ง๋ฅผ ์์กด์ฑ ์ฌ์ ๋ฒ๋ค๋ง์์ ์ ์ธํ์ธ์:
// vite.config.js
export default { optimizeDeps: { exclude: ['@huggingface/usd-web-viewer'] } };MIT ๋ผ์ด์ ์ค๋ก ๋ฐฐํฌ๋ฉ๋๋ค. WASM ๋ฐ์ด๋๋ฆฌ์ ์ปดํ์ผ๋ Rust ํฌ๋ ์ดํธ์ ๋ผ์ด์ ์ค๋ THIRD_PARTY_LICENSES์ ์์ต๋๋ค.