TrendShift 딥다이브 · 2026-07-03

XR Blocks 딥다이브
— 구글이 만든 "AI + XR 프로토타이핑" 웹 라이브러리

XR Blocks는 구글 XR Labs가 공개한 경량 WebXR + AI 라이브러리다. three.js 위에서, 손 추적·제스처·깊이 인식·공간 UI·Gemini AI를 몇 줄로 켜서 몰입형(XR) 앱을 빠르게 만든다. 핵심은 두 가지 — ① 헤드셋 없이도 브라우저에서 돌아가는 데스크톱 시뮬레이터, ② "AI가 코드를 잘 생성하도록" 설계된 API(이른바 Vibe Coding XR). (저장소: google/xrblocks · Apache-2.0 · TypeScript · ★431 · npm v0.17.0 · TrendShift 월간 뷰 · Hacker News 화제작)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

핵심 메시지

"XR판 게임 엔진 + AI 리모컨" — three.js 위에 손·눈·공간·Gemini를 얹어, 헤드셋 앱을 웹처럼 빠르게 찍어낸다.

VR/AR 앱을 처음부터 만들려면 할 일이 산더미다 — WebXR 세션 열기, 카메라·렌더러 세팅, 매 프레임 루프 돌리기, 손 관절 추적 모델 붙이기, 공간에 뜨는 버튼 UI 만들기, 그리고 AI까지. XR Blocks는 이 "몰입형 앱의 밑작업"을 통째로 대신해 주는 SDK(개발 키트)다.

개발자는 xb.Script라는 클래스 하나를 상속해 "무엇을 보여줄지"만 적고 xb.init()을 부른다. 그러면 엔진이 알아서 렌더링·XR 세션·손 추적·AI를 굴린다. 비유하면 — 유니티(Unity)가 게임 개발에서 해 주는 일을, XR Blocks가 "웹 기반 AI+XR"에서 해 주는 것이다. 게다가 같은 코드가 안드로이드 XR 헤드셋에서도, 그냥 노트북 크롬에서도(시뮬레이터) 돌아간다.

README의 자기소개는 이렇다: "XR Blocks is a lightweight, cross-platform library for rapidly prototyping advanced XR and AI experiences." — "고급 XR·AI 경험을 빠르게 프로토타이핑하기 위한 가볍고 크로스플랫폼인 라이브러리." 여기서 세 단어가 핵심이다: lightweight(무겁지 않게), cross-platform(헤드셋·데스크톱 모두), rapidly prototyping(빠른 시제품).

기반은 three.js(웹에서 3D를 그리는 사실상 표준 라이브러리)다. XR Blocks는 three.js를 "의존 대상(peer dependency)"으로 두고, 그 위에 XR 전용 기능(손·깊이·평면·AI)을 얹는 레이어 역할을 한다. 타깃은 Chrome 136+이고, 삼성 Galaxy XR 같은 안드로이드 XR 기기의 WebXR을 지원한다.

용어
XR · WebXR
XR(eXtended Reality, 확장 현실)은 VR(가상현실)·AR(증강현실)·MR(혼합현실)을 통틀어 부르는 말이다. WebXR은 이 XR을 웹 브라우저에서 직접 구현하도록 브라우저가 제공하는 표준 API다. 앱을 스토어에 올리지 않고 URL 하나로 헤드셋에서 여는 게 가능해진다. XR Blocks는 이 WebXR을 훨씬 쉽게 쓰도록 감싼 도구다.
이 프로젝트의 트레이드마크
"AI가 읽기 좋은 API" — Legible to AI 설계

XR Blocks가 다른 3D 라이브러리와 결정적으로 다른 점은 설계 철학이다. 저자들은 논문에서 XR 앱을 LLM(예: Gemini)으로 "바이브 코딩(vibe coding)"하는 걸 목표로 잡았다. 그래서 API를 일부러 고수준·의미 중심·오용하기 어렵게 설계하고, 모든 공개 함수를 src/xrblocks.ts 한 파일에 모아 뒀다. 저장소가 스스로 밝힌 "AI로 생성한 앱이 깨지는 1순위 원인 = 존재하지 않는 API를 지어내는 것(hallucinated API)"을 줄이려는 정교한 장치다. 코드베이스 안에 AGENTS.md·CONTEXT.md·skills/까지 갖춰 "AI 에이전트가 이 SDK를 헷갈리지 않게" 안내한다.

2왜 주목받는가

구글 XR Labs 공개 · three.js 창시자 참여 · 헤드셋 없는 시뮬레이터 · Gemini Live · "바이브 코딩 XR".

