프로토타입 연구 개발 및
형상관리
HCI 국제 학회 논문 연구 일지 · 두 번째 편
이번 글에서는 연구 아이디어를 실제 작동하는 시스템으로 구현한 과정과, 그 과정에서의 기술적 복잡성을 어떻게 관리했는지 정리해보고자 합니다.
연구 프로젝트의 프로토타입 구현에는 다양한 기술 스택이 필요했습니다. Unity 클라이언트, 원격 GPU 서버의 Python 파이프라인, TCP 기반 영상 스트리밍, C++ 네이티브 플러그인까지, 서로 다른 언어와 환경에서 동작하는 모듈들을 공동 연구자들과 함께 개발하고 하나의 시스템으로 통합해야 했습니다.
원격 협업 시스템에서 원격 사용자는 현장 환경을 기반으로 재구성된 가상 장면을 활용하는 과정에서 정보 비대칭성과 상호작용의 제약을 경험합니다. 기존 접근법들은 각각의 한계를 가지고 있었고, 이를 해결하기 위해 새로운 기술 스택이 필요했습니다.
📹 영상 스트리밍
✓ 넓은 시야각, 빠른 렌더링
✗ 깊이 정보 부재
✗ 능동적 공간 탐색 불가
📐 Photogrammetry
✓ 점진적 재구성 가능
✗ 해상도·정확도 한계
✗ 표면 중심 메쉬 생성
🧠 NeRF
✓ 고품질 Novel View 합성
✗ 계산량 매우 큼
✗ 넓은 환경 부적합
💡 구현 방향: 3D Gaussian Splatting + 360° 스트리밍
3DGS는 장면을 다수의 가우시안 점(위치, 색상, 공분산)으로 구성하여 명시적이고 빠른 렌더링이 가능합니다. NeRF의 암묵적 표현과 달리 대규모·동적 환경에서도 높은 반응성을 유지합니다.
본 시스템은 실시간 360° 스트리밍(현장 맥락 제공)과 3DGS(자유 시점 탐색)를 통합하여, 룸스케일 수준의 원격 환경 탐색 및 새로운 시각적 인터랙션을 구현하고자 했습니다.
1. 시스템 아키텍처 개요

1.1 요구사항 정의: 무엇을 구현해야 하는가
3DGS를 원격 협업에 활용한다는 연구 방향만으로는 시스템을 구현할 수 없습니다. 이 아이디어를 실제 작동하는 프로토타입으로 만들려면, 추상적인 목표를 구체적인 기능 요구사항으로 번역하는 과정이 필요합니다.
- 실시간 360° 영상 스트리밍: Insta360 카메라로 촬영되는 현장의 맥락을 지연 없이 원격 사용자에게 전달
- 3DGS 기반 장면 재구성: 촬영된 영상으로부터 자유 시점 탐색이 가능한 3D 환경 생성
- 자동화된 파이프라인: 사용자가 수동 명령 없이 촬영만 하면 재구성 진행
- 렌더링 인터랙션 기법 구현: 차폐 인지 탐색과 투시 기반 탐색 등 3DGS 고유 특성을 활용한 시각화 기법
문제는 이 요구사항들이 서로 다른 도메인에 걸쳐 있다는 점이었습니다. 영상 스트리밍은 네트워크와 코덱, 3DGS 학습은 GPU 컴퓨팅, 렌더링은 그래픽스 파이프라인, 각각 영역이 달라 어떤 방식으로 접근해야할지 막막했습니다.
1.2 기술 스택 선정: 개발자와의 논의
공동 연구자들과 각 모듈의 기술 스택을 함께 논의했습니다. 이 과정에서 중요했던 건 "왜 이 기술인가"에 대한 근거를 명확히 하는 것이었습니다.
영상 스트리밍 방식 선정 과정
WebRTC 낮은 지연과 호환성이 장점이지만 Unity 통합이 복잡하고 NAT 문제 있음
UDP 초기 시도했으나 패킷 손실 시 양안 렌즈 360° 영상이 심하게 깨지는 문제 발생
TCP (최종 선택) Unity와 통합 용이, 청크 단위 전송과 ACK 신호로 프레임 손실 제어
이런 의사결정 과정을 문서화해두니 나중에 "왜 이렇게 구현했지?"라는 질문에 근거를 가지고 답할 수 있었습니다.
1.3 하드웨어 리소스 제약과 원격 오케스트레이션

