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

Reprojection Cache

프로그래밍 2011. 12. 27. 02:00
Posted by cagetu
안녕하세요. 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 

댓글을 달아 주세요

  1. Favicon of https://gamedevforever.com ozlael 2011.12.22 16:27 신고  댓글주소  수정/삭제  댓글쓰기

    reprojection cache 한표

  2. Favicon of http://sumnomm.blog.me sumnomm 2011.12.27 02:41  댓글주소  수정/삭제  댓글쓰기

    SSAO나 그림자의 프레임을 반토막을 내서 속도를 증가시킨다는 외국글
    을본적이 있었는데 중첩해서 퀄리티를 올릴수도 있었군요!!

    • Favicon of http://cagetu.egloo.com cagetu 2011.12.27 09:24  댓글주소  수정/삭제

      예. 다운 샘플링은 필수로 해야할 것 같아요. 물론, 다시 원래 해상도로 복원할 때 이슈가 있기는 하지만, 처리 속도상이나 메모리 사용량 면에서 최적화를 해주어야 합니다.
      나둥에 다운 샘플링 > 업 샘플링도 한번 다루어 불게요. ^^

  3. Favicon of https://gamedevforever.com 핑속 2011.12.27 10:17 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 잘 봤습니다 ^^

  4. Favicon of https://gamedevforever.com ozlael 2011.12.27 10:20 신고  댓글주소  수정/삭제  댓글쓰기

    이제 코드를 주세요 !!!!!!!

  5. sgpro 2011.12.27 10:41  댓글주소  수정/삭제  댓글쓰기

    고맙습니다. ^^

  6. Favicon of https://gamedevforever.com 친절한티스 2011.12.27 10:47 신고  댓글주소  수정/삭제  댓글쓰기

    이제 코드를 주세요!!!

    우와 좋아보인다. 속도 향상도 상당하겠네욤.

  7. Favicon of https://gamedevforever.com 알콜코더 2011.12.27 11:03 신고  댓글주소  수정/삭제  댓글쓰기

    오.. 이런 테크닉이.. 이런게 가능하지 않을까.. 생각은 많이 했었는데.. 여러가지 이유로 불가능할거라 생각했는데..
    실제로 응용한 기술이 있군요.. 멋집니당~~

    자. 이제 코드와 샘플을 올려주세염..

  8. Roi 2011.12.27 11:39  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다.

  9. Favicon of https://gamedevforever.com Silverchime 2011.12.27 11:45 신고  댓글주소  수정/삭제  댓글쓰기

    잘봤습니다! 멋진 트릭이네요

  10. Favicon of https://gamedevforever.com 랩.좀비 2011.12.27 15:03 신고  댓글주소  수정/삭제  댓글쓰기

    올. 좋은 글 감사합니다.

  11. 유래너스 2011.12.27 17:19  댓글주소  수정/삭제  댓글쓰기

    글내용과는 상관없는 여담입니다만

    "나가시와 젠지"가 아니고 "니시카와 젠지" 입니다.^^;

  12. Favicon of https://hgcoder.tistory.com hgcoder 2011.12.27 18:30 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 내용 감사합니다 ^^ 그림자 지글거리는데 적용해보면
    어떨지 시도해 봐야겠어요 ㅎㅎ

    • Favicon of https://gamedevforever.com cagetu 2011.12.27 18:48 신고  댓글주소  수정/삭제

      저는 그림자 관련해서는 많이 보지는 않았지만, 논문이 있던 것 같아요. ㅎㅎ. 찾아보시면, 논문님께서 잘 알려주실거에요.. ^^

  13. Hybrid 2011.12.27 23:12  댓글주소  수정/삭제  댓글쓰기

    우아 멋지다. 배트맨 아캄시티에서 그림자가 지속적으로 지글 거렸는데, 그게 이거 때문이었나보네요.
    (아니면 다른 이유인가.......;)

    • Favicon of http://cagetu.egloo.com cagetu 2011.12.28 06:51  댓글주소  수정/삭제

      언리얼 그림자에 적용되었는지는 모르겠어요. 셰이더 코드를 한번 열어봐야겠네요. ㅎㅎ

    • Favicon of https://gamedevforever.com 김포프 2011.12.28 08:31 신고  댓글주소  수정/삭제

      Gears of War 2에서부터 epic games에서는 SSAO를 여러 프레임에 걸쳐 계산했었어요. 그러니 언리얼 엔진에도 들어가 있지 않을까요?

  14. Favicon of https://gamedevforever.com 대마왕J 2011.12.30 11:17 신고  댓글주소  수정/삭제  댓글쓰기

    우오앙 멋지다 ㅇㅇ 코드내놔요 코드