XR Blocks가 트렌딩에 오른 이유는 여러 겹이다. 첫째, "구글 XR Labs가 직접 낸 오픈소스"라는 무게다. 저자 명단에는 three.js를 만든 Ricardo Cabello(mrdoob), 구글 리서치의 David Kim·Ruofei Du 등이 포함돼 있다. 웹 3D 생태계의 원류가 참여한 프로젝트라는 상징성이 크다. 둘째, 삼성 Galaxy XR 출시와 안드로이드 XR 플랫폼이 뜨면서, "웹으로 XR을 만드는 가장 쉬운 길"에 대한 수요가 폭발했다.

맨손 WebXR 개발로는 왜 벅찬가

방식할 수 있는 것한계
순수 WebXR API브라우저에서 XR 세션 직접 제어렌더러·루프·입력·손추적을 전부 직접 배선. 보일러플레이트 지옥
three.js 단독3D 렌더링 + WebXR 헬퍼 약간손 제스처·깊이·평면·AI·공간 UI는 직접 구현해야
네이티브(Unity 등)강력한 XR 툴체인빌드·스토어 배포 무겁고, URL로 바로 열기 불가
XR Blocks손·깊이·AI·UI를 enable*()로 켜기 + 시뮬레이터Chrome 136+ 의존, three.js 지식 필요
비유

맨손 WebXR이 "부품으로 자동차 조립"이라면, XR Blocks는 "시동 걸면 굴러가는 완성차"다. 엔진(렌더 루프)·핸들(입력)·센서(손·깊이)가 이미 연결돼 있고, 운전자는 "어디로 갈지(무엇을 그릴지)"만 정하면 된다. 게다가 실제 도로(헤드셋)가 없어도 시뮬레이터(노트북 크롬)에서 미리 몰아볼 수 있다.

주목도를 끌어올린 구체적 요인은 다음과 같다.

① 헤드셋 없이 개발 — 데스크톱 시뮬레이터. XR 개발의 가장 큰 고통은 "기기가 있어야 테스트된다"는 점이다. XR Blocks는 ?formFactor=desktop만 붙이면 일반 크롬에서 가상 사용자·가상 손·가상 깊이로 앱을 돌린다. 헤드셋을 쓰고 벗는 반복 없이 코드→새로고침으로 개발한다.
② Gemini가 1급 시민. options.enableAI() 한 줄로 Gemini에 연결된다. 단순 질의부터 Gemini Live(실시간 멀티모달 대화), 카메라로 본 물체를 Gemini가 인식하는 object detection까지 XR과 엮인다.
③ CDN 한 줄로 시작. 설치 없이 <script type="importmap">에 jsDelivr URL만 넣으면 브라우저에서 바로 돈다. "빈 HTML 파일 하나로 XR 씬 띄우기"가 가능하다.
④ 학술 백본. arXiv 논문 2편(2509.25504 XR Blocks, 2603.24591 Vibe Coding XR)과 research.google 블로그가 뒷받침한다. 단순 데모가 아니라 "Human-centered AI + XR"이라는 연구 비전의 구현체다.

균형 잡기
"공식 지원 제품이 아님 + 아주 최신 API"

README가 명시한다 — "This is not an officially supported Google product." XR Labs 팀과 외부 협력자가 능동적으로 유지하지만 구글의 공식 SLA는 없고, 오픈소스 보안 포상(VRP) 대상도 아니다. 또 Chrome 136+·안드로이드 XR이라는 최신 환경 의존이 크고, 버전이 v0.17.0으로 아직 1.0 이전이라 API가 바뀔 수 있다. "실험·학습·프로토타입"에는 최고지만, 프로덕션엔 버전 고정과 검증이 필요하다.

3기술 스택 전체 지도

TypeScript + three.js를 축으로, 온디바이스 ML(MediaPipe/LiteRT)·클라우드 AI(Gemini)·물리(Rapier WASM)를 조립.

XR Blocks는 순수 프론트엔드 라이브러리다 — 서버가 없다. 대신 브라우저에서 돌아가는 여러 무거운 기술을 하나의 SDK로 오케스트레이션한다. 언어는 TypeScript(strict)이고, 빌드 결과물은 ESM 번들(build/xrblocks.js) 하나 + 애드온별 번들이다. 무거운 의존성(three, Gemini, MediaPipe, Rapier 등)은 번들에 넣지 않고 external로 빼서, 사용자가 importmap/CDN으로 따로 로드한다.

① 3D 렌더링 코어

