GPU 렌더링 버그, 부동 소수점(Float)의 함정
GPU 인스턴싱(GPU Instancing)을 활용한 샌드 타일 렌더링(Sand Tile Rendering) 과정에서 아티팩트(Artifact) 발생
Z-버퍼링(Z-buffering) 문제, 인스턴싱 코드, 쉐이더(Shader) 코드 검토에도 불구하고 원인 파악 실패
원근 투영(Perspective Projection) 시 발생하는 부동 소수점(Float) 정밀도 문제로 인해 픽셀 값(Pixel Value)이 미세하게 달라지는 현상 발견
CPU 측에서 0.5f를 더하여(Adding 0.5f) 부동 소수점 오차를 해결, 렌더링 아티팩트 제거
GPU 인스턴싱(GPU Instancing)과 렌더링 아티팩트(Rendering Artifact)
본 게시물은 GPU 인스턴싱(GPU Instancing)을 사용하여 샌드 타일을 렌더링하는 과정에서 발생한 렌더링 아티팩트(Rendering Artifact) 문제를 다룬다. 특히, 각 타일의 인접 정보를 8비트 정수로 표현하고, 이를 bgfx의 제약으로 인해 부동 소수점(Float)으로 변환하여 인스턴스 데이터로 전달하는 과정에서 문제가 발생했다. 인스턴스 데이터(Instance Data)의 정확성 부족으로 인해 쉐이더(Shader)에서 예상치 못한 그림자가 나타나는 현상이 발생했다.
부동 소수점(Float) 정밀도 문제와 원근 투영(Perspective Projection)
문제의 핵심은 원근 투영(Perspective Projection) 시 발생하는 부동 소수점(Float) 정밀도 문제에 있다. 3D 그래픽스에서 원근 투영은 픽셀의 깊이에 따라 값을 나누고 곱하는 과정을 거치는데, 이 과정에서 미세한 오차가 발생할 수 있다. 특히, 모든 정점이 동일한 값을 가지는 경우에도, GPU의 픽셀 보간(Pixel Interpolation) 과정에서 이러한 오차가 증폭되어 렌더링 결과에 영향을 미칠 수 있다. 이는 특정 하드웨어에서만 나타나는 문제일 수 있다.
문제 해결: CPU 측 보정(CPU-Side Correction)
해결책은 CPU 측에서 인스턴스 데이터로 전달되는 값에 0.5f를 더하는 것이었다. 이렇게 함으로써, 부동 소수점 연산으로 인한 오차가 발생하더라도, 쉐이더(Shader)에서 해당 값을 정수로 변환할 때 올바른 값을 얻을 수 있도록 했다. CPU 측 보정(CPU-Side Correction)을 통해 렌더링 아티팩트(Rendering Artifact)를 제거하고, 다양한 하드웨어 환경에서 일관된 렌더링 결과를 보장할 수 있었다.
GPU 렌더링 최적화와 트레이드오프(Trade-offs)
본 사례는 GPU 렌더링 최적화 과정에서 발생하는 트레이드오프(Trade-offs)를 보여준다. GPU 인스턴싱(GPU Instancing)은 드로우 콜(Draw Call) 수를 줄여 성능을 향상시키지만, 인스턴스 데이터의 정밀도 문제와 같은 새로운 문제를 야기할 수 있다. 또한, Old OpenGL 지원과 같은 하위 호환성(Backward Compatibility) 유지를 위해 특정 기능을 사용할 수 없는 경우도 발생한다. 따라서, 개발자는 다양한 하드웨어 환경과 렌더링 기법의 특성을 고려하여 최적의 해결책을 찾아야 한다.