GRAPHICS PROGRAMMING

헤어 메시카드의 버텍스 소팅과 SIMD 프로그래밍 토론 기록

jplee 2025. 5. 13. 14:28

2021년 내가 신동 네트워크로 이직 후 이 전 회사인 넷이즈 항저우 동료(한국인)인 그래픽스 프로그래머와 소통 한 내용은 아래와 같다.


 

Neon SIMD와 Compute Shader를 활용한 헤어 메시 렌더링 최적화

기술적 배경

Neon SIMD 기술이 언급된 이유는 OpenGL-ES API 하위 버전 호환성을 중요시하는 프로젝트 환경에서 Compute Shader를 사용할 수 없었기 때문입니다. 이러한 제약 조건 하에서 효율적인 헤어 메시 렌더링 구현을 위한 대안으로 활용되었습니다.

헤어 메시 렌더링 알고리즘

헤어 메시 렌더링 시 핵심은 삼각형을 카메라와의 거리에 따라 적절히 정렬(Sorting)한 후 드로우 콜을 수행하는 것입니다. 매 프레임마다 카메라 위치 변화에 따라 삼각형들을 재정렬하여 새로운 인덱스 버퍼를 생성하고, 이를 통해 렌더링을 수행합니다. 완벽한 정확도의 정렬은 불가능하지만, 시각적으로 허용 가능한 수준의 결과를 보장할 수 있습니다.

구현 방식 비교

Neon SIMD 기반 구현

  • CPU 레벨에서 Neon SIMD 연산을 활용하여 삼각형 정렬 수행
  • 저수준(Low-Level) 프로그래밍 영역에서 세심한 최적화 필요
  • GPU로의 컨텍스트 업로딩 부분이 복잡하며, UE4에서는 C API를 통해 호출

Compute Shader 기반 구현

  • 인덱스 버퍼를 직접 GPU에서 생성 가능
  • Compute Shader에 인덱스 버퍼와 버텍스 버퍼를 입력으로 설정하고 정렬된 인덱스 버퍼를 출력
  • 구현이 상대적으로 단순하고 효율적

정렬 알고리즘

정렬 방식은 단순하게 접근합니다. 삼각형 내 카메라와 가장 가까운 정점의 거리를 기준으로 판별하여 정렬합니다. 초기 구현은 단순한 삽입 정렬(Insert Sorting)으로 시작하여 문제점들을 파악하고 점진적으로 개선하는 방식이 효과적입니다.

현재 접근법의 한계

이 방식의 주요 한계점은 단일 메시 내에서의 정렬만 해결 가능하다는 점입니다. 예를 들어, 서로 다른 캐릭터의 헤어 메시가 복잡하게 겹치는 경우에는 캐릭터 간 알파 정렬이 이루어지지 않습니다. 다만, 최신 게임에서는 이러한 상황이 자주 발생하지 않는 편입니다.

참고 자료

본 논의에서 언급된 구현 방식과는 직접적 연관은 없으나, GPU 기반 병렬 정렬 알고리즘에 관한 추가 정보로 비토닉 정렬(Bitonic Sorting)을 언리얼 엔진의 Compute Shader로 구현한 사례를 참조할 수 있습니다.

 

 

Parallel Bitonic Sorting on the GPU – Compute Shader implementation in Unreal – Valentin Kraft's Portfolio

Download the Plugin for the Unreal Engine here: https://github.com/ValentinKraft/UE4_SortingComputeShader The compute shader that handles the sorting: //Since we can't #include private Engine shaders such as Common.ush we have to copy the needed Shaders fr

www.valentinkraft.de

 


위 토론내용을 바탕으로 AI 와 소통해 보고 있다.

넷이즈 엔진 전문가 토론 요약 (Summary of Discussion with Netease Engine Experts)

핵심 포인트 (Key Points):

이 내용은 넷이즈 엔진 전문가들과의 토론에 관한 요약입니다. 주요 주제는 헤어 메시 렌더링을 위한 삼각형 소팅(정렬) 구현 방법에 관한 것입니다.

1. Neon SIMD 사용 이유

  • Neon SIMD를 사용한 이유는 Compute Shader를 사용할 수 없는 환경이었기 때문입니다.
  • 이는 프로젝트가 OpenGL-ES API의 하위 버전을 지원해야 했기 때문입니다.

