"매 visual motion 과 vestibular 의 mismatch 의 motion sickness 의 trigger". 매 VR 의 가장 큰 UX 장벽 — 매 frame rate / FOV / locomotion 의 careful design 의 mitigation. 2026 의 Quest 3 / Vision Pro / PCVR 의 90Hz+ 의 default — 매 여전히 design pattern 의 핵심.
매 핵심
매 원인
Sensory mismatch: 매 eye 의 motion 의 perceive — 매 inner ear 의 stationary 의 report.
Low frame rate: <72fps 의 judder 의 sickness 의 trigger.
Vection: 매 large optical flow 의 self-motion 의 illusion.
Latency: motion-to-photon >20ms 의 mismatch 의 amplify.
FOV motion: peripheral 의 motion 의 sensitivity 가장 큼.
매 mitigation 기법
Teleport locomotion: 매 smooth 대신 fade-to-black + jump.
Tunnel vision (vignette): 매 motion 시 peripheral mask — 매 vection 감소.
Snap turning: 매 smooth rotation 대신 30° step.
Comfort settings: 매 user 의 individual tuning.
High frame rate: 90Hz+ 의 mandatory — Quest 3 의 default 90/120Hz.
Stable horizon: 매 cockpit / fixed reference frame.
매 응용
Beat Saber — 매 stationary play 의 zero motion sickness.
Half-Life Alyx — 매 teleport + smooth 의 toggle.
매 자전거 simulator — 매 physical motion 의 real vestibular alignment.
💻 패턴
매 Three.js + WebXR 의 framerate 의 monitor
import*asTHREEfrom'three';constrenderer=newTHREE.WebGLRenderer({antialias: true});renderer.xr.enabled=true;letlastTime=performance.now();renderer.setAnimationLoop((time)=>{constdt=time-lastTime;if(dt>14)console.warn(`Frame drop: ${dt.toFixed(1)}ms`);// 매 <72fps 의 경고
lastTime=time;renderer.render(scene,camera);});
매 Vignette 의 motion 시 적용
// fragment shaderuniformfloatu_vignetteStrength;varyingvec2vUv;voidmain(){vec2center=vUv-0.5;floatdist=length(center);floatvignette=smoothstep(0.5,0.3-u_vignetteStrength*0.2,dist);gl_FragColor=vec4(color.rgb*vignette,1.0);}
// 매 movement 의 detect 후 strength 의 ramp
constspeed=velocity.length();material.uniforms.u_vignetteStrength.value=THREE.MathUtils.clamp(speed/5,0,0.6);
매 Snap turn 의 implementation
letlastTurnTime=0;constSNAP_ANGLE=Math.PI/6;// 30°
constCOOLDOWN=250;functionupdate(controller: THREE.Group,input: GamepadAxes){constnow=performance.now();if(Math.abs(input.thumbstickX)>0.7&&now-lastTurnTime>COOLDOWN){rig.rotation.y-=Math.sign(input.thumbstickX)*SNAP_ANGLE;lastTurnTime=now;fadeOutIn(50);// 매 brief blackout 의 ease
}}
// 매 vehicle simulator 의 cockpit mesh 의 always-visible
constcockpit=newTHREE.Mesh(cockpitGeo,cockpitMat);camera.add(cockpit);// 매 head 에 follow — 매 vestibular reference
scene.add(camera);
매 Comfort 설정 의 노출
constsettings={movementType:'teleport'as'teleport'|'smooth',vignetteEnabled: true,snapTurn: true,snapAngle: 30,};// 매 in-game menu 의 user 노출 — 매 individual variance 의 대응
매 Latency 의 측정
constxrSession=renderer.xr.getSession();xrSession?.requestAnimationFrame((time,frame)=>{// 매 frame.predictedDisplayTime - performance.now() = motion-to-photon
});
매 결정 기준
상황
Approach
Casual user
teleport + snap turn (default)
Hardcore VR
smooth + comfort toggle
Vehicle sim
cockpit + stable horizon
Stationary game
minimal locomotion (Beat Saber)
Motion ride
physical motion 의 sync
기본값: teleport + snap turn 의 default. 매 user toggle 의 expose.