영역도구역할
3D 엔진three.js 0.184 (peer)씬 그래프·렌더러·WebXR 헬퍼. XR Blocks의 토대
레이캐스트 가속three-mesh-bvhBVH로 광선-메시 충돌을 빠르게(손가락이 무엇을 가리키나)
공간 텍스트troika-three-textSDF 기반 3D 텍스트 렌더링(공간 UI의 글자)
가우시안 스플랫@sparkjsdev/spark3D Gaussian Splatting 렌더러 — 실사 3D 장면 표현

② 입력 · 온디바이스 ML

영역도구역할
손·시각 추론@mediapipe/tasks-vision손 랜드마크·제스처·객체 인식(브라우저 내 추론)
오디오 추론@mediapipe/tasks-audio오디오 분류 등 온디바이스 오디오 태스크
추론 런타임LiteRT (구 TensorFlow Lite)제스처·깊이 모델을 기기 안에서 로컬 실행
음성 인식Web Speech API@types/dom-speech-recognition — 음성→텍스트

③ AI · 물리 · 공간 UI

영역도구역할
클라우드 AI@google/genai (Gemini)질의·멀티모달·Gemini Live 실시간 세션
AI 호환openaiOpenAI 호환 백엔드도 xb.ai 뒤에 추상화
물리 엔진@dimforge/rapier3d (+simd)Rust로 짠 물리 엔진의 WASM 빌드. 강체·충돌
플렉스 공간 UI@pmndrs/uikituiblocks 애드온의 기반 — 3D 공간의 flexbox 카드
웹 컴포넌트/반응성lit · @preact/signals-coreUI 컴포넌트·신호 기반 상태 관리

④ 빌드 · 개발 · 배포

번들러Rollup 4 — TypeScript·terser·dts·inject·replace 플러그인. ESM + .min.js + .d.ts + 애드온 동시 출력
테스트Vitest 4 (+ jsdom, coverage-v8). 테스트는 소스 옆 *.test.ts로 병치
린트/포맷ESLint 9 flat config (+ eslint-plugin-tsdoc) · Prettier. 빌드는 경고에도 실패(--failAfterWarnings)
로컬 서빙http-server + concurrently (npm run dev = 워치 빌드 + :8080 서버)
배포npm 패키지(xrblocks) + jsDelivr CDN(importmap). bundlephobia로 용량 추적
원격 제어bin xrblocks-remote-controlws(WebSocket) 릴레이 서버. 자동화/외부 원격 실행용
설계 통찰
"온디바이스는 로컬, AI만 클라우드" — 프라이버시 경계선

기술 스택이 두 세계로 갈린다. 손 추적·제스처·깊이 인식은 LiteRT/MediaPipe로 기기 안에서 처리돼 데이터가 밖으로 안 나간다. 반면 Gemini Live/Flash 같은 AI 기능은 구글 서버로 데이터를 전송한다. README가 이 경계를 명확히 문서화하고, API 키를 클라이언트에 심지 말라(프로덕션은 서버 프록시 필수)고 반복 경고한다. "센서는 로컬, 지능은 클라우드"라는 현대 온디바이스 AI 앱의 전형적 구도다.

4아키텍처 심화 분석

싱글턴 엔진(Core) + 스크립트 생명주기(Script) + 옵션 스위치(Options). 유니티 MonoBehaviour를 웹으로.

XR Blocks의 심장은 "하나의 싱글턴 엔진 + 스크립트 생명주기" 패턴이다. 게임 엔진을 써 봤다면 익숙하다 — 유니티의 MonoBehaviour처럼, 개발자는 xb.Script를 상속해 init()·update() 같은 생명주기 훅만 채우고, 엔진이 나머지(렌더 루프·XR 세션·입력)를 굴린다.

