꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.

Reprojection Cache

프로그래밍 2011. 12. 27. 02:00
Posted by 알 수 없는 사용자
안녕하세요. 12일, 27일에 글을 올리고 있는 cagetu입니다. 벌써 2번째 글을 올리는군요. 후후...

제 주요 관심사가 게임에 관련된 그래픽스입니다만, 다른 분들처럼 전공을 한 것이 아닌 그냥 언더그라운드에서 야매(?)로 익힌 것인지라, 최대한 제가 만들어보면서 터득(?)한 내용을 중심으로 이야기를 해볼 생각입니다.
또한,
"나가시와 젠지의 3D 게임 팬을 위한 그래픽스 강좌" 에 올라오는 글들을 잘 보고 있는데 (구글 번역 만쉐!), 2번 중 한 번 정도는 이런 형식의 그래픽스 관련 내용을 올려볼까 생각하고 있습니다.



이번에는 Temporal Coherence 라는 주제로 적어볼까 하는데요?! 제 나름대로는 이 녀석이 꽤 활용도가 높을 것 같다는 생각이 들어서 주제를 정해봤습니다. 동영상 압축 기술에 사용된 녀석이 실시간 렌더링에 적용된 것으로 알고 있구요. 게임에서는 그림자나 Screen-Space Ambient Occlusion과 같은 기술에 주로 사용 됩니다.

핵심 아이디어는 간단합니다. 현재 보고 계시는 화면은 이전 프레임과 현재 프레임을 비교해 봤을 때, 변경된 부분은 아마도 그렇게 많지는 않을 것입니다. 그렇다면, 이전 프레임의 화면과 비교해서, 달라진 부분만 기록하는 방식으로 동영상 압축등의 처리가 가능하겠지요? 이게 Temporal Coherence의 아이디어입니다. (해석하면, "시간에 대한 일관성"?! -_-;;)

이걸 실시간 렌더링으로 가져온 녀석이 Reprojection Cache (혹은 Reverse Reprojection Cache) 입니다.


게임 화면도 마찬가지로, 캐릭터가 뛰어가는 장면을 생각해보신다면, 아마도 평화롭게 뛰어가고 있는 캐릭터는 한 프레임의 장면과 이전 프레임의 장면과의 차이가 아마 거의 없을 것입니다. 물론 속도가 엄청나게 빠른 캐릭터가 있다고 하더라고, 화면에 절반 정도는 이전 프레임에서 보여졌던 장면일 것입니다.
거기에 최근 게임의 그래픽이 이전에 비해서, 높은 수준으로 구현되고 있기 때문에, 더욱 많은 Pixel 연산을 처리하고 있습니다.

이런 게임 화면에서 Reprojection Cache를 이용해서, 변경된 부분만 Pixel 연산을 하고 나머지는 이전 프레임에서 계산된 결과를 재활용할 수 있다면, 화면 대부분의 무거운 Pixel 연산을 그냥 Pass 해버릴 수 있을 것입니다


영상을 보면서, 이야기를 이어가도록 하겠습니다.