2. 헤어 메시 렌더링 방법

  • 머리카락 헤어 메시 렌더링 시 삼각형을 정렬한 후 그리는 방식을 사용합니다.
  • 매 프레임마다 카메라와의 거리에 따라 삼각형을 정렬합니다.
  • 이 과정에서 새로운 인덱스 버퍼가 생성되고, 이를 사용하여 드로잉합니다.
  • 완벽한 정렬은 불가능하지만, 수용 가능한 수준의 결과를 보장할 수 있습니다.

3. 구현 방법 비교

  • CPU/Neon SIMD 방식:
    • CPU에서 정렬 시 Neon SIMD 연산을 사용할 수 있으나, 저수준 프로그래밍을 신중하게 해야 합니다.
    • Neon SIMD로 구현 시 GPU로 컨텍스트를 업로딩하는 부분이 더 복잡합니다(UE4의 C API 사용).
  • Compute Shader 방식:
    • Compute Shader 사용이 가능한 프로젝트라면 동일한 형태로 구현 가능합니다.
    • Compute Shader로 인덱스 버퍼를 생성하여 렌더링할 수 있습니다.
    • 인덱스 버퍼와 버텍스 버퍼를 Compute Shader에 입력으로 설정하고 정렬된 인덱스 버퍼를 출력하면 됩니다.

4. 정렬 알고리즘

  • 정렬은 단순하게 처리됩니다.
  • 삼각형 버텍스 중 카메라와 가장 가까운 정점의 거리를 기준으로 정렬합니다.
  • 단순한 삽입 정렬로 시작하여 문제점을 파악하고 개선하는 방식을 권장합니다.

5. 한계점

  • 이 방식은 한 메시 내에서의 정렬만 가능합니다.
  • 예를 들어, 서로 다른 캐릭터의 머리카락이 겹치는 경우 캐릭터 간 알파 정렬이 불가능합니다(최신 게임에서는 이런 상황이 드물다고 언급).

6. 참고 자료

  • 소팅 알고리즘 관련 참고 링크가 제공되었습니다(Unreal Engine에서의 Compute Shader를 사용한 병렬 바이토닉 정렬 구현).

Neon SIMD vs Compute Shader 구현 방법 비교 분석

효율성 측면의 분석

Neon SIMD 방식 (CPU 기반)

장점:

  • OpenGL-ES 하위 버전 환경에서 사용 가능합니다.
  • 특정 모바일 디바이스나 레거시 하드웨어에서 동작 가능합니다.
  • CPU 아키텍처에 최적화된 SIMD 명령어를 활용하여 병렬 처리가 가능합니다.

단점:

  • CPU와 GPU 간 데이터 전송 병목 현상이 발생합니다. 매 프레임마다 정렬된 인덱스 버퍼를 GPU로 업로드해야 합니다.
  • CPU 리소스를 소비하므로 다른 게임 로직에 영향을 줄 수 있습니다.
  • 저수준 프로그래밍이 필요하여 개발 복잡도가 높습니다.
  • UE4의 C API를 사용한 컨텍스트 업로딩 부분이 복잡합니다.
  • 일반적으로 대규모 데이터셋에서는 GPU 기반 솔루션보다 성능이 떨어집니다.

Compute Shader 방식 (GPU 기반)

장점:

  • 정렬 작업을 GPU에서 직접 수행하므로 CPU-GPU 데이터 전송 오버헤드가 감소합니다.
  • 대량의 삼각형을 병렬로 처리할 수 있어 높은 성능을 제공합니다.
  • CPU 리소스를 절약하여 다른 게임 로직에 더 많은 자원을 할당할 수 있습니다.
  • 구현이 상대적으로 간단합니다 - 인덱스 버퍼와 버텍스 버퍼를 입력으로, 정렬된 인덱스 버퍼를 출력으로 설정하는 방식입니다.

단점:

  • OpenGL-ES 3.1 이상 또는 이에 상응하는 그래픽 API가 필요합니다.
  • 일부 오래된 모바일 기기나 저사양 디바이스에서는 지원되지 않을 수 있습니다.
  • 쉐이더 코드 디버깅이 CPU 코드보다 복잡할 수 있습니다.