설계 도중 가장 큰 제약은 GPU 리소스였습니다. 3DGS 학습에는 고성능 GPU가 필요한데, 로컬 개발 환경에서는 학습 시간에 너무 많은 시간이 소요되었습니다
해결책은 원격 GPU 서버를 활용하면서 사용자가 복잡한 명령어를 직접 실행하지 않아도 되는 자동화 파이프라인을 구축하는 것이었습니다. Python Paramiko 라이브러리를 통해 SSH 연결을 생성하고, 연구실 원격 서버에서 Structure-from-Motion과 Gaussian 최적화를 순차 실행하는 스크립트를 작성했습니다.
1.4 리소스 관리 및 모듈 간 인터페이스 명세화
네 개의 주요 모듈—Data Collection, Reconstruction, Streaming, Rendering—을 병렬로 개발하려면 각 팀원에게 역할 배분이 필요했습니다. 각 팀원의 기술 스택과 관심사를 파악한 뒤, 강점에 맞는 모듈을 할당했습니다.
🔧 Reconstruction 모듈
Python 기반 원격 GPU 파이프라인 — 서버 인프라에 익숙한 팀원
🎨 Rendering 모듈
Unity 컴퓨트 셰이더 기반 3DGS 렌더링 — 그래픽스 프로그래밍에 관심 있는 팀원
🌐 Streaming 모듈
TCP 기반 영상 송수신 프로토콜 — 네트워크 구현에 흥미 있는 팀원
📦 통합 및 Data Collection
전체 파이프라인 연결과 유니티 클라이언트 구현 — 제가 담당
각자 독립적으로 개발을 진행하되 통합이 원활하려면, 모듈 간 인터페이스를 먼저 합의해야 했습니다. 각 모듈이 어떤 입력을 받고 어떤 출력을 내보내는지, 데이터 형식과 호출 방식을 추상화하여 정의했습니다.
- Streaming: H.264 인코딩 프레임 입력 → TCP 전송 → 바이트 배열 반환
- Rendering: .ply 파일 경로 입력 → 컴퓨트 셰이더 처리 → Texture2D 출력
- Reconstruction: 360° 영상 프레임 입력 → SfM+3DGS 학습 → .ply 파일 출력
- Data Collection: SDK 캡처 입력 → Streaming/Reconstruction 전달
이렇게 기능을 추상화하고 인터페이스를 먼저 합의하니, 각자 개발을 진행하면서도 통합 시 충돌을 줄일 수 있었습니다. 내부 구현 방식은 담당자가 자유롭게 결정하되, 입출력 규약만 지키면 되는 구조입니다.
2. 형상 관리
2.1 Azure DevOps 도입

네 명이 서로 다른 모듈을 개발하면서 코드 버전 관리와 작업 현황 파악이 필요했습니다.
왜 Azure DevOps를 선택했나?
Jira 팀원들이 익숙하지 않아 설정과 관리가 번거로움
GitHub Unity 프로젝트 특성상 용량 제한이 문제
Azure DevOps ✓ 5인 이하 팀 무료, 저장소 용량 제한 없음, Git + 백로그 관리 통합
작업 항목은 Epic → Feature → Task 계층으로 구조화했습니다:
- Epic: 시스템 주요 모듈 단위
- Feature: 각 모듈 내 구현해야 할 기능
- Task: 실제 개발 작업 단위 (예: "FFmpeg GPU 디코더 연동 테스트")
- Task 생성: Feature 하위에 구체적 작업 단위로 분할, 담당자 지정
- 상태 업데이트: To Do → In Progress → Done 상태 변경 시 카카오톡으로 공유
- 블로커 관리: 막힌 부분 발생 시 Task에 코멘트 남기고 담당자 태그
- 완료 검증: PR 머지 후 Task 완료 처리, 다음 의존 작업에 알림
각 Task에 담당자를 지정하고 상태를 업데이트하면서 진행 상황을 실시간으로 확인했습니다. 특히 모듈 간 의존성이 있는 작업은 선행 Task 완료 시 후속 담당자에게 즉시 전달하는 방식으로 병목을 최소화하고자 했습니다.
2.2 브랜치 관리
Azure Repos에서 브랜치 전략을 정리했습니다:
feature/[모듈명]-[기능]: 각 팀원이 독립적으로 개발

실험적인 구현 내용들이 많고 연구 방향에 따라 구현 방향이 새로 생기거나 바뀌다보니 feature가 너무 많고 난잡해졌습니다. 어느 순간 브랜치 목록이 혼잡해지면서 어떤 브랜치가 최신인지, 어떤 브랜치가 머지 대기 중인지 파악이 어려워졌습니다.
2.3 개발 문서화