개발자가 쓰는 코드 xb.add(new MainScript()) ← 내 Script 등록 xb.init(new xb.Options()) ← 엔진 부팅 │ ▼ ┌───────────────────────────────────────────────────────────┐ │ Core (싱글턴, = xb.core) src/core/Core.ts │ │ · renderer / camera / WebXR 세션 생성 │ │ · 매 프레임 루프 소유 (requestAnimationFrame) │ │ · DI Registry(의존성 주입 레지스트리) 보유 │ │ · Options를 읽어 필요한 서브시스템만 켬 │ └───────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌──────┐ ┌───────┐ ┌────────┐ ┌────────┐ ┌────────┐ │input │ │ world │ │ depth │ │ ai │ │ ui │ │손·시선│ │평면·물체│ │깊이·오클 │ │Gemini │ │공간패널 │ │제스처 │ │(Gemini·│ │루전 셰이더│ │/OpenAI │ │Reticle │ │strokes│ │MediaPipe)│ │ │ │ │ │ │ └──────┘ └───────┘ └────────┘ └────────┘ └────────┘ │ physics(Rapier) · sound(공간음향·음성) · simulator · camera … ▼ ┌───────────────────────────────────────────────────────────┐ │ Script (내 앱, = THREE.Object3D) src/core/Script.ts │ │ init() 한 번 호출 (async 가능) │ │ update(t,frame) 매 프레임 │ │ onSelectEnd() 핀치(XR) / 클릭(데스크톱) 통합 │ │ onObjectGrab..., onHover..., initPhysics() … │ └───────────────────────────────────────────────────────────┘ ── 모든 공개 API는 src/xrblocks.ts 한 파일(barrel)로 노출 ── ── 같은 코드가 [안드로이드 XR 기기] 또는 [데스크톱 시뮬레이터]에서 실행 ──
용어
싱글턴 엔진 · 생명주기 훅 (Lifecycle Hook)
싱글턴은 프로그램 전체에 딱 하나만 존재하는 객체다. XR Blocks의 Core가 그렇다 — 렌더러·카메라·XR 세션을 혼자 소유해 충돌을 막는다. 생명주기 훅은 "특정 시점에 자동으로 불리는 함수"다. init(시작 시), update(매 프레임), onSelectEnd(선택 시)처럼, 개발자는 "언제 실행할지"는 신경 안 쓰고 "무엇을 할지"만 채운다.

패턴 1 — 스크립트 하나가 곧 THREE.Object3D

똑똑한 설계 포인트: xb.Scriptthree.js의 Object3D를 상속한다. 즉 스크립트 자체가 씬 그래프의 노드다. 그래서 this.add(mesh)를 하면 그 메시가 "내 스크립트 밑"에 붙는다. 별도의 "씬에 추가" 개념을 배울 필요가 없다.

// 가장 작은 XR Blocks 앱 (CONTEXT.md의 정석 패턴)
import * as THREE from 'three';
import * as xb from 'xrblocks';

class MainScript extends xb.Script {
  init() {                       // 한 번 실행
    this.add(new THREE.HemisphereLight(0xffffff, 0x666666, 3));
    const cube = new THREE.Mesh(
      new THREE.BoxGeometry(0.3, 0.3, 0.3),
      new THREE.MeshStandardMaterial({color: 0x4285f4}));
    // 사용자 앞, 편한 높이에 배치 (단위=미터)
    cube.position.set(0, xb.user.height - 0.3, -xb.user.objectDistance);
    this.add(cube);              // this 가 곧 Object3D
    this.cube = cube;
  }
  onSelectEnd() {                // 데스크톱 클릭 OR XR 핀치
    this.cube.material.color.set(Math.random() * 0xffffff);
  }
}
xb.add(new MainScript());
xb.init(new xb.Options());       // 엔진 + 렌더 루프 부팅

패턴 2 — 기능은 Options의 enable*()로 켠다

손 추적이 필요하면 options.enableHands(), 깊이 인식은 enableDepth(), AI는 enableAI(). 내부를 만지지 않고 스위치를 켜듯 기능을 조립한다. 이 체이닝 방식 덕에 "이 앱이 무슨 능력을 쓰는가"가 코드 상단에서 한눈에 보인다.

const options = new xb.Options();
options.enableUI();              // 공간 UI + 조준점
options.enableHands();           // 손 관절 추적
options.enableGestures();        // 핀치/주먹/포인트/스프레드/엄지척
options.enableDepth();           // WebXR 깊이 센싱 + 깊이 메시
options.enablePlaneDetection();  // 바닥·벽 등 평면 인식
options.enableObjectDetection(); // 물체 인식(카메라 권한도 함께)
options.enableAI();              // Gemini/OpenAI → xb.ai
xb.init(options);

// 예외: 물리는 enablePhysics()가 없다 — RAPIER를 직접 주입
import RAPIER from '@dimforge/rapier3d-simd-compat';
options.physics.RAPIER = RAPIER; // 이 대입이 물리를 켠다
용어
Barrel Export (배럴 익스포트)
여러 파일에 흩어진 공개 심볼을 한 파일에서 모아 다시 내보내는 방식. XR Blocks는 src/xrblocks.ts 하나가 SDK의 "공식 API 목록"이다. 거기 없으면 내부용이다. 이렇게 하면 사용자(그리고 AI)가 "무엇을 쓸 수 있나"를 한 곳에서 확인하고, import * as xb from 'xrblocks'로 전부 접근한다. AI의 API 환각을 줄이는 핵심 장치.

패턴 3 — Reality Model: user · world · agents

