Trouble/Vision

nvdiffrast 사용 시 렌더링 깨지는 문제

침닦는수건 2025. 6. 24. 15:04
반응형

textured mesh를 렌더링하는 툴로 요즘 nvdiffrast를 애용하고 있는데, 약간의 버그 아닌 버그를 발견해서 기록해둔다. 

 

일단 nvdiffrast를 굳이 쓰는 이유는 pytorch3d에 수십만 vertex/face mesh를 올린 뒤 렌더링해보면 오류가 난다. face per pixel 즉 rasterize 과정에서 pixel 당 face를 배정하는 과정에서 face가 너무 많기 때문에 터져버리는 문제가 있다. 이걸 heuristic하게 손으로 틀어 맞춰야 하는데 mesh 데이터를 많이 처리하는 입장에서 이게 너무 번거로웠다. 뚜렷하게 몇개의 vertex/face에서 터지는지도 발견 못하기 때문에 pytorch3d는 오로지 저해상도 textured mesh에서만 유용했다.

 

nvdiffrast는 더 이상 관리가 안되긴 하지만, 현 시점에서는 pytorch3d가 겪는 그런 문제가 없을 뿐더러 쓸 만하다. (좌표계가 좀 지랄맞은 것이 유일한 단점. x값이 뒤집혀 나온다. 따라서 uv 값을 다룰 때 보통 v값만 1-v로 업데이트해주는데 얘는 1-u로 u도 업데이트해줘야 맞는 문제가 있음. anyway)

 

nvdiffrast의 단점 (아래 문제 포함)은 아직까지는 pytorch3d에 비하면 사소한 것 같다. 

 

문제

(좌) -30 도 (중) 0도 (우) 30도

 

위 그림처럼 textured mesh를 각도를 바꿔가면서 렌더링하고, 이를 사용하려고 했는데 어느 순간 위와 같이 렌더링이 안되고 검정색으로 나오는 문제가 생겼다.

 

보통 다른 툴에서 이런 경우 backface culling 문제로 렌더러가 mesh face의 방향을 헷갈려서 렌더링을 안하는 경우였는데, 얘는 좀 달랐다. 아래 중앙 그림과 같이 일부만 안되는건 backface culling 문제로 해석이 안된다. 

 

원인

시간이 조금 흐른 뒤에 우연히 알게 됐는데, 원인은 texture map의 너무 높은 해상도다. 

 

어떻게 발견했냐면, 똑같은 mesh인데 10장 렌더링할 때는 멀쩡하고 20장 렌더링할 때는 10장 때부터 깨지는 걸 보고 뭔가 10장이 한계임을 알고 나서다. 메모리든 뭐든 렌더러가 들고 있는 capacity를 넘어서는 뭔가가 있다는 직감으로 시작해서 디버깅하다가 찾았다. 

 

보통 8K texture map을 사용하는 경우 mesh vertex/face 해상도와 상관없이 깨지는 일이 빈번하고 2K texture map을 사용하는 경우에는 수십장까지 깨지지 않았다. (많이 하면 깨짐. 따라서 분할 렌더링해야 함)

 

내 생각엔 nvdiffrast가 differentaible rendering 툴이다 보니 texture map까지도 뭔가 graph에 포함시킬 경우를 대비해서 매 렌더링마다 texture map을 clone한 뒤 뭔 짓거리를 하기 때문에 그런 것 같다. (H,W,3)의 parameter가 추가되는 셈인데 해상도가 크니 터질 만도...

 

해결법

texture map을 resize하자... 웬만하면 2K를 넘어서지 말자. nvdiffrast 쓸 때는.

반응형