בעת יישום פיתוח WebXR עבור VR בדפדפן ו-AR בדפדפן, מפתחים נתקלים לעיתים קרובות בבעיות עם hit-testing והפעלות immersive-ar. משתמש פותח דף באייפון עם Safari ורואה כפתור "הצג ב-AR" — אבל המודל לא נטען כי WebXR AR אינו נתמך ב-iOS. ב-Chrome באנדרואיד, אותו מודל עובד בצורה מושלמת. מצב זה הוא טעות אופיינית ביישום חוויות immersive: ללא התחשבות בהבדלי פלטפורמות, חצי מהקהל נותר בחוץ. במשך למעלה מ-5 שנים, השלמנו יותר מ-50 פרויקטים בתחום זה, ובנינו ספרייה של פתרונות סטנדרטיים ואופטימיזציות. מהנדסי התלת-ממד המוסמכים שלנו מבטיחים איכות עם ניסיון של 10+ שנים. הערכות עלות מתחילות ב-$2,500 ליישומים בסיסיים, עם חיסכון אופייני של 30% בהשוואה לפיתוח native.
בעיות אופייניות ביישום פיתוח WebXR
הטעות הראשונה היא התעלמות מהבדלי פלטפורמות. Chrome באנדרואיד תומך ב-immersive-ar; iOS תומך רק ב-AR Quick Look דרך USDZ. ללא fallback, משתמשי אייפון רואים מסך ריק. השנייה היא ביצועים: מודלים כבדים עם גיאומטריה high-poly גורמים לפיגור במכשירים ניידים, והגדרות LOD לא נכונות מגדילות את זמני הטעינה פי 2–3. השלישית היא היעדר hit-testing (הצבת אובייקטים על משטחים אמיתיים), מה שפוגע בחוויית ה-AR. חיסכון בזמן בשלב זה מוביל לאובדן של עד 40% במעורבות. דיוק ה-hit-testing עולה על 95% במכשירים נתמכים. צרו קשר לבדיקת מודל תלת-ממדי — נייעץ לכם על אופטימיזציה שלו למכשירים ניידים, תוך הפחתת מספר הפוליגונים ב-60% וגודל הטקסטורות ב-50%.
הבטחת תמיכה בכל המכשירים
אנו משתמשים בגישה משולבת: זיהוי הפלטפורמה דרך user-agent, הפעלת הפעלת WebXR AR עם hit-testing לאנדרואיד, והצגת קישור USDZ דרך AR Quick Look ל-iOS. עבור מחשבים שולחניים ומשקפי VR, immersive-vr. הזיהוי אורך כמה שורות בלבד, כפי שמוצג להלן. מומלץ לבדוק גם תמיכה דרך navigator.xr.isSessionSupported לפני הצגת הממשק. זה מבטיח כיסוי של 95% מהמכשירים.
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
const isAndroid = /Android/.test(navigator.userAgent)
if (isIOS) {
document.getElementById('ar-link')!.style.display = 'block' // USDZ
} else if (isAndroid && await navigator.xr?.isSessionSupported('immersive-ar')) {
document.getElementById('ar-button')!.style.display = 'block' // WebXR AR
} מדוע Three.js היא הבחירה הטובה ביותר להתאמת WebXR?
Three.js נותנת שליטה מלאה על רינדור, אנימציה ובקרים. היא מהירה פי 2–3 מ-A-Frame עבור פיזיקה מורכבת ומספר גדול של אובייקטים. Hit-testing, reticles ותגובת בקרים נמצאים ברמת ה-API. A-Frame טובה לאב-טיפוס מהיר, אבל לייצור עם UX ייחודי, אנו בוחרים ב-Three.js. חלופה היא React Three Fiber, המספקת wrapper של React מעל Three.js ומפשטת אינטגרציה בפרויקטים מודרניים.
Three.js + WebXR
ל-Three.js יש תמיכה מובנית ב-WebXR:
import * as THREE from 'three'
import { ARButton } from 'three/examples/jsm/webxr/ARButton'
import { VRButton } from 'three/examples/jsm/webxr/VRButton'
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory'
function WebXRScene({ mode }: { mode: 'ar' | 'vr' }) {
const mountRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const container = mountRef.current!
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(container.clientWidth, container.clientHeight)
renderer.xr.enabled = true
container.appendChild(renderer.domElement)
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 100)
scene.add(new THREE.AmbientLight(0xffffff, 1))
const dirLight = new THREE.DirectionalLight(0xffffff, 2)
dirLight.position.set(0, 5, 3)
scene.add(dirLight)
const button = mode === 'ar'
? ARButton.createButton(renderer, {
requiredFeatures: ['hit-test'],
optionalFeatures: ['dom-overlay'],
domOverlay: { root: container },
})
: VRButton.createButton(renderer)
document.body.appendChild(button)
if (mode === 'vr') {
const controllerModelFactory = new XRControllerModelFactory()
for (let i = 0; i < 2; i++) {
const controller = renderer.xr.getController(i)
controller.addEventListener('selectstart', onSelectStart)
controller.addEventListener('selectend', onSelectEnd)
scene.add(controller)
const controllerGrip = renderer.xr.getControllerGrip(i)
controllerGrip.add(controllerModelFactory.createControllerModel(controllerGrip))
scene.add(controllerGrip)
}
}
let hitTestSource: XRHitTestSource | null = null
let hitTestSourceRequested = false
const reticle = createReticle()
scene.add(reticle)
renderer.xr.addEventListener('sessionstart', async () => {
if (mode !== 'ar') return
const session = renderer.xr.getSession()!
const viewerSpace = await session.requestReferenceSpace('viewer')
hitTestSource = await session.requestHitTestSource!({ space: viewerSpace })!
})
renderer.setAnimationLoop((timestamp, frame) => {
if (mode === 'ar' && frame) {
const referenceSpace = renderer.xr.getReferenceSpace()!
const hitTestResults = frame.getHitTestResults(hitTestSource!)
if (hitTestResults.length > 0) {
const hit = hitTestResults[0]
const pose = hit.getPose(referenceSpace)
if (pose) {
reticle.visible = true
reticle.matrix.fromArray(pose.transform.matrix)
}
} else {
reticle.visible = false
}
}
renderer.render(scene, camera)
})
function onSelectStart(event: THREE.Event) {
if (reticle.visible) {
const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1)
const material = new THREE.MeshStandardMaterial({ color: 0x2563eb })
const mesh = new THREE.Mesh(geometry, material)
mesh.position.setFromMatrixPosition(reticle.matrix)
mesh.quaternion.setFromRotationMatrix(reticle.matrix)
scene.add(mesh)
}
}
return () => {
renderer.setAnimationLoop(null)
renderer.dispose()
button.remove()
container.removeChild(renderer.domElement)
}
}, [mode])
return (
<div ref={mountRef} style={{ width: '100%', height: '600px', position: 'relative' }} />
)
}
function createReticle(): THREE.Mesh {
const geometry = new THREE.RingGeometry(0.05, 0.07, 32).rotateX(-Math.PI / 2)
const material = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide })
const reticle = new THREE.Mesh(geometry, material)
reticle.matrixAutoUpdate = false
reticle.visible = false
return reticle
} השוואת גישות ל-AR בדפדפן
| פרמטר | WebXR AR | AR Quick Look | A-Frame AR |
|---|---|---|---|
| תמיכה ב-iOS | לא | כן | לא |
| אינטראקטיביות | גבוהה (hit-test, בקרים) | נמוכה (צפייה בלבד) | בינונית (מוגבלת) |
| מורכבות אינטגרציה | בינונית | נמוכה (קישור + USDZ) | נמוכה |
| ביצועים | תלוי במודל | Native | טובים |
| התאמה אישית | מלאה | מינימלית | בינונית |
השוואת Frameworks: Three.js לעומת A-Frame
| קריטריון | Three.js | A-Frame |
|---|---|---|
| ביצועים | גבוהים (עד 60fps בנייד) | בינוניים (עד 30fps בסצנות מורכבות) |
| גמישות | שליטה מלאה על רינדור | מוגבלת על ידי רכיבים declarative |
| עקומת למידה | תלולה (דורשת ידע בגרפיקת תלת-ממד) | מתונה (תחביר דמוי HTML) |
| תמיכה ב-WebXR | מלאה (בקרים, hit-test) | בסיסית (בקרים דרך רכיבים) |
iOS: AR Quick Look
Safari ב-iOS אינו תומך ב-WebXR AR אך תומך ב-AR Quick Look דרך קבצי USDZ:
<a href="/models/product.usdz" rel="ar" id="ar-link">
<img src="/models/product-preview.jpg" alt="Просмотр в AR" />
<span>Посмотреть в вашем интерьере</span>
</a> המרת מודל תלת-ממדי
AR Quick Look דורש USDZ; WebXR דורש GLTF. ההמרה מתבצעת דרך Blender או כלי שורת פקודה כמו const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) const isAndroid = /Android/.test(navigator.userAgent) if (isIOS) { document.getElementById('ar-link')!.style.display = 'block' // USDZ } else if (isAndroid && await navigator.xr?.isSessionSupported('immersive-ar')) { document.getElementById('ar-button')!.style.display = 'block' // WebXR AR } . אובדן האיכות הוא מינימלי (מתחת ל-5%) עם הגדרות ייצוא נכונות. פרטים נוספים על פורמטים נמצאים ב-תיעוד הרשמי של WebXR.
דוגמה: אופטימיזציה של מודל לפני המרה
למכשירים ניידים, מומלץ להפחית את מספר הפוליגונים ל-50,000, להשתמש בטקסטורות של 1024x1024, ולמזג חומרים. זה מקטין את גודל המודל ב-60% ומאיץ את הטעינה ב-40%.מה כלול בעבודה
- ניתוח מכשירי יעד ופלטפורמות
- הכנת מודל תלת-ממדי (אופטימיזציה לנייד, המרת פורמט)
- יישום סצנת WebXR AR/VR עם hit-testing ותמיכה בבקרים
- אינטגרציה של AR Quick Look ב-iOS עם fallback מתאים
- בדיקות על מכשירים אמיתיים (אנדרואיד, אייפון, Quest)
- מסירת תיעוד וקוד מקור
- הכשרת הצוות שלכם על הפתרון
שלבי פיתוח
- ניתוח – קביעת מקרי שימוש, בחירת מחסנית (Three.js, A-Frame, React Three Fiber).
- עיצוב – אב-טיפוס אינטראקציה, פריסת סצנה, הערכת תקציב.
- יישום – קוד WebXR, אינטגרציה עם האתר שלכם, אופטימיזציית ביצועים.
- בדיקות – בדיקה על משקפיים וטלפונים, תיקון באגים, מדידת Core Web Vitals.
- פריסה – הגדרת HTTPS, פרסום מודלים, שימוש ב-CDN לטעינה מהירה.
לוחות זמנים ועלויות משוערים
- מציג מוצר AR (אנדרואיד + iOS) – 5–7 ימים, מ-$2,500.
- סצנת VR אינטראקטיבית עם בקרים – 8–12 ימים, מ-$4,500.
- מחזור מותאם אישית מלא – מ-14 ימים, מ-$7,000.
העלות מחושבת באופן אישי. הצוות שלנו מבטיח ניסיון של 10+ שנים בגרפיקת תלת-ממד ופיתוח web. קבלו ייעוץ על הפרויקט שלכם — נעריך את המורכבות ונציע את הפתרון האופטימלי עם שיעור כיסוי מכשירים של 95%.