논문이 제시하는 개념 모델은 "Reality Model"이다. 현실을 세 가지 1급 요소로 추상화한다 — xb.user(사용자: 키·손·시선·선택 상태), xb.world(세계: 인식된 평면·물체·메시), 그리고 AI agents. 여기에 "상호작용 문법(interaction grammar)"을 더해, 명시적 이벤트(클릭·핀치 = onSelectStart)와 암묵적 의도(제스처·시선·음성)를 구분해 다룬다.

// 사용자·AI를 코드로 다루기
xb.user.height;                  // 사용자 눈높이(미터)
xb.user.isSelectingAt(object);   // 이 물체를 선택 중인가?
xb.user.isPointingAt(object);    // 이 물체를 가리키나?(호버)

if (xb.ai.isAvailable()) {       // AI는 항상 가드!
  const res = await xb.ai.query({prompt: '먼지에 관한 하이쿠를 써줘.'});
  // res.text 에 답. 멀티모달·Gemini Live 세션도 지원
}

패턴 4 — 두 개의 UI 시스템(의도적 분리)

공간 UI가 두 갈래다. 코어 UI(xb.SpatialPanel + .addGrid()/.addRow()/.addButton())는 가볍고 의존성이 없어 HUD·메뉴에 좋다. uiblocks 애드온(@pmndrs/uikit 기반)은 flexbox·그라디언트·그림자까지 되는 풀 레이아웃이다. 문서는 "둘을 한 패널에 섞지 말라"고 못박는다. 필요에 따라 골라 쓰는 구조.

5디렉토리 구조 해부

"src의 서브시스템 한 폴더 = 한 능력" + 예제 3종(samples/demos/templates) + AI용 skills.

xrblocks/ ├── src/ ← SDK 소스 (능력별 한 폴더) │ ├── xrblocks.ts ★ 배럴: 공개 API 전부 여기로 │ ├── SKILL.md in-tree SDK 개요(개발자·AI용) │ ├── core/ ★ Core 싱글턴·Script·Options·User·DI Registry │ ├── input/ 컨트롤러·손·시선·마우스 + gestures/ + strokes/ │ ├── world/ 평면·메시·물체(Gemini·MediaPipe 백엔드)·소리 │ ├── depth/ 깊이 센싱·깊이 메시 + occlusion/ 셰이더 │ ├── ai/ Gemini + OpenAI 파사드(query/live/이미지) │ ├── agent/ 에이전트 프레임워크: 도구·메모리·컨텍스트(WIP) │ ├── ui/ SpatialPanel·Grid/Row/Col·ModelViewer·Reticle │ ├── ux/ DragManager 등 재사용 상호작용 │ ├── simulator/ 데스크톱 XR 시뮬레이터(가상 사용자/손/깊이) │ ├── sound/ 공간 음향·음성 인식/합성 │ ├── physics/ Rapier3D 연동 │ ├── lighting/ camera/ video/ stereo/ 광추정·기기카메라·영상·스테레오 │ ├── utils/ ModelLoader·의존성 주입 헬퍼 │ ├── StylizedFace.ts VisemeWeights.ts 아바타 얼굴·립싱크 비젬 │ └── addons/ 별도 빌드 모듈: uiblocks·netblocks· │ testing·glasses·volumes·virtualkeyboard … ├── samples/ 기능별 예제(문서 사이트에서 서빙) ├── demos/ 쇼케이스: Ballpit·XR-Emoji·XR-Object·Gemini-Icebreakers ├── templates/ 최소 시작점: 0_basic·1_ui·2_hands·6_ai … ├── docs/ Docusaurus 매뉴얼(xrblocks.github.io) ├── skills/ AI 에이전트용 xb-* 스킬 15종(아래) ├── evals/ 생성 코드 평가(환각 API 잡기) ├── build/ ← Rollup 생성물(직접 편집 금지) ├── AGENTS.md CONTEXT.md GEMINI.md CLAUDE.md ← AI 에이전트 안내 문서들 ├── rollup.config.js package.json tsconfig*.json └── LICENSE(Apache-2.0) · README.md

세 덩어리로 나눠 읽으면 명료하다.

① SDK 본체 src/. 규칙이 단순하다 — "한 폴더 = 한 능력(서브시스템)". core/가 엔진의 뼈대(Core·Script·Options)이고, 나머지 input/world/depth/ai/ui/physics…가 각각 하나의 기능을 담당한다. 새 기능을 추가할 때도 "폴더 만들고 → Options에 enable*() 붙이고 → 배럴에 export"라는 정형 절차(AGENTS.md에 명시)를 따른다.

