AR/VR/XR은 현실과 가상을 결합하는 기술 스펙트럼이다. AR(증강현실)은 현실에 가상을 덧씌우고, VR(가상현실)은 완전한 가상 환경을 제공하며, XR(확장현실)은 이 모두를 포괄한다.
현실-가상 연속체
현실 ───────────────────────────── 가상
│ AR (증강현실) │ MR (혼합현실) │ VR (가상현실) │
AR: 현실 위에 2D/3D 오버레이 (포켓몬GO, ARKit)
MR: 가상 객체가 현실과 물리적으로 상호작용 (HoloLens)
VR: 완전한 가상 몰입 환경 (Meta Quest, PS VR2)
XR: AR+MR+VR 통합 개념
주요 플랫폼 비교
| 플랫폼 | 유형 | FOV | 해상도 | 주요 용도 |
|---|
| Meta Quest 3 | VR/MR | 110° | 2064×2208 | 게임, 소셜 |
| Apple Vision Pro | MR/VR | 100° | 3660×3200 | 생산성, 엔터 |
| HoloLens 2 | AR/MR | 52° | 2048×1080 | 산업, 의료 |
| Magic Leap 2 | AR | 70° | 1440×1760 | 기업용 |
ARKit 예시 (iOS)
swift
import ARKit
import RealityKit
class ARViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
// 평면 감지 AR 세션
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal, .vertical]
config.environmentTexturing = .automatic
arView.session.run(config)
// 탭으로 3D 객체 배치
let tapGesture = UITapGestureRecognizer(
target: self, action: #selector(handleTap))
arView.addGestureRecognizer(tapGesture)
}
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
let location = recognizer.location(in: arView)
let results = arView.raycast(
from: location, allowing: .estimatedPlane, alignment: .horizontal)
if let result = results.first {
let anchor = AnchorEntity(world: result.worldTransform)
let box = ModelEntity(mesh: .generateBox(size: 0.1),
materials: [SimpleMaterial(color: .blue, isMetallic: true)])
anchor.addChild(box)
arView.scene.addAnchor(anchor)
}
}
}
javascript
// WebXR Device API
async function startVR() {
if (!navigator.xr) return;
const session = await navigator.xr.requestSession('immersive-vr',
{ requiredFeatures: ['local-floor', 'bounded-floor'] });
const referenceSpace = await session.requestReferenceSpace('local-floor');
const glLayer = new XRWebGLLayer(session, gl);
session.updateRenderState({ baseLayer: glLayer });
session.requestAnimationFrame(onXRFrame);
}
function onXRFrame(time, frame) {
const pose = frame.getViewerPose(referenceSpace);
for (const view of pose.views) {
// view.projectionMatrix, view.transform으로 렌더링
renderEye(view);
}
session.requestAnimationFrame(onXRFrame);
}
관련 문서