Files
2nd/10_Wiki/Topics/Programming & Language/VR Sickness.md
T
2026-05-10 22:08:15 +09:00

5.4 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-20260508-vr-sickness-redir VR Sickness 10_Wiki/Topics verified self
cybersickness
simulator sickness
VR motion sickness
none A 0.91 applied
vr
ux
perception
three-js
2026-05-10 pending
language framework
TypeScript Three.js / WebXR

VR Sickness

매 한 줄

"매 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.

매 응용

  1. Beat Saber — 매 stationary play 의 zero motion sickness.
  2. Half-Life Alyx — 매 teleport + smooth 의 toggle.
  3. 매 자전거 simulator — 매 physical motion 의 real vestibular alignment.

💻 패턴

매 Three.js + WebXR 의 framerate 의 monitor

import * as THREE from 'three';

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.xr.enabled = true;

let lastTime = performance.now();
renderer.setAnimationLoop((time) => {
  const dt = time - lastTime;
  if (dt > 14) console.warn(`Frame drop: ${dt.toFixed(1)}ms`);  // 매 <72fps 의 경고
  lastTime = time;
  renderer.render(scene, camera);
});

매 Vignette 의 motion 시 적용

// fragment shader
uniform float u_vignetteStrength;
varying vec2 vUv;

void main() {
  vec2 center = vUv - 0.5;
  float dist = length(center);
  float vignette = smoothstep(0.5, 0.3 - u_vignetteStrength * 0.2, dist);
  gl_FragColor = vec4(color.rgb * vignette, 1.0);
}
// 매 movement 의 detect 후 strength 의 ramp
const speed = velocity.length();
material.uniforms.u_vignetteStrength.value = THREE.MathUtils.clamp(speed / 5, 0, 0.6);

매 Snap turn 의 implementation

let lastTurnTime = 0;
const SNAP_ANGLE = Math.PI / 6;  // 30°
const COOLDOWN = 250;

function update(controller: THREE.Group, input: GamepadAxes) {
  const now = 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
  }
}

매 Teleport locomotion

function teleport(targetPos: THREE.Vector3) {
  fadeToBlack(150).then(() => {
    rig.position.copy(targetPos);
    fadeFromBlack(150);
  });
}

매 Stable horizon (cockpit reference)

// 매 vehicle simulator 의 cockpit mesh 의 always-visible
const cockpit = new THREE.Mesh(cockpitGeo, cockpitMat);
camera.add(cockpit);  // 매 head 에 follow — 매 vestibular reference
scene.add(camera);

매 Comfort 설정 의 노출

const settings = {
  movementType: 'teleport' as 'teleport' | 'smooth',
  vignetteEnabled: true,
  snapTurn: true,
  snapAngle: 30,
};
// 매 in-game menu 의 user 노출 — 매 individual variance 의 대응

매 Latency 의 측정

const xrSession = 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.

🔗 Graph

  • 부모: Virtual Reality UX
  • 변형: VR 멀미 (VR Sickness) · VR 멀미(VR sickness) (Korean variants)
  • 응용: Beat Saber · 가상현실(VR) 자전거 시뮬레이터
  • Adjacent: Vergence-Accommodation Conflicts · 깊이 지각(Depth perception) · Edge Bleeding

🤖 LLM 활용

언제: VR app 의 design 의 comfort 권장, frame rate budget 의 explain, snap turn / teleport 의 trade-off. 언제 X: 매 medical 진단 — 매 individual variance 의 큼 의 인지.

안티패턴

  • <72fps 의 ship: 매 sickness 의 garantee.
  • Smooth-only locomotion: 매 casual user 의 alienate.
  • Forced camera shake: 매 vection 증폭.
  • Unstable horizon: 매 vehicle 의 wobble.

🧪 검증 / 중복

  • Verified (Oculus VR Best Practices, Valve Half-Life Alyx postmortem).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — VR sickness FULL 작성