컨νΈλ‘€λ¬μ νΈλ νΈλνΉμ ν¬ν¨ν WebXR μ λ ₯ μμ€λ₯Ό νμνμ¬ μ μΈκ³ μ¬μ©μλ₯Ό μν λ§€λ ₯μ μ΄κ³ μ§κ΄μ μΈ κ°μ νμ€ λ° μ¦κ° νμ€ κ²½νμ λ§λ€μ΄ 보μΈμ.
WebXR μ λ ₯ μμ€: λͺ°μ ν κ²½νμ μν 컨νΈλ‘€λ¬ λ° νΈλ νΈλνΉ λ§μ€ν°νκΈ°
WebXRμ λΈλΌμ°μ μμ μ§μ λͺ°μ ν κ°μ λ° μ¦κ° νμ€ κ²½νμ λ§λ€ μ μλ κ°λ ₯ν λꡬλ₯Ό μ 곡ν©λλ€. λͺ¨λ λͺ°μ ν μ ν리μΌμ΄μ μ μ€μν μΈ‘λ©΄μ μ¬μ©μκ° κ°μ μΈκ³μ μνΈ μμ©νλ λ°©μμ λλ€. WebXRμ μ£Όλ‘ μ»¨νΈλ‘€λ¬μ νΈλ νΈλνΉκ³Ό κ°μ λ€μν μ λ ₯ μμ€λ₯Ό κ°λ ₯νκ² μ§μν©λλ€. μ΄λ¬ν μ λ ₯ λ°©λ²μ νμ©νλ λ°©λ²μ μ΄ν΄νλ κ²μ μ μΈκ³ μ¬μ©μλ₯Ό μν΄ μ§κ΄μ μ΄κ³ λ§€λ ₯μ μΈ κ²½νμ λ§λλ λ° λ§€μ° μ€μν©λλ€.
WebXR μ λ ₯ μμ€ μ΄ν΄νκΈ°
WebXRμμ μ λ ₯ μμ€λ κ°μ νκ²½κ³Ό μνΈ μμ©νλ λ° μ¬μ©λλ 물리μ μ₯μΉ λλ λ°©λ²μ λνλ λλ€. μ΄λ¬ν μ λ ₯ μμ€λ κ°λ¨ν κ²μν¨λμ κ°μ 컨νΈλ‘€λ¬λΆν° μ κ΅ν νΈλ νΈλνΉ μμ€ν κΉμ§ λ€μν μ μμ΅λλ€. κ° μ λ ₯ μμ€λ κ°λ°μκ° XR κ²½ν λ΄μμ κ°μ²΄λ₯Ό μ μ΄νκ³ , μ₯λ©΄μ νμνλ©°, λμμ νΈλ¦¬κ±°νλ λ° μ¬μ©ν μ μλ λ°μ΄ν° μ€νΈλ¦Όμ μ 곡ν©λλ€.
μ λ ₯ μμ€μ μ’ λ₯
- 컨νΈλ‘€λ¬: μ¬μ©μκ° μμ λ€κ³ μ‘°μνλ λ²νΌ, μ‘°μ΄μ€ν±, νΈλ¦¬κ±°, ν°μΉν¨λκ° μλ 물리μ μ₯μΉμ λλ€. 컨νΈλ‘€λ¬λ VR κ²½νμ μν μΌλ°μ μ΄κ³ μ λ’°ν μ μλ μ λ ₯ λ°©λ²μ λλ€.
- νΈλ νΈλνΉ: μΉ΄λ©λΌμ μ»΄ν¨ν° λΉμ μκ³ λ¦¬μ¦μ μ¬μ©νμ¬ 3D 곡κ°μμ μ¬μ©μμ μμ κ°μ§νκ³ μΆμ ν©λλ€. μ΄λ₯Ό ν΅ν΄ κ°μ νκ²½κ³Ό μμ°μ€λ½κ³ μ§κ΄μ μΈ μνΈ μμ©μ΄ κ°λ₯ν©λλ€.
- κΈ°ν μ λ ₯ μμ€: ννμ§λ μμ§λ§, WebXRμ μμ κΈ°λ° μνΈ μμ©μ μ¬μ©νλ ν€λ νΈλνΉμ΄λ μμ± μΈμκ³Ό κ°μ λ€λ₯Έ μ λ ₯ μμ€λ μ§μν μ μμ΅λλ€.
WebXRμμ 컨νΈλ‘€λ¬ μμ νκΈ°
컨νΈλ‘€λ¬λ WebXR κ°λ°μμ λ리 μ§μλλ©° λΉκ΅μ κ°λ¨ν μ λ ₯ μμ€μ λλ€. μ λ°λμ μ¬μ© νΈμμ±μ κ· νμ μ 곡νμ¬ κ΄λ²μν μ ν리μΌμ΄μ μ μ ν©ν©λλ€.
컨νΈλ‘€λ¬ κ°μ§ λ° μ κ·Ό
WebXR APIλ μλ‘μ΄ μ
λ ₯ μμ€κ° μ°κ²°λκ±°λ μ°κ²° ν΄μ λ λ κ°λ°μμκ² μ리λ μ΄λ²€νΈλ₯Ό μ 곡ν©λλ€. xr.session.inputsourceschange
μ΄λ²€νΈλ μ¬μ© κ°λ₯ν μ
λ ₯ μμ€μ λ³κ²½μ κ°μ§νλ μ£Όμ λ°©λ²μ
λλ€.
xrSession.addEventListener('inputsourceschange', (event) => {
// New input source connected
event.added.forEach(inputSource => {
console.log('New input source:', inputSource);
// Handle the new input source
});
// Input source disconnected
event.removed.forEach(inputSource => {
console.log('Input source removed:', inputSource);
// Handle the disconnected input source
});
});
μ
λ ₯ μμ€κ° κ°μ§λλ©΄ ν΄λΉ μμ±μ μ κ·Όνμ¬ κΈ°λ₯κ³Ό μνΈ μμ© λ°©λ²μ κ²°μ ν μ μμ΅λλ€. inputSource.profiles
λ°°μ΄μλ 컨νΈλ‘€λ¬μ λ μ΄μμκ³Ό κΈ°λ₯μ μ€λͺ
νλ νμ€νλ νλ‘ν λͺ©λ‘μ΄ ν¬ν¨λμ΄ μμ΅λλ€. μΌλ°μ μΈ νλ‘νμλ 'generic-trigger', 'oculus-touch', 'google-daydream' λ±μ΄ μμ΅λλ€.
컨νΈλ‘€λ¬ λ°μ΄ν° κ°μ Έμ€κΈ°
컨νΈλ‘€λ¬μ νμ¬ μν(μ: λ²νΌ λλ¦, μ‘°μ΄μ€ν± μμΉ, νΈλ¦¬κ±° κ°)λ₯Ό μ»μΌλ €λ©΄ XRFrame.getControllerState()
λ©μλλ₯Ό μ¬μ©ν΄μΌ ν©λλ€. μ΄ λ©μλλ 컨νΈλ‘€λ¬μ νμ¬ μ
λ ₯ κ°μ ν¬ν¨νλ XRInputSourceState
κ°μ²΄λ₯Ό λ°νν©λλ€.
xrSession.requestAnimationFrame(function onAnimationFrame(time, frame) {
const pose = frame.getViewerPose(xrReferenceSpace);
if (pose) {
const inputSources = xrSession.inputSources;
for (const inputSource of inputSources) {
if (inputSource.hand) continue; // Skip hand tracking
const inputSourceState = frame.getControllerState(inputSource);
if (inputSourceState) {
// Access button states
for (const button of inputSourceState.buttons) {
if (button.pressed) {
// Handle button press event
console.log('Button pressed:', button);
}
}
// Access axes values (e.g., joystick positions)
for (const axis of inputSourceState.axes) {
console.log('Axis value:', axis);
// Use axis value to control movement or other actions
}
//Access squeeze state (if available)
if (inputSourceState.squeeze != null) {
if(inputSourceState.squeeze.pressed) {
console.log("Squeeze pressed");
}
}
}
}
}
});
컨νΈλ‘€λ¬ μ‘΄μ¬ μκ°ννκΈ°
κ°μ μΈκ³μμ 컨νΈλ‘€λ¬μ μ‘΄μ¬μ μμΉλ₯Ό λνλ΄κΈ° μν΄ μ¬μ©μμκ² μκ°μ νΌλλ°±μ μ 곡νλ κ²μ΄ μ€μν©λλ€. 컨νΈλ‘€λ¬μ 3D λͺ¨λΈμ λ§λ€κ³ 컨νΈλ‘€λ¬μ ν¬μ¦μ λ°λΌ μμΉμ λ°©ν₯μ μ λ°μ΄νΈνμ¬ μ΄λ₯Ό λ¬μ±ν μ μμ΅λλ€.
const inputSources = xrSession.inputSources;
for (const inputSource of inputSources) {
if (inputSource.hand) continue; // Skip hand tracking
const gripPose = frame.getPose(inputSource.gripSpace, xrReferenceSpace);
if (gripPose) {
// Update the controller model's position and rotation
controllerModel.position.set(gripPose.transform.position.x, gripPose.transform.position.y, gripPose.transform.position.z);
controllerModel.quaternion.set(gripPose.transform.orientation.x, gripPose.transform.orientation.y, gripPose.transform.orientation.z, gripPose.transform.orientation.w);
}
}
μμ : 컨νΈλ‘€λ¬ κΈ°λ° μνΈμμ© β μκ°μ΄λ
컨νΈλ‘€λ¬μ μΌλ°μ μΈ μ¬μ© μ¬λ‘λ μ¬μ©μκ° κ°μ νκ²½ λ΄μμ λΉ λ₯΄κ² μ΄λν μ μλλ‘ νλ μκ°μ΄λμ λλ€. λ€μμ 컨νΈλ‘€λ¬ νΈλ¦¬κ±°λ₯Ό μ¬μ©νμ¬ μκ°μ΄λμ ꡬννλ κ°λ¨ν μμ μ λλ€.
// Check if the trigger button is pressed
if (inputSourceState.buttons[0].pressed) {
// Perform teleportation logic
const targetPosition = calculateTeleportLocation();
xrReferenceSpace = xrSession.requestReferenceSpace('local-floor', { position: targetPosition });
}
WebXRμμ νΈλ νΈλνΉμ ν νμ©νκΈ°
νΈλ νΈλνΉμ 컨νΈλ‘€λ¬μ λΉν΄ λ μμ°μ€λ½κ³ μ§κ΄μ μΈ μνΈ μμ© λ°©λ²μ μ 곡ν©λλ€. μ¬μ©μλ μμ μ μμ μ¬μ©νμ¬ κ°μ κ°μ²΄λ₯Ό μ§μ μ‘°μνκ³ , μ μ€μ²λ₯Ό λ§λ€λ©°, νκ²½κ³Ό μνΈ μμ©ν μ μμ΅λλ€.
νΈλ νΈλνΉ νμ±ννκΈ°
νΈλ νΈλνΉμ μ¬μ©νλ €λ©΄ WebXR μΈμ
μ μμ±ν λ 'hand-tracking'
μ νμ κΈ°λ₯μ μμ²ν΄μΌ ν©λλ€.
navigator.xr.requestSession('immersive-vr', {
requiredFeatures: [],
optionalFeatures: ['hand-tracking']
}).then(session => {
xrSession = session;
// ...
});
μ λ°μ΄ν° μ κ·ΌνκΈ°
νΈλ νΈλνΉμ΄ νμ±νλλ©΄ inputSource.hand
μμ±μ ν΅ν΄ μ λ°μ΄ν°μ μ κ·Όν μ μμ΅λλ€. μ΄ μμ±μ μ¬μ©μμ μμ λνλ΄λ XRHand
κ°μ²΄λ₯Ό λ°νν©λλ€. XRHand
κ°μ²΄λ μκ°λ½ λ, κ΄μ , μλ°λ₯κ³Ό κ°μ μμ κ΄μ μμΉ λ° λ°©ν₯μ λν μ κ·Όμ μ 곡ν©λλ€.
xrSession.requestAnimationFrame(function onAnimationFrame(time, frame) {
const pose = frame.getViewerPose(xrReferenceSpace);
if (pose) {
const inputSources = xrSession.inputSources;
for (const inputSource of inputSources) {
if (!inputSource.hand) continue; // Skip controllers
// Get the XRHand object
const hand = inputSource.hand;
// Iterate through the joints of the hand
for (let i = 0; i < hand.length; i++) {
const jointSpace = hand[i];
// Get the pose of the joint
const jointPose = frame.getPose(jointSpace, xrReferenceSpace);
if (jointPose) {
// Access the joint's position and orientation
const jointPosition = jointPose.transform.position;
const jointOrientation = jointPose.transform.orientation;
// Update the position and rotation of a 3D model representing the joint
jointModels[i].position.set(jointPosition.x, jointPosition.y, jointPosition.z);
jointModels[i].quaternion.set(jointOrientation.x, jointOrientation.y, jointOrientation.z, jointOrientation.w);
}
}
}
}
});
μ μ‘΄μ¬ μκ°ννκΈ°
컨νΈλ‘€λ¬μ λ§μ°¬κ°μ§λ‘, κ°μ μΈκ³μμ μ¬μ©μμ μμ νννκΈ° μν΄ μκ°μ νΌλλ°±μ μ 곡νλ κ²μ΄ μ€μν©λλ€. μμ 3D λͺ¨λΈμ λ§λ€κ³ νΈλ νΈλνΉ λ°μ΄ν°μ λ°λΌ μμΉμ λ°©ν₯μ μ λ°μ΄νΈνμ¬ μ΄λ₯Ό λ¬μ±ν μ μμ΅λλ€. λλ ꡬλ νλΈμ κ°μ λ κ°λ¨ν μκ°νλ₯Ό μ¬μ©νμ¬ κ΄μ μμΉλ₯Ό λνλΌ μλ μμ΅λλ€.
μμ : μ κΈ°λ° μνΈμμ© β κ°μ²΄ μ‘κΈ°
νΈλ νΈλνΉμ κ°μ₯ μΌλ°μ μ΄κ³ μ§κ΄μ μΈ μ¬μ© μ¬λ‘ μ€ νλλ κ°μ κ°μ²΄λ₯Ό μ‘κ³ μ‘°μνλ κ²μ λλ€. λ€μμ νΈλ νΈλνΉμ μ¬μ©νμ¬ κ°μ²΄ μ‘κΈ°λ₯Ό ꡬννλ κ°λ¨ν μμ μ λλ€.
// Check if a finger is close to an object
if (distanceBetweenFingerAndObject < threshold) {
// Grab the object
grabbedObject = object;
grabbedObject.parent = handJointModel; // Attach the object to the hand
}
// When the finger moves away from the object
if (distanceBetweenFingerAndObject > threshold) {
// Release the object
grabbedObject.parent = null; // Detach the object from the hand
// Apply velocity to the object based on the hand's movement
grabbedObject.velocity.set(handVelocity.x, handVelocity.y, handVelocity.z);
}
WebXR μ λ ₯ κ°λ°μ μν λͺ¨λ² μ¬λ‘
λ§€λ ₯μ μ΄κ³ μ¬μ©μ μΉνμ μΈ WebXR κ²½νμ λ§λ€λ €λ©΄ λ€μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄λ κ²μ΄ μ€μν©λλ€.
- λͺ νν μκ°μ νΌλλ°± μ 곡: νμ μ¬μ©μμ μ λ ₯ μ₯μΉ(컨νΈλ‘€λ¬ λλ μ)μ μ‘΄μ¬μ μνλ₯Ό λνλ΄λ μκ°μ νΌλλ°±μ μ 곡νμμμ€.
- μ§κ΄μ μΈ μνΈμμ© μ°μ μ: μ¬μ©μμκ² μμ°μ€λ½κ³ μ§κ΄μ μΌλ‘ λκ»΄μ§λ μνΈμμ©μ μ€κ³νμμμ€. μ§μ μ‘°μμ΄ νμν μμ μλ νΈλ νΈλνΉμ, λ μ λ°νκ±°λ 볡μ‘ν μ μ΄κ° νμν μμ μλ 컨νΈλ‘€λ¬ μ¬μ©μ κ³ λ €νμμμ€.
- μ±λ₯ μ΅μ ν: νΈλ νΈλνΉ λ° μ»¨νΈλ‘€λ¬ μ λ ₯μ μ±λ₯μ λ§μ΄ μλͺ¨ν μ μμ΅λλ€. μ§μ°μ μ΅μννκ³ λΆλλ½κ³ λ°μμ± μλ κ²½νμ 보μ₯νλλ‘ μ½λλ₯Ό μ΅μ ννμμμ€. κ°μ²΄ νλ§ λ° LOD(Level of Detail)μ κ°μ κΈ°μ μ μ¬μ©νμ¬ μ±λ₯μ ν₯μμν€λ κ²μ κ³ λ €νμμμ€.
- μ λ ₯ μ΄λ²€νΈλ₯Ό ν¨μ¨μ μΌλ‘ μ²λ¦¬: μ λ ₯ μ΄λ²€νΈ νΈλ€λ¬ λ΄μμ μ§μ λΉμ©μ΄ λ§μ΄ λλ μμ μ μννμ§ λ§μμμ€. λμ μ λ ₯ μ΄λ²€νΈλ₯Ό λκΈ°μ΄μ λ£κ³ λ³λμ μ€λ λμμ μ²λ¦¬νκ±°λ requestAnimationFrameμ μ¬μ©νμ¬ λ©μΈ λ λλ§ μ€λ λλ₯Ό μ°¨λ¨νμ§ μλλ‘ νμμμ€.
- λ€μ€ μ λ ₯ μμ€ μ§μ: νΈλ νΈλνΉμ΄λ νΉμ 컨νΈλ‘€λ¬ μ νμ μ κ·Όν μ μλ μ¬μ©μλ₯Ό μν λ체 λ©μ»€λμ¦μ μ 곡νμμμ€. μ¬μ©μκ° μ νΈλ λ° μ¬μ© κ°λ₯ν νλμ¨μ΄μ λ°λΌ λ€λ₯Έ μ λ ₯ λ°©λ² κ°μ μ νν μ μλλ‘ νμ©νλ κ²μ κ³ λ €νμμμ€.
- μ κ·Όμ±: μ κ·Όμ±μ μΌλμ λκ³ XR κ²½νμ μ€κ³νμμμ€. μμ± μ μ΄ λλ μμ κΈ°λ° μνΈ μμ©κ³Ό κ°μ΄ μ₯μ κ° μλ μ¬μ©μλ₯Ό μν λ체 μ λ ₯ λ°©λ²μ μ 곡νμμμ€. λͺ¨λ μνΈ μμ©μ΄ μκ°μ λ° μ²κ°μ μ νΈλ₯Ό ν΅ν΄ λͺ ννκ² μ λ¬λλμ§ νμΈνμμμ€.
μ λ ₯ μ€κ³λ₯Ό μν κΈλ‘λ² κ³ λ € μ¬ν
μ μΈκ³ μ¬μ©μλ₯Ό μν WebXR κ²½νμ μ€κ³ν λλ λ¬Ένμ μ°¨μ΄μ μ κ·Όμ± μꡬ μ¬νμ κ³ λ €νλ κ²μ΄ μ€μν©λλ€. λ€μμ μΌλμ λμ΄μΌ ν λͺ κ°μ§ μ£Όμ μμμ λλ€.
- μ μ€μ² μΈμμ λ¬Ένμ μ°¨μ΄: μ μ€μ²λ λ¬Ένμ λ°λΌ λ€λ₯Έ μλ―Έλ₯Ό κ°μ§ μ μμ΅λλ€. νΉμ μ§μμμ λΆμΎκ°μ μ£Όκ±°λ μ€ν΄λ₯Ό μ΄ μ μλ μ μ€μ² μ¬μ©μ νΌνμμμ€. λ체 μνΈ μμ© λ°©λ²μ μ 곡νκ±°λ μ¬μ©μκ° μ μ€μ² λ§€νμ μ¬μ©μ μ μν μ μλλ‘ νλ κ²μ κ³ λ €νμμμ€. μλ₯Ό λ€μ΄, μμ§μκ°λ½μ μΉμΌμΈμ°λ μ μ€μ²λ λ§μ μμ λ¬ΈνκΆμμ κΈμ μ μ΄μ§λ§, μ€λ λ° λ¨λ―Έ μΌλΆ μ§μμμλ λΆμΎνκ² μ¬κ²¨μ§ μ μμ΅λλ€.
- μ ν¬κΈ° λ° λͺ¨μμ λ€μμ±: νΈλ νΈλνΉ μκ³ λ¦¬μ¦μ λ€μν μΈκ΅¬ μ§λ¨μ κ±Έμ³ μ ν¬κΈ°μ λͺ¨μμ λ³νλ₯Ό μμ©νκΈ° μν΄ μ‘°μ ν΄μΌ ν μ μμ΅λλ€. μ¬μ©μκ° νΉμ μ νΉμ±μ λ§κ² νΈλ νΈλνΉμ λ―ΈμΈ μ‘°μ ν μ μλ 보μ μ΅μ μ μ 곡νμμμ€.
- μΈμ΄ λ° νμ§ν: λͺ¨λ ν μ€νΈ λ° μ€λμ€ μ νΈκ° λ€λ₯Έ μΈμ΄μ λ§κ² μ μ ν νμ§νλμλμ§ νμΈνμμμ€. ν μ€νΈ νμ§νμ νμμ±μ μ΅μννκΈ° μν΄ μμ΄μ½ κΈ°λ° μΈν°νμ΄μ€ μ¬μ©μ κ³ λ €νμμμ€.
- μ₯μ κ° μλ μ¬μ©μλ₯Ό μν μ κ·Όμ±: μ²μλΆν° μ κ·Όμ±μ μΌλμ λκ³ XR κ²½νμ μ€κ³νμμμ€. μμ± μ μ΄, μμ κΈ°λ° μνΈ μμ© λλ μ€μμΉ μ κ·Όκ³Ό κ°μ μ₯μ κ° μλ μ¬μ©μλ₯Ό μν λ체 μ λ ₯ λ°©λ²μ μ 곡νμμμ€. λͺ¨λ μνΈ μμ©μ΄ μκ°μ λ° μ²κ°μ μ νΈλ₯Ό ν΅ν΄ λͺ ννκ² μ λ¬λλμ§ νμΈνμμμ€. κ°μμ±μ ν₯μμν€κΈ° μν΄ ν μ€νΈ λ° μμ΄μ½μ ν¬κΈ°μ μμμ μ¬μ©μ μ μν μ μλ μ΅μ μ μ 곡νλ κ²μ κ³ λ €νμμμ€.
- νλμ¨μ΄ κ°μ©μ± λ° λΉμ©: λ€λ₯Έ μ§μμ XR νλμ¨μ΄ κ°μ©μ± λ° λΉμ©μ μ μνμμμ€. μ κ°ν λͺ¨λ°μΌ VR ν€λμ λ° μ¦κ° νμ€ μ§μ μ€λ§νΈν°μ ν¬ν¨ν λ€μν μ₯μΉμ νΈνλλλ‘ κ²½νμ μ€κ³νμμμ€.
κ²°λ‘
컨νΈλ‘€λ¬μ νΈλ νΈλνΉμ ν¬ν¨ν WebXR μ λ ₯ μμ€λ₯Ό λ§μ€ν°νλ κ²μ λ§€λ ₯μ μ΄κ³ μ§κ΄μ μΈ λͺ°μ ν κ²½νμ λ§λλ λ° νμμ μ λλ€. κ° μ λ ₯ λ°©λ²μ κΈ°λ₯μ μ΄ν΄νκ³ μνΈ μμ© μ€κ³μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄λ©΄, μ μΈκ³ μ¬μ©μλ₯Ό μν΄ λ§€λ ₯μ μ΄κ³ μ κ·Ό κ°λ₯νλ©° μ¦κ±°μ΄ XR μ ν리μΌμ΄μ μ λ§λ€ μ μμ΅λλ€. WebXR κΈ°μ μ΄ κ³μ λ°μ ν¨μ λ°λΌ, 물리μ μΈκ³μ κ°μ μΈκ³ μ¬μ΄μ κ²½κ³λ₯Ό λμ± λͺ¨νΈνκ² λ§λλ λμ± μ κ΅ν μ λ ₯ λ°©λ²μ΄ λ±μ₯ν κ²μΌλ‘ κΈ°λν μ μμ΅λλ€.
μ¬μ©μ μνΈ μμ©μ μΈλΆ μ¬νμ μ£Όμλ₯Ό κΈ°μΈμ΄κ³ μ΄λ¬ν λͺ¨λ² μ¬λ‘λ₯Ό ν΅ν©ν¨μΌλ‘μ¨ κ°λ°μλ μ μΈκ³ μ¬μ©μμκ² μ§μ μΌλ‘ λͺ°μ κ° μκ³ μ§κ΄μ μ΄λ©° μ κ·Ό κ°λ₯ν WebXR κ²½νμ λ§λ€ μ μμ΅λλ€. XRμ λ―Έλλ λ°μΌλ©°, μ¬λ € κΉκ³ μ¬μ©μ μ€μ¬μ μΈ λμμΈμ μ§μ€ν¨μΌλ‘μ¨ μ΄ νμ μ μΈ κΈ°μ μ μ μ¬λ ₯μ μ΅λν λ°νν μ μμ΅λλ€.