② 예제 3종 세트. 학습 동선이 계단식이다. templates/최소 뼈대(복붙 시작점), samples/기능 하나씩 보여주는 예제, demos/완성형 쇼케이스(Ballpit 물리, XR-Emoji, Gemini Icebreakers). 막히면 이 실제 파일에서 패턴을 복사하라는 게 공식 가이드다.

③ AI를 위한 문서 계층. 이 저장소의 독특함 — 루트에 AGENTS.md·CONTEXT.md·GEMINI.md·CLAUDE.md가 있고, skills/에는 xb-core·xb-ui·xb-hands·xb-gestures·xb-depth·xb-world·xb-ai·xb-physics·xb-simulator·xb-sound·xb-netblocks·xb-uiblocks·xb-modelviewer·xb-lipsync·xb-testing 15개 스킬이 있다. 사람과 AI 에이전트 모두를 독자로 상정한 구조다.

용어
Addon(애드온) · Peer Dependency
애드온은 코어에 항상 포함되지 않고 필요할 때만 따로 로드하는 선택 모듈이다(uiblocks·netblocks 등). 코어 번들을 가볍게 유지하는 장치. Peer dependency는 "이 라이브러리를 쓰려면 당신이 three.js도 설치해야 한다"고 선언하는 방식 — XR Blocks가 three를 번들에 넣지 않고 peerDependencies로 둔 이유는, 앱이 three 사본을 두 개 로드하는 참사를 막기 위해서다.

6학습 포인트 (기술별)

이 저장소에서 "무엇을 배울 수 있는가" — 개념 → 코드 위치 → 실습 아이디어.

학습 포인트 A

게임 엔진식 아키텍처 — 싱글턴 + 컴포넌트 생명주기

웹 프론트엔드 개발자에게 낯선 "엔진이 루프를 돌리고, 나는 훅만 채운다"는 패러다임을 실물로 배운다. src/core/Core.ts(싱글턴)와 Script.ts(확장점)를 읽으면, 유니티·언리얼이 쓰는 방식이 웹에서 어떻게 재현되는지 보인다.

실습: Script의 훅(init/update/onSelectEnd)에 console.log를 넣고 호출 순서와 빈도를 관찰. update(time, frame)가 초당 몇 번 불리는지 세어 보기.

학습 포인트 B

WebXR + three.js의 결합

브라우저에서 XR을 여는 WebXR Device API와, 3D를 그리는 three.js 씬 그래프가 어떻게 맞물리는지. ScriptTHREE.Object3D를 상속한다는 사실 하나로 "3D 객체 계층 = 앱 구조"가 된다.

실습: templates/0_basic를 열어 큐브 하나를 띄우고, 위치(position)·회전(rotation)을 update()에서 시간에 따라 바꿔 회전하는 물체 만들기.

학습 포인트 C

브라우저 안의 온디바이스 ML (MediaPipe / LiteRT)

서버 없이 브라우저에서 직접 신경망 추론을 돌리는 법. 손 랜드마크·제스처·물체 인식이 src/input/gestures/·src/world/objects/에서 어떻게 모델을 로드하고 매 프레임 추론하는지 관찰한다.

실습: enableHands() + enableGestures()를 켜고 gesturestart 이벤트를 구독해, 엄지척(thumbs-up)을 하면 색이 바뀌는 앱 만들기(시뮬레이터에서도 됨).

학습 포인트 D

멀티모달 AI 통합 — Gemini query & Live

텍스트뿐 아니라 이미지·오디오·실시간 대화를 XR과 엮는 법. src/ai/AI.ts가 Gemini·OpenAI를 xb.ai 뒤에 추상화한 파사드 패턴, 그리고 xb.ai.isAvailable() 가드 관례를 배운다.

실습: AI Studio 키로 enableAI() 후, 화면 물체를 클릭하면 Gemini가 그 물체를 설명하도록 xb.ai.query() 연결(키 가드 필수).

학습 포인트 E

WASM 물리 엔진 (Rapier3D)

Rust로 짠 물리 엔진을 WebAssembly로 브라우저에서 굴리는 실전 예. enablePhysics()없고 options.physics.RAPIER = RAPIER로 주입하는 특이 패턴, initPhysics()/physicsStep() 훅을 src/physics/demos/Ballpit에서 확인.

실습: Rapier를 주입하고 공 여러 개를 중력으로 떨어뜨리는 미니 Ballpit 만들기.

학습 포인트 F

라이브러리 빌드 & "AI 친화 API" 설계

rollup.config.js로 ESM·min·.d.ts·애드온을 동시에 뽑고 무거운 의존성을 external로 빼는 라이브러리 번들링, 그리고 src/xrblocks.ts 배럴 + skills/ + evals/LLM의 API 환각을 억제하는 설계를 통째로 배운다. "코드를 사람과 AI 모두가 읽는다"는 요즘 트렌드의 모범.