네 명이 서로 다른 모듈을 병렬로 개발하다 보니, "이 함수가 뭘 하는 거지?", "이 파라미터는 어떤 형식이지?"라는 질문이 자주 나왔습니다. 같은 질문이 반복되고 예전에 설명한 내용을 다시 찾기 어려워지면서 문서화의 필요성을 느꼈습니다.
Google Docs를 활용해 개발 문서를 작성:
- 환경 설정: FFmpeg, CUDA, Insta360 SDK 설치 및 경로 설정 방법
- DLL 빌드: C++ 프로젝트 빌드 → Unity 플러그인 배치 절차
- API 명세: 모듈 간 함수 호출 방식, 파라미터 형식, 반환값
- 레퍼런스: 구현 시 참고한 논문, GitHub 레포, 기술 블로그 링크
- 트러블슈팅: 자주 발생하는 에러와 해결 방법 기록
댓글 기능도 적극 활용했는데, 문서 내용에 질문이 있거나 수정이 필요한 부분은 해당 위치에 직접 댓글을 달아 논의했습니다. 카카오톡처럼 대화가 흘러가버리지 않고 맥락이 문서에 남아 있어서 나중에 참고하기 좋았습니다.
문서화를 시작한 건 프로젝트 중반 이후였습니다. 초반에는 "일단 구현부터"라는 생각에 미뤘는데, 팀원이 이탈했을 때 해당 모듈의 구조를 파악하는 데 어려움을 겪으면서 초반부터 개발과 병행했어야 했다는 걸 깨달았습니다.
2.4 빌드 파이프라인과 자동화

통합 과정에서 특히 까다로웠던 부분은 Native 플러그인 관리였습니다. Insta360 카메라 연동을 위해 C++ 기반의 Insta360 SDK를 사용했는데, Unity에서 이를 활용하려면 DLL로 별도 빌드하는 과정이 필요했습니다.
이 과정을 자동화하기 위해 빌드 스크립트를 작성했습니다. C++ 코드 변경 후 스크립트를 실행하면 Visual Studio 빌드 → DLL 파일 복사 → Unity 프로젝트 경로에 배치까지 한 번에 처리되도록 했습니다.
3. 협업과 커뮤니케이션
3.1 주간 미팅 구조
팀원들과 매주 정기 미팅을 진행했습니다. 각자 학업 일정이 달라서 전원이 모이기 어려운 주도 있었지만, 격주 1회는 진행 상황을 공유하는 자리를 만들었습니다.
- 진척 공유 (15분): 각자 지난주 완료한 작업, Azure DevOps 보드 상태 업데이트
- 이슈 논의 (20분): 막힌 부분 공유, 해결 방안 브레인스토밍, 담당자 지정
- 다음 주 계획 (15분): 이번 주 진행할 작업 확인, 의존성 있는 작업 조율
- 액션 아이템 정리 (10분): 결정 사항과 담당자 명시, 카카오톡에 요약 공유
Azure DevOps 보드를 화면에 띄워놓고 각자 Task 상태를 실시간으로 업데이트하면서 이야기했습니다. 미팅 후에는 결정 사항을 카카오톡에 정리해서 공유하고, 이슈가 있는 Task에는 코멘트를 남겨 후속 논의를 이어갔습니다.
3.2 이슈 대응 프로세스
개발 중 이슈가 발생하면 다음 프로세스로 대응했습니다:
- 이슈 발견: 담당자가 Azure DevOps Task에 이슈 내용 기록
- 즉시 공유: 카카오톡으로 관련 팀원들에게 알림, 블로커 여부 판단
- 원인 분석: 담당자 또는 관련 모듈 담당자가 함께 디버깅
- 해결 및 문서화: 해결 방법을 Task 코멘트와 개발 문서에 기록
3.3 갈등과 조율
연구 프로젝트 특성상 일정이 유동적이었고, 몇 가지 갈등 상황이 있었습니다.
예상보다 개발 기간이 길어지면서 한 팀원이 군 입대로 인해 개발을 중단해야 하는 상황이 발생했습니다. 해당 파트는 그 팀원이 아니면 코드 구조를 파악하기 어려운 상태였습니다.
멀티플레이어 오브젝트 상호작용이 화면에 보이지 않는 문제가 있었습니다. 3DGS 렌더링의 그래픽스 파이프라인이 일반 Unity 오브젝트보다 나중에 그려지면서 상호작용 오브젝트를 완전히 덮어버린 것입니다.
멀티플레이어 기능을 위해 Photon 서버를 활용했는데 연구실에서는 연결이 되지 않았습니다. 원인은 교내 네트워크가 Photon 트래픽을 게임 프로그램으로 인식해 차단하고 있었던 것입니다.
연구 프로젝트에서 공동 저자로 참여하는 만큼, 기여가 어느 정도인지에 대한 기대가 달랐습니다.
4. 구현 결과
4.1 Unity 클라이언트: 원격 협업 상호작용 및 시각 렌더링

Unity는 이 프로젝트에서 사용자가 직접 마주하는 시각적 경험과 상호작용을 담당했습니다.
🌐 360° 비디오 구면 매핑

