부동소수점의 미세한 변화가 셰이더 버그를 해결하다
When the fractional part of a float fixes your shader
Hacker NewsVoronoi 노이즈 셰이더를 제작하던 중 특정 고성능 PC에서만 애니메이션에 미묘한 끊김 현상이 발생하여 원인 분석을 시작했습니다.
- 초기에는 GPU 드라이버의 부동소수점 오작동으로 추정했으나, 실제로는 노이즈 함수 매개변수의 상수 값을 아주 미세하게 변경하는 것만으로 문제가 해결되었습니다.
- 이는 복잡한 그래픽 버그가 하드웨어 드라이버 문제보다 코드 내의 단순 상수 값이나 구현 방식에 극도로 민감하게 의존할 수 있음을 보여주는 사례입니다.
- 부동소수점 연산과 노이즈 함수가 결합된 환경에서 예상치 못한 상수 값의 민감성이나 낮은 수준의 디테일을 점검해 보세요.
Voronoi 노이즈 기반의 셰이더 애니메이션을 제작하던 중, 특정 고성능 PC에서만 미묘한 끊김 현상이 발생하여 원인 분석에 착수했습니다. 초기에는 이 문제가 드라이버의 부동소수점 오작동(GLSL `fract()` 사용) 때문일 것이라는 가설을 세우고, 의 도움을 받아 `fract(x)`를 수학적으로 동등한 `x - floor(x)`로 대체하는 방법을 시도했습니다. 이 방법은 문제가 발생했던 기기에서 끊김 현상을 해결하는 데 성공하며 큰 주목을 받았습니다.
그러나 이후 추가 테스트를 진행한 결과, LLM이 제시했던 '드라이버 문제' 가설은 여러 장치에서 오류가 일관되게 재현되지 않아 무효화되었습니다. 글쓴이는 문제를 해결하기 위해 코드를 단순화하고 노이즈 함수 호출 부분을 검토하는 과정에서 새로운 단서를 발견했습니다.
최종적으로 문제는 노이즈 함수에 전달되는 (parameter)의 상수 값 자체에 극도로 민감하게 의존하고 있음을 밝혀냈습니다. 원래 코드에서 스칼라 승수(`398.0`)를 `398.1`과 같이 아주 미세한 소수점 값을 변경하는 것만으로도 끊김 현상이 사라졌습니다. 이는 복잡한 그래픽 버그가 하드웨어 드라이버의 일반적인 결함보다는 코드 내 단순 상수 값의 변화에 민감하게 반응할 수 있음을 보여주는 사례입니다.
용어 풀이
- GPU
- 많은 계산을 한꺼번에 처리하는 칩. AI 학습과 실행에 가장 많이 써요.
- LLM
- 방대한 글을 학습해 문장을 이해하고 만들어 내는 AI 모델. ChatGPT, Claude, Gemini가 여기에 속해요.
- 매개변수
- 모델이 학습하면서 조정한 내부 숫자. 개수가 많을수록 대체로 모델이 크고 무거워요.