--- id: wiki-2026-0508-시각-전정-충돌-visual-vestibular-confl title: 시각-전정 충돌(Visual-vestibular conflict) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [VVC, visual-vestibular mismatch, sensory conflict] duplicate_of: none source_trust_level: A confidence_score: 0.95 verification_status: applied tags: [vr, perception, sickness, vestibular] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: any framework: vr --- # 시각-전정 충돌(Visual-vestibular conflict) ## 매 한 줄 > **"매 visual motion 과 vestibular system 의 input mismatch 가 sickness 를 유발한다"**. Reason & Brand 의 1975 sensory conflict theory — VR 에서 user 가 see motion but feel stationary (or vice versa) 시, 매 brain 이 conflict 를 poison signal 로 misinterpret. 매 modern VR 의 #1 design constraint. ## 매 핵심 ### 매 메커니즘 - **시각 cue**: optic flow 가 forward motion 을 indicate. - **전정 cue**: 머리 actual movement 가 zero (sitting still). - **Mismatch detection**: vestibular nuclei 가 conflict 를 detect. - **Evolutionary response**: poison hypothesis (Treisman 1977) — nausea, vomit reflex. ### 매 영향 요소 - **FOV**: wider FOV → 매 stronger optic flow → 매 worse VVC. - **Acceleration**: linear acceleration > constant velocity. - **Yaw rotation**: smooth turning 이 worst (snap turn 으로 mitigate). - **Latency**: motion-to-photon > 20ms 시 sickness 가속. ### 매 응용 (mitigation) 1. Teleportation locomotion (no continuous motion). 2. Vignette / tunneling on movement. 3. Snap turn (e.g., 30° increments). 4. High refresh rate (90Hz+, 2026 standard 120Hz). 5. Cockpit / static reference frame. ## 💻 패턴 ### Vignette on locomotion (Three.js) ```typescript import * as THREE from "three"; const vignette = new THREE.ShaderMaterial({ uniforms: { intensity: { value: 0 } }, fragmentShader: ` uniform float intensity; varying vec2 vUv; void main() { float d = distance(vUv, vec2(0.5)); gl_FragColor = vec4(0., 0., 0., smoothstep(0.3, 0.7, d) * intensity); }` }); function onLocomotion(speed: number) { vignette.uniforms.intensity.value = THREE.MathUtils.clamp(speed / 5, 0, 0.7); } ``` ### Snap turn implementation ```typescript const SNAP_DEGREES = 30; let lastSnap = 0; function onThumbstickX(x: number) { const now = performance.now(); if (Math.abs(x) > 0.7 && now - lastSnap > 250) { camera.rotation.y -= Math.sign(x) * THREE.MathUtils.degToRad(SNAP_DEGREES); lastSnap = now; } } ``` ### Teleport locomotion ```typescript function teleport(target: THREE.Vector3) { fadeToBlack(100); setTimeout(() => { rig.position.copy(target); fadeFromBlack(100); }, 100); } ``` ### Frame-rate enforcement ```typescript // 90Hz minimum on Quest 3, 120Hz on Vision Pro const targetFPS = navigator.userAgent.includes("Vision") ? 120 : 90; renderer.setAnimationLoop((t, frame) => { // skip work if budget exceeded }); ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Seated experience | continuous + vignette OK | | Standing / room scale | teleport + snap turn 권장 | | Racing / cockpit sim | static cockpit ref → 매 reduces VVC | | Audience first-time | always teleport default | | Pro user | option for smooth | **기본값**: teleport + snap turn 30° + vignette on continuous motion. ## 🔗 Graph - 부모: [[VR Sickness]] - 변형: [[Vergence-Accommodation Conflicts]] - Adjacent: [[가상현실 멀미 (VR Sickness)]] · [[안구 운동 기능 (Oculomotor Functions)]] - 응용: [[가상현실(VR) 자전거 시뮬레이터]] ## 🤖 LLM 활용 **언제**: locomotion 설계 review · sickness 원인 분석 · UX option 추천. **언제 X**: actual user testing 의 substitute (subjective experience 측정 필수). ## ❌ 안티패턴 - **Smooth locomotion default**: 매 first-time user 의 30%+ 가 sick. - **No comfort options**: accessibility 실패. - **Frame drop tolerance**: 60Hz fallback → severe sickness. - **Forced rotation**: cinematic 의도 → 즉시 sick. ## 🧪 검증 / 중복 - Verified (Reason & Brand 1975 · Stanney VR Handbook · Meta VR Comfort guidelines). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — VVC mechanism + mitigation 코드 |