성능 비교 분석

  1. 처리 속도:
    • 대량의 헤어 메시 삼각형(10,000개 이상)을 처리하는 경우, Compute Shader는 대규모 병렬 처리 능력 덕분에 Neon SIMD보다 훨씬 빠를 가능성이 높습니다.
    • 소규모 메시(1,000개 미만의 삼각형)에서는 두 방식의 성능 차이가 크지 않을 수 있으며, 오히려 CPU-GPU 데이터 전송 오버헤드 때문에 Neon SIMD가 더 효율적일 수 있습니다.
  2. 메모리 사용:
    • Neon SIMD: CPU 메모리를 사용하고, 정렬 후 GPU로 데이터를 전송해야 합니다.
    • Compute Shader: 대부분의 작업이 GPU 메모리 내에서 이루어지므로 메모리 전송 오버헤드가 적습니다.
  3. 확장성:
    • 복잡한 헤어 스타일이나 여러 캐릭터의 헤어를 처리할 때 Compute Shader가 훨씬 더 나은 확장성을 제공합니다.
  4. 전력 효율:
    • 모바일 디바이스에서는 전력 소비도 중요한 고려사항입니다.
    • 대규모 연산의 경우 일반적으로 GPU가 CPU보다 전력 효율이 좋습니다.
    • 따라서 Compute Shader가 배터리 효율성 면에서 우수할 수 있습니다.

적용 시나리오별 권장 방식

  1. 최신 하드웨어 타겟 프로젝트:
    • Compute Shader 방식이 확실히 유리합니다.
    • 더 나은 성능, 더 간단한 구현, 더 적은 CPU 부하를 제공합니다.
  2. 광범위한 하드웨어 호환성이 필요한 프로젝트:
    • 타겟 디바이스가 Compute Shader를 지원하는지 확인해야 합니다.
    • 지원하지 않는 디바이스가 주요 타겟이라면 Neon SIMD를 사용해야 할 수도 있습니다.
    • 하지만 가능하다면 하드웨어 감지 후 Compute Shader와 Neon SIMD를 선택적으로 사용하는 하이브리드 접근법이 최선입니다.
  3. 복잡한 헤어 렌더링이 필요한 고품질 게임:
    • 확실히 Compute Shader 방식이 더 적합합니다.
    • 더 많은 삼각형을 효율적으로 처리할 수 있고, 추가적인 시각적 개선도 더 쉽게 구현할 수 있습니다.

총평

현대적인 게임 개발 환경에서는 Compute Shader를 사용한 구현이 대부분의 상황에서 더 효율적이고 권장됩니다. 다음과 같은 이유로 Compute Shader 방식이 우수합니다:

  1. 성능 우위: GPU의 병렬 처리 능력을 활용해 더 빠른 삼각형 정렬을 수행할 수 있습니다.
  2. 개발 효율성: 구현이 상대적으로 단순하고, 저수준 CPU 프로그래밍의 복잡성을 피할 수 있습니다.
  3. 리소스 활용: CPU 부하를 줄여 다른 게임 시스템에 더 많은 리소스를 할당할 수 있습니다.
  4. 미래 지향적: 현대 그래픽 하드웨어는 모두 Compute Shader를 지원하며, 이 트렌드는 계속될 것입니다.

다만, 레거시 하드웨어나 특정 모바일 플랫폼을 지원해야 하는 상황에서는 Neon SIMD 방식을 대안으로 고려할 수 있습니다. 이상적으로는 하드웨어 기능에 따라 두 방식을 동적으로 선택하는 접근법이 최적의 해결책이 될 수 있습니다.


실제 성능 비교 상황

소규모 메시(예: 1,000개 미만의 삼각형)에서는 다음과 같은 시나리오가 발생할 수 있습니다:

  1. Compute Shader 방식:
    • 초기 설정 시간: ~0.1-0.3ms
    • 버퍼 전송 시간: ~0.05-0.1ms
    • 실제 계산 시간: ~0.01-0.05ms (매우 빠름)
    • 결과 동기화 시간: ~0.05-0.1ms
    • 총 소요 시간: ~0.21-0.55ms
  2. Neon SIMD 방식:
    • 초기 설정 시간: ~0.01-0.05ms (더 적음)
    • 실제 계산 시간: ~0.1-0.2ms (GPU보다 느림)
    • 결과 버퍼 전송 시간: ~0.05-0.1ms
    • 총 소요 시간: ~0.16-0.35ms

이러한 상황에서는 연산 자체는 GPU가 빠르지만, GPU 사용에 따른 고정 오버헤드가 실제 계산 시간보다 더 커서 전체적으로 Neon SIMD가 더 효율적일 수 있습니다.