실습: src/xrblocks.ts를 훑어 공개 API 지도를 직접 그려 보고, AGENTS.md의 "환각 API 피하기" 표와 대조.

7하드웨어 / 시스템 요구사항

헤드셋은 선택 — 크롬만 있으면 시뮬레이터로 대부분 학습 가능. AI만 키 필요.

항목요구/권장
브라우저Chrome 136+ (WebXR 지원). 데스크톱 개발/시뮬레이터도 크롬 기준
XR 기기(선택)안드로이드 XR 기기(예: 삼성 Galaxy XR). 실기기 손추적·깊이·패스스루용
헤드셋 없이데스크톱 크롬 + 시뮬레이터로 대부분 개발/테스트 가능(?formFactor=desktop)
개발 환경Node.js + npm (npm cinpm run dev). 로컬 :8080 서빙
AI 기능Gemini API 키(AI Studio 발급). 비(非)AI 샘플은 키 불필요
온디바이스 ML손·제스처·깊이는 LiteRT로 기기 안에서 실행 → 데이터 로컬 처리
설치 없이 체험jsDelivr CDN + importmap만으로 빈 HTML에서 실행(빌드 불필요)
진입 관점
"가장 쉬운 시작 = CDN 템플릿을 데스크톱 크롬에서 열기"

헤드셋도, 설치도, 빌드도 필요 없다. README의 Basic 예제 HTML을 그대로 저장해 크롬에서 열면(또는 라이브 데모 링크), 실린더가 뜨고 클릭하면 색이 바뀐다(시뮬레이터의 클릭 = XR의 핀치). 여기서 시작해 enableHands/enableAI를 하나씩 켜 보는 게 가장 안전한 학습 경로다.

현실적 주의
"API 키를 클라이언트에 심지 말 것"

README·AGENTS.md가 거듭 경고한다 — ?key=... URL 파라미터나 keys.json 방식은 로컬 프로토타입 전용이다. 클라이언트 코드(JS)에 키를 넣으면 누구나 추출해 쿼터·과금을 도용할 수 있다. 프로덕션은 반드시 본인 서버로 AI 호출을 프록시해야 한다. 또 AI 기능은 데이터가 구글 서버로 가므로 Gemini 약관을 따라야 한다.

8직접 해볼 수 있는 실습 과제

난이도별로 손을 움직여 보는 5가지. (전부 데스크톱 시뮬레이터로 가능)

입문 ★☆☆

과제 1 — CDN 한 장으로 첫 XR 씬

빌드·설치 없이 importmap만으로 브라우저에서 실린더를 띄우고, 클릭해 색을 바꾼다.

<!-- index.html 의 <head> 에 importmap -->
<script type="importmap">
{ "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.module.js",
    "xrblocks": "https://cdn.jsdelivr.net/gh/google/xrblocks@build/xrblocks.js"
}}
</script>

본문 <script type="module">에 4장의 MainScript를 넣고 데스크톱 크롬에서 연다. 클릭 = 핀치임을 체감한다.

과제 2 — 저장소 클론 후 샘플 둘러보기

공식 예제를 로컬에서 서빙하며 "무엇이 되는지" 감을 잡는다.

git clone --depth=1 https://github.com/google/xrblocks.git
cd xrblocks && npm ci
npm run dev        # 워치 빌드 + http://127.0.0.1:8080
# 브라우저에서 samples/demos 를 열고, ?formFactor=desktop 로 시뮬레이터 강제

Ballpit·XR-Emoji·Gemini-Icebreakers 데모를 열어 코드와 결과를 대조한다.

중급 ★★☆

과제 3 — 공간 UI 패널 만들기

enableUI()xb.SpatialPanel에 그리드·버튼을 얹어 "공중에 뜬 메뉴"를 만든다. 버튼의 onTriggered(클릭/핀치/터치 통합)로 씬을 조작한다. templates/1_ui가 참고서.

과제 4 — 손 + 제스처로 상호작용

enableHands() + enableGestures()를 켜고 gesturestart/gestureupdate/gestureend를 구독한다. 핀치로 물체를 잡아 옮기고(onObjectGrab*), 엄지척으로 색 변경 같은 반응을 붙인다. templates/2_hands 참고.

고급 ★★★

과제 5 — Gemini 붙이기 + 물리로 Ballpit

