docs(10_Wiki): Topic_Business/General/Graphic/Programming을 Topics/ 하위로 이동
최상위 10_Wiki/Topic_*였던 4개 카테고리 폴더를 10_Wiki/Topics/Topic_* 로 재배치. 콘텐츠 변경 없음(순수 폴더 이동) — Topics/ 하위 나머지 폴더는 이미 지난 커밋에서 전부 정리된 상태(잔존 항목은 에이전트 운영 상태 및 사용자가 보존을 요청한 업데이트0615/무제 3.canvas 뿐).
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
---
|
||||
id: wiki-2026-0508-vr-sickness
|
||||
title: VR Sickness
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Cybersickness, VR Motion Sickness, Simulator Sickness]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [vr, ux, perception, comfort]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: csharp
|
||||
framework: unity-xr
|
||||
---
|
||||
|
||||
# VR Sickness
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 vestibular system 매 시각-전정 mismatch 매 만들면 매 nausea 의 발생"**. 매 1990s simulator sickness 연구의 매 VR 확장 — 매 2026 매 Quest 3, Vision Pro, Pico 4 Ultra 매 90Hz+ / foveated rendering 으로 매 줄어들고 있지만 매 design choice (locomotion, FOV) 가 매 dominant factor.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 원인 (Sensory Conflict Theory)
|
||||
- **Visual-vestibular mismatch**: 눈은 movement 보지만 inner ear 는 stationary 신호 — 매 brain 의 "독 상태" 추정.
|
||||
- **Latency**: motion-to-photon > 20ms 매 sickness 급증.
|
||||
- **Low frame rate**: < 90Hz, 특히 dropped frame, 매 trigger.
|
||||
- **FOV manipulation**: peripheral vision movement 매 강한 vection.
|
||||
- **IPD mismatch**: 매 잘못된 inter-pupillary distance 매 eye strain → nausea.
|
||||
- **Acceleration in virtual locomotion**: 매 constant velocity OK, 매 acceleration 의 매 worst.
|
||||
|
||||
### 매 완화 기법
|
||||
- **Teleport locomotion**: 매 smooth move 보다 매 sickness ~80% 감소.
|
||||
- **Tunneling / vignette**: peripheral 의 dark mask, vection 줄임.
|
||||
- **Snap turn**: smooth turn 대신 30~45° 매 step rotation.
|
||||
- **Static reference frame**: cockpit, helmet rim 등 매 fixed visual anchor.
|
||||
- **High refresh + reprojection**: 90Hz 이상 + ATW/ASW.
|
||||
- **Foveated rendering**: 매 GPU budget 매 free up → frame stability.
|
||||
|
||||
### 매 응용
|
||||
1. Beat Saber: stationary play, 매 sickness rare.
|
||||
2. Half-Life Alyx: teleport + smooth 양쪽 옵션, comfort slider.
|
||||
3. Microsoft Flight Sim VR: cockpit anchor, 매 long-session OK.
|
||||
4. No Man's Sky VR: smooth locomotion default — 매 highest sickness reports.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Comfort vignette (Unity URP)
|
||||
```csharp
|
||||
// 매 movement speed 매 따라 매 peripheral mask 매 강도 조절
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public class ComfortVignette : MonoBehaviour {
|
||||
[SerializeField] Vignette vignette;
|
||||
[SerializeField] CharacterController player;
|
||||
[SerializeField] float maxIntensity = 0.6f;
|
||||
|
||||
void Update() {
|
||||
float speed = player.velocity.magnitude;
|
||||
float t = Mathf.Clamp01(speed / 4f); // 4 m/s 매 full vignette
|
||||
vignette.intensity.value = t * maxIntensity;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Snap turn input
|
||||
```csharp
|
||||
public class SnapTurn : MonoBehaviour {
|
||||
[SerializeField] Transform xrRig;
|
||||
[SerializeField] float snapDegrees = 30f;
|
||||
[SerializeField] float deadzone = 0.7f;
|
||||
bool armed = true;
|
||||
|
||||
void Update() {
|
||||
float x = OVRInput.Get(OVRInput.Axis2D.SecondaryThumbstick).x;
|
||||
if (Mathf.Abs(x) < deadzone) { armed = true; return; }
|
||||
if (!armed) return;
|
||||
xrRig.Rotate(0, Mathf.Sign(x) * snapDegrees, 0);
|
||||
armed = false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Teleport locomotion (XR Interaction Toolkit)
|
||||
```csharp
|
||||
// 매 XRI 의 매 TeleportationProvider + arc raycaster 사용
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion.Teleportation;
|
||||
|
||||
public class TeleportTrigger : MonoBehaviour {
|
||||
[SerializeField] TeleportationProvider provider;
|
||||
public void RequestTeleport(Vector3 destination) {
|
||||
var req = new TeleportRequest {
|
||||
destinationPosition = destination,
|
||||
matchOrientation = MatchOrientation.WorldSpaceUp,
|
||||
};
|
||||
provider.QueueTeleportRequest(req);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Frame timing budget check
|
||||
```csharp
|
||||
// 매 frame budget 위반 매 detect — Quest 3 매 11.1ms@90Hz, 8.3ms@120Hz
|
||||
void LateUpdate() {
|
||||
float budget = 1f / Application.targetFrameRate;
|
||||
if (Time.unscaledDeltaTime > budget * 1.2f) {
|
||||
Debug.LogWarning($"Frame overran: {Time.unscaledDeltaTime*1000f:F1}ms");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### IPD calibration
|
||||
```csharp
|
||||
// OpenXR 매 user IPD 매 read — 매 잘못 설정 매 nausea 의 hidden cause
|
||||
using UnityEngine.XR;
|
||||
|
||||
float GetIpdMeters() {
|
||||
var head = InputDevices.GetDeviceAtXRNode(XRNode.Head);
|
||||
head.TryGetFeatureValue(CommonUsages.eyesData, out var eyes);
|
||||
var l = eyes.leftEye.position;
|
||||
var r = eyes.rightEye.position;
|
||||
return Vector3.Distance(l, r);
|
||||
}
|
||||
```
|
||||
|
||||
### Dynamic foveated rendering toggle (Quest 3)
|
||||
```csharp
|
||||
// Quest 3 매 eye-tracked foveation — frame stability 의 강력한 도구
|
||||
OVRManager.eyeTrackedFoveatedRenderingEnabled = true;
|
||||
OVRManager.foveatedRenderingLevel = OVRManager.FoveatedRenderingLevel.HighTop;
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Casual / first-time user | Teleport + snap turn default |
|
||||
| Action / FPS | Smooth + vignette + snap turn option |
|
||||
| Sim (flight, racing) | Cockpit anchor, smooth, 90Hz+ guaranteed |
|
||||
| Standing-only experience | 거의 sickness-free — Beat Saber model |
|
||||
| Seated narrative | Static camera + cuts, no virtual locomotion |
|
||||
|
||||
**기본값**: Comfort menu 의 매 모든 option 매 expose — user 가 choose.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Cybersickness]] · [[Simulator Sickness]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: VR comfort design review, locomotion option 추천, frame budget 분석.
|
||||
**언제 X**: AR / pass-through 만 (vestibular conflict 적음), non-immersive VR / 360 video.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Forced smooth locomotion**: comfort option 의 X — 매 user churn.
|
||||
- **Cinematic camera shake**: VR 매 절대 X — 매 immediate nausea.
|
||||
- **Acceleration / deceleration smooth curve**: linear 보다 매 더 sick.
|
||||
- **Stuttering / dropped frames**: 60Hz 의 매 X — 매 90Hz minimum.
|
||||
- **High-altitude vertigo without snap**: 매 some users 매 panic + sickness.
|
||||
- **No comfort settings menu**: 2026 매 standard expectation.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Oculus Best Practices 2025, Apple Vision Pro HIG, IEEE VR 2025 cybersickness papers).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — sensory conflict theory, mitigation patterns, Unity XR code |
|
||||
Reference in New Issue
Block a user