콘텐츠로 이동

브라우저 지원

이 페이지는 브라우저에서 alpha2를 실행하는 데 필요한 것과 서버가 보내야 하는 것을 정리합니다. 다 읽고 나면 브라우저를 점검하고 호스팅을 설정할 수 있습니다.

  • 브라우저: Chrome 96, Firefox 89, Safari 26 이상. WebAssembly 모듈에는 WebAssembly SIMD와 reference types가 필요하며, 이 둘이 없으면 엔진도, 오디오 워크릿도, 확장 모듈도 불러올 수 없습니다.
  • .wasm을 application/wasm으로 제공. 그렇지 않으면 로더가 더 느린 컴파일 방식으로 대신하고 경고를 남깁니다.
  • 오디오 프리뷰에는 cross-origin isolated 페이지가 필요합니다. 편집, 비디오 프리뷰, export에는 필요하지 않습니다.

아래 패널은 지금 이 문서를 보고 있는 브라우저를 검사하고, 작은 캔버스에서 엔진을 시작해 봅니다.

여러분의 앱에서는 alpha2/robustness의 detectBrowserCapabilities()가 같은 질문에 답합니다. 하드웨어 WebGPU 어댑터, WebGL2, WebCodecs, OffscreenCanvas, WebAssembly 기능이 있는지, 그리고 "auto"가 어떤 렌더러를 고를지(renderer: "gpu" 또는 "cpu") 알려 줍니다. 이 답은 호출한 스레드에서만 유효하며, 워커 호스트는 WorkerRenderBackend.detectCapabilities()로 따로 물어봐야 합니다.

WebEffectRegistry.createForHtmlCanvas(canvas)(워커에서는 OffscreenCanvas와 함께 createForCanvas)는 WebGPU로 렌더링하고, 브라우저에 WebGPU가 없으면 WebGL2로 렌더링합니다. WebGPU 디바이스는 캔버스를 바인딩하기 전에 열기 때문에, 실패해도 캔버스는 다른 컨텍스트에 쓸 수 있는 상태로 남습니다.

둘 다 쓸 수 없을 때(하드웨어 가속을 끈 Chrome, 차단 목록에 오른 GPU 등)는 WebEffectRegistry.createCpu(canvas)로 엔진의 CPU 렌더러를 만듭니다. 호출 방식은 같고, WebAssembly 안에서 단일 스레드로 그린 뒤 프리뷰를 캔버스의 2D 컨텍스트에 올립니다. 네이티브 CPU 렌더러와 정확히 같은 그림을 그리고, 런타임 WGSL 이펙트는 EFFECT_ERROR로 거부하며, export에는 캔버스가 필요하지 않습니다.

import init, { WebEffectRegistry } from "alpha2/wasm";
await init();
let engine;
try {
engine = await WebEffectRegistry.createForHtmlCanvas(canvas, { softwareAdapter: "refuse" });
} catch {
engine = WebEffectRegistry.createCpu(canvas);
}

{ softwareAdapter: "refuse" }는 소프트웨어 어댑터(SwiftShader, llvmpipe, WARP, WebGPU 폴백 어댑터)를 거부하며, 브라우저가 그 밖의 어댑터를 제공하지 않으면 GPU_INIT_FAILED로 실패합니다. alpha2/renderer-choice의 createRenderer(binding, canvas, mode)가 이 선택을 대신해 줍니다. "auto"는 하드웨어 GPU가 있으면 GPU로, 없으면 CPU 렌더러로 그리며, 무엇을 만들었는지 알려 줍니다.

오디오를 위한 cross-origin isolation

섹션 제목: “오디오를 위한 cross-origin isolation”

오디오 프리뷰는 공유 메모리의 링 버퍼를 통해 믹스된 오디오를 AudioWorklet으로 보냅니다. 여기에는 SharedArrayBuffer가 필요하고, 따라서 cross-origin isolated 페이지여야 합니다. 페이지와 함께 다음 두 헤더를 보내세요.

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

alpha2/audio-timeline의 canShareAudioMemory()로 현재 페이지가 조건을 만족하는지 확인할 수 있습니다.

.wasm 파일에는 Content-Type: application/wasm을 보내세요. 패키지에 들어 있는 모듈은 alpha2/wasm/alpha2_wasm_bg.wasm(엔진), alpha2/wasm/alpha2_audio_worklet.wasm(오디오 워크릿), alpha2/wasm/alpha2_extensions_bg.wasm(SVG, 애니메이션 이미지, Lottie, OpenEXR, 이미지 시퀀스용이며 그런 소스가 있을 때만 불러옴)입니다.

init()은 엔진 모듈을 JavaScript 파일 옆에서 불러옵니다. 번들러가 위치를 옮긴다면 URL, Response, 바이트, 또는 컴파일된 WebAssembly.Module을 넘기세요.

await init({ module_or_path: wasmUrl });

이 사이트는 serve로 제공되며, serve.json이 isolation 헤더와 .wasm 타입을 함께 보냅니다.

{
"headers": [
{
"source": "**",
"headers": [
{ "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
{ "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }
]
},
{
"source": "**/*.wasm",
"headers": [{ "key": "Content-Type", "value": "application/wasm" }]
}
]
}

선택 의존성인 mediabunny는 @types/dom-webcodecs 0.1.13을 설치하는데, 이 선언이 TypeScript 5.9의 DOM 라이브러리와 충돌합니다. skipLibCheck로 컴파일하거나, package.json에 "overrides": { "@types/dom-webcodecs": "0.1.19" }를 추가하세요. alpha2/mediabunny를 가져오는 앱은 lib에 "ESNext.Disposable"도 넣어야 합니다.