둘 중 하나(또는 둘 다)에 도전한다. (A) AI Studio 키로 enableAI()xb.ai.query()화면 속 물체를 Gemini가 설명하게 하고, 여유가 되면 startLiveSession()으로 실시간 대화까지. (B) options.physics.RAPIER를 주입하고 initPhysics()/physicsStep()으로 공이 중력에 떨어지는 Ballpit을 재현. xb.ai.isAvailable() 가드와 키 보안 수칙을 지키면 실무 감각이 완성된다.

9관련 기술 심화 학습 로드맵

4주 코스 — three.js/WebXR 기초부터 AI·물리·애드온까지.

주차주제구체적 목표
1주차three.js & WebXR 기초씬·카메라·메시·재질·조명 개념. templates/0_basic를 시뮬레이터로 실행. src/xrblocks.ts 배럴과 CONTEXT.md 정독으로 "공개 API 지도" 파악
2주차Script 생명주기 & 입력init/update/onSelectEnd 훅 숙달. enableUI로 SpatialPanel, enableHands/enableGestures로 손·제스처 입력 다루기. 이벤트(명시) vs 의도(암묵) 구분
3주차세계 이해 & AIenableDepth/enablePlaneDetection/enableObjectDetectionxb.world 활용. enableAI + Gemini query/Live, 멀티모달·온디바이스 ML(MediaPipe/LiteRT) 구조 읽기
4주차물리·애드온·기여Rapier 물리(initPhysics/physicsStep), uiblocks(고급 UI)·netblocks(멀티플레이어) 애드온. *.test.ts(Vitest) 작성법 익히고 samples/에 예제 하나 기여
곁들이면 좋은 배경 지식
three.js · WebAssembly · 온디바이스 AI

XR Blocks는 여러 최신 웹 기술의 집대성이라, 각 축을 따로 알면 훨씬 깊어진다. three.js(3D 렌더링의 근본), WebAssembly(Rapier 물리가 왜 빠른가), 브라우저 ML(MediaPipe/LiteRT로 신경망을 로컬 실행), 그리고 "코드를 LLM이 읽고 생성한다"는 전제의 API 설계 — 이 네 갈래가 XR Blocks를 관통하는 큰 흐름이다.

10핵심 키워드 사전

이 프로젝트를 읽을 때 반복 등장하는 용어 정리.

키워드
XR / WebXRVR·AR·MR 통칭 / 그것을 웹 브라우저에서 구현하는 표준 API
Android XR구글의 XR 플랫폼. 삼성 Galaxy XR 등이 대상 기기
three.js웹 3D 렌더링의 사실상 표준 라이브러리. XR Blocks의 토대(peer dep)
Core / Script / Options엔진 싱글턴(xb.core) / 개발자 확장점(생명주기 훅) / 기능 스위치(enable*())
Reality Model논문의 개념 모델 — user·world·agents를 1급 요소로 추상화
interaction grammar명시적 이벤트(클릭·핀치)와 암묵적 의도(제스처·시선·음성)를 나눠 다루는 문법
Gemini / Gemini Live구글 LLM / 실시간 멀티모달 대화 세션. xb.ai로 접근
LiteRT / MediaPipe온디바이스 추론 런타임(구 TensorFlow Lite) / 손·시각·오디오 태스크 SDK
Rapier3DRust로 짠 물리 엔진의 WASM 빌드. 강체·충돌 담당
WebAssembly (WASM)브라우저에서 네이티브급 속도로 도는 바이너리 포맷(Rapier가 이걸로 실행)
importmapHTML에서 모듈 이름→URL 매핑. 설치 없이 CDN으로 라이브러리 로드
peer dependency"쓰려면 당신이 함께 설치해야 하는" 의존성(three.js). 사본 중복 방지
barrel export공개 API를 한 파일(src/xrblocks.ts)에 모아 내보내기
desktop simulator헤드셋 없이 크롬에서 XR을 흉내 내는 개발용 시뮬레이터(?formFactor=desktop)
passthrough / immersive-ar·vr기기 카메라로 현실을 보며 증강 / WebXR의 AR·VR 세션 모드
depth sensing · occlusion깊이 인식 → 가상 물체가 현실 물체 뒤로 가려지는(오클루전) 효과
gesture recognition핀치·주먹·포인트·스프레드·엄지척 등 손 모양 인식
Gaussian Splatting점(스플랫)들로 실사 3D 장면을 표현하는 기법(Spark 렌더러)
addon코어에 항상 없고 필요 시 로드하는 선택 모듈(uiblocks·netblocks 등)
vibe coding XRLLM에게 자연어로 지시해 XR 앱을 생성하는 워크플로(논문 2603.24591)
hallucinated APIAI가 존재하지 않는 함수를 지어내는 것 — 이 SDK가 억제 대상으로 명시

11참고 링크

원본을 직접 확인하고 싶을 때.