Accelerating Real-Time Shading with Reverse ReprojectionCaching[1]
(http://www.cse.ust.hk/~psander/)

영상에서 빨간 부분이 이전 프레임과 비교해서, 없었던 새로운 부분입니다. 생각보다 별로 없지요?!
이 도표가 Reprojection Cache의 전체적인 흐름입니다. 간단하죠?! ㅎ


물론, 가장 이상적인 상태라면, 이전 프레임에서 셰이딩이 완료된 픽셀을 그대로 가지고 와서, 현재 프레임에서 바로 사용하는 것입니다만, 라이팅 계산과 같이 위치에 영향을 받는 픽셀 계산의 경우에는 이전 픽셀을 그대로 가지고 오면 오차가 발생할 것 입니다. 이럴 때에는 Hybrid 하게 이전 프레임의 색상 정보에, 픽셀 정보만 새로 계산하는 형태로 처리를 한다면, 어느 정도는 재활용이 가능할 것입니다. (동영상의 오리 부분을 보세요.)

또한, Reprojection Cache의 이전 프레임의 값을 얻어올 수 있다는 성질을 이용해서, 이전 프레임들의 값들을 시간에 따라 지속적으로 누적시키는 방법을 이용하면, 저렴한 비용으로 높은 퀄리티의 결과를 얻을 수도 있습니다. 이 방식은 그림자나 SSAO에서 주로 사용됩니다.  


[Pixel Correct Shadow Maps With Temporal Reprojection ... [4]]


그림자의 경우에는 알리아싱(지글거림)문제를 해결하기 위해서나  이전 프레임의 그림자 정보를 저장하고 있다가 현재 프레임의 정보에 누적을 시켜줍니다. 이런 형태로 n 프레임이 지나게 되면, 지속적으로 누적된 결과로, 안정적인 결과를 얻을 수 있게 됩니다. (물론, 현실적으로 몇 가지 처리를 해주어야 겠지요?!)

그리고, 게임에서 가장 많이 사용되는 활용되는 부분은 아마도, Screen Space Ambient Occlusion일 것입니다. 그림자와 마찬가지로, 이전 프레임에서 렌더링된 SSAO 결과와 현재 프레임에서 구현 AO의 결과를 누적시키는 방법인데요. 이 방식을 이용해서, 많은 수의 sampling을 하지 않아도, 누적된 결과를 통해서, 많은 수의 sampling을 한 것 과 같은 높은 품질의 AO를 만들어 낼 수 있습니다. (
이에 관련한 논문[2]을 통해서 구현 내용을 보실 수 있습니다.)
 
하지만, 이렇게 시간에 따라 누적을 하게 되면, 움직이는 물체의 경우에는 한 가지 눈에 띄는 오류(artifact)가 있는데요. 움직임에 따라, 누적된 결과의 잔상이 보인다는 것입니다. 
UDK의 사례로 한번 보도록 하겠습니다. UDK 샘플 테스트맵에서 박스를 움직여보면, AO가 미세하게 뒤늦게 따라오는 것을 볼 수 있습니다 . (보이시나요?! ㅎㅎ)


하지만, 얻어지는 이점에 비하여, 이해할 만한 수준의 오류라고 판단이 되기 때문에, 최소한으로 잔상이 보이도록만 유지하는 선에서 구현을 하고 있습니다. (사실 집중해서, 들여다 보니까 저게 보이지, 게임 할 때에는 보이지도 않습니다.)

실제로 Reprojection Cache의 구현 방법은 복잡하지 않습니다. 하지만, 상당히 좋은 효과를 얻을 수 있고요.  이 방식은 motion blur, light shaft와 같이 퀄리티를 위해서는 많은 수의 샘플링이 필요하지만, 많이 blur되어서, 정밀도에 많은 영향이 없는 형태의 처리에서는 충분히 응용할 수 도 있습니다. 

Reprojection Cache의 소개(?) 정도로 글을 적어보았습니다. 간단하게 정리하면, 그냥   
"이전 프레임의 Pixel 정보를 가지고 와서, 재활용한다"
가 되겠군요. (그냥 이렇게 이해하시면 될 듯 합니다. ㅎㅎ)

직접 구현할 경우가 많지는 않을 수 있겠지만, 현/차세대 게임 엔진에서 사용을 하고 있는 기술이고, 앞으로도 계속적으로 다른 기술들의 기초가 될 수 있는 기술이기도 하니 알아두시면 좋지 않을까요?! ^^

[참고자료]
[1] Accelerating Real-Time Shading with Reverse ReprojectionCaching
[2] Bilateral Filtering / Reprojection Cache 소개
[3] http://gl3d.net/148
[4] Pixel Correct Shadow Maps with Temporal Reprojection
[5] 
http://portsnake.tistory.com/entry/gears-of-war2
[6] 
Exploiting temporal and spatial coherence 

반응형
,