Insta360 카메라의 두 어안 영상을 구면에 매핑해 하나의 360° 뷰로 합성하는 셰이더를 작성했습니다. 경계 영역의 왜곡을 보정하는 알고리즘을 구현해 실시간 360° 영상을 게임 엔진의 텍스쳐로 끊김 없이 렌더링할 수 있게 되었습니다.
👁️ 차폐 인지 탐색

3DGS 모델의 깊이 정보를 활용해 인접 픽셀들의 깊이 값을 비교하고, 현재 카메라 위치 기준으로 어떤 영역이 폐색되어 있는지를 실시간으로 계산합니다. 감지된 폐색 영역은 하이라이트로 시각화됩니다.
🔍 투시 기반 탐색

3DGS의 각 가우시안 포인트가 개별적인 알파 값을 가지고 있어 렌더링 단계에서 반투명 효과가 가능합니다. 사용자가 물체를 투과해 그 너머의 공간을 직접 확인할 수 있습니다.
🔄 중첩 장면 블렌딩

실시간 360° 스트림과 3DGS 장면 사이를 급격하게 전환하면 시각적 불연속으로 인해 멀미를 유발할 수 있습니다. 두 장면을 동시에 렌더링하면서 투명도와 색상 스케일링을 조절해 자연스럽게 전환할 수 있는 기능을 구현했습니다.
4.2 Python 백엔드: 원격 GPU 학습 자동화
Unity 클라이언트에서 버튼 하나만 누르면 다음 과정이 자동으로 진행됩니다:
- 로컬의 360° 영상 데이터를 원격 서버로 전송 (SFTP)
- Structure-from-Motion으로 카메라 포즈 추정
- 3D Gaussian Splatting 학습 실행
- 결과 파일(.ply) 변환 및 로컬로 자동 회수
- Unity 클라이언트에서 즉시 렌더링
4.3 네트워크 레이어: 안정적인 실시간 스트리밍
360° 비디오를 실시간으로 원격 전송하는 것은 네트워크 레이어의 핵심 과제였습니다.

각 프레임은 H.264로 인코딩된 후 작은 청크 단위로 분할되어 전송됩니다. 수신 측은 모든 청크가 도착했는지 확인한 후에만 디코딩을 수행하며, 각 청크의 도착 여부를 ACK 신호로 주고받아 중복이나 손실을 방지합니다.
인코딩과 디코딩 모두 GPU 가속을 적용했습니다. FFmpeg의 h264_cuvid 디코더를 통해 GPU에서 직접 복원하고, NVIDIA NPP 라이브러리를 사용해 NV12 색공간에서 RGBA로 빠르게 변환했습니다.
4.4 정리
최종 구현 영상
🎯 CrossGaussian이란?
원격 현장의 360° 실시간 영상 스트리밍과 3D Gaussian Splatting 기반 장면 재구성을 통합한 협업 인터페이스입니다. 현장 사용자가 Insta360 카메라로 공간을 촬영하면 영상이 실시간으로 원격 사용자에게 스트리밍되는 동시에, 원격 GPU 서버에서 3DGS 학습이 자동으로 진행되어 자유 시점 탐색이 가능한 3D 환경이 생성됩니다.
❌ 기존 화상 회의의 한계
"카메라 좀 왼쪽으로 돌려주세요", "그 뒤에 뭐가 있어요?" — 현장 사용자가 직접 움직여줘야만 원하는 시점을 확인 가능. 의사소통 부담 발생.
✓ CrossGaussian의 해결
3DGS의 명시적 장면 표현으로 원격 사용자가 직접 자유롭게 공간 탐색. 시점 제약과 정보 비대칭 해소.
🔬 3DGS 기반 인터랙션 기법
카메라 시점에서 가려진 영역을 자동 감지하여 하이라이트로 안내
물체를 반투명하게 만들어 그 너머의 공간을 직접 확인
프로토타입 개발에는 대략 5개월이 소요되었습니다. 프로토타입 부터 형상 관리까지의 과정을 돌아보면, 아래와 같은 역량을 키울 수 있었습니다.
✨ 다음 글에서는
완성된 프로토타입을 가지고 사용자 실험을 어떻게 설계하고 수행했는지, 그리고 학회 포스터, 시스템 피규어, 논문 작성과 발표까지의 과정을 다뤄보겠습니다.
연구의 마지막 단계인 "결과를 어떻게 커뮤니티에 전달할 것인가"에 대한 이야기입니다.
'Project Reflection > CrossGaussian' 카테고리의 다른 글
| 국제 학회 HCI 논문 연구 과정 3: 사용자 실험부터 논문 작성·발표까지 (1) | 2025.10.17 |
|---|---|
| 국제 학회 HCI 논문 연구 과정 1: HCI 리서치와 연구 설계 (3) | 2024.09.28 |