안녕하세요. 프로그래머 cagetu입니다.
오늘은 Bloom 효과에 대해서 이야기해볼 생각입니다. 특별히 제가 설명하지 않아도 다들 무엇인지 아실정도로 너무나 잘 알려져 있고, 이미 많은 게임에서 사용하고 있는 기술입니다. 일명 뽀샤시 효과라고 하지요?! ㅎㅎ
(이미지 출처: http://photohistory.tistory.com/2322)
이처럼 보편적인 내용을 제가 또 다루어보는 이유는 저도 만들어보면서 참 어려웠기 때문입니다. 이 기술을 적용했을 때 뭔가 이렇게 환상적으로 좋아지는 결과를 생각하지만, 실제로 구현을 해보면 의외로 원하는 결과를 얻는 것이 생각보다 쉽지 않았습니다.
그래서 오늘은 Bloom 효과가 어떤 것인지에 대해서 알아보고, 게임에서 Bloom을 어떻게 하면 좋게 만들 수 있을지에 대해서 제가 고민하면서 이런 저런 자료를 통해서 알게된 내용을 한번 정리해서 이야기 해볼까 합니다. 그렇다고 제가 이렇게 하면 완벽한 Bloom을 만들 수 있어요! 라고 이야기하는 건 아닙니다. 그걸 알면 저에게 알려주세요~. ^^
(분량 관계로 자세한 설명에 대해서는 관련 자료를 링크해서 설명하도록 하겠습니다.)
그렇다면 Bloom 효과란 무엇일까요?
카메라 렌즈에 빛이 들어올 때 카메라가 100% 정확히 그 빛의 정보를 담아내지 못하기 때문에, 태양과 같이 강렬한 빛을 찍으면 실제로 보이는 빛보다 더 큰 면적으로 찍히게 됩니다. 이런 현상은 마치 빛이 퍼져보이는 것과 같은 효과를 나타냅니다. 이것을 흉내내서 처리하는 것을 우리는 Bloom 효과라고 합니다.
Bloom 효과의 정의는 다음과 같습니다. 보신 바와 같이 "강한 빛을 찍으면 실제로 보이는 빛보다 더 큰 몇적으로 찍히게 됩니다" 가 가장 큰 포인트입니다. 따라서, 위에서 언급한 Bloom의 성질에 의하면, 사실 위에서 처럼 강제로 뭉개서 뽀샤시 하게 만든 것은 실제로 Bloom의 성질과는 맞지 않습니다 (물론, 설정에 따라서 만들어 내지 못하는 것은 아닙니다만...). 즉, Bloom 효과와 뽀샤시 효과를 같은 것이 아니라는 이야기입니다. 우리가 만들려고 하는 것은 강한 빛을 받는 부분이 번지는 것이지 화면이 전체적으로 뽀샤시해지는 것이 아니라는 것을 정확히 해야 합니다!
그렇다면 게임에서 Bloom을 만들려면 어떻게 해야 할까요?
가장 먼저 Bloom하면 빼놓을 수 없는 것이 HDR(High Dynamic Range)이기 때문에 HDR을 이야기 하지 않을수가 없습니다. 하지만, HDR이란 주제가 너무 방대하기 때문에, 여기서는 제가 이전에 발표했던 자료로 대체하도록 하겠습니다.
(알콜코더님의 발표자료도 함께 보시면 좋아요: http://gamedevforever.com/168)
게임 그래픽 특히 포스트 프로세싱이 본격적으로 사용되고 있는 현 시점에서 HDR은 굉장히 큰 의미를 가지고 있습니다.
Bloom 이라는 효과의 기본 또한 HDR입니다 입니다. 물론 HDR을 사용하지 않다고 하더라도 Bloom 효과 자체는 표현이 가능합니다. 그래서, 우리는 구현 방식에 따라서, HDR Bloom과 LDR Bloom (유사 HDR)로 구분해서 사용을 하기도 합니다. 모든 Bloom 파이프라인을 Float Buffer에서 처리하는 방식을 HDR Bloom이라고 하고, HDR 장면을 LDR로 변경시킨 후 Bloom 파이프라인을 처리하는 것을 LDR Bloom 이라고 합니다.
[HDR Bloom 과 LDR Bloom "HDR In Valve's Source Engine" Siggraph 2006]
그럼 간단하게 Bloom 효과를 만들어 내는 방법을 알아보도록 하겠습니다.
- 렌더타겟에 장면을 렌더링 한다.
- 렌더타겟에 렌더링된 장면에서 밝은 부분을 추출해서 렌더링한다.
- 추출해낸 밝은 부분을 가진 렌더타겟을 블러시킨다.
- 렌더링된 장면 렌더타겟과 블러된 렌더타겟과 합성한다.
그럼 여기서 좀 더 나은 Bloom을 만들기 위한 방법들을 한번 알아보도록 하겠습니다.
* 밝은 부분을 추출하자!
블룸 현상은 강렬한 빛이 찍혔을 때 나오는 현상이기 때문에 실제로 렌더링된 장면에서도 이런 특성에 맞추어서 밝은 영역을 잘 추출해내는 것 가장 중요한 문제입니다. 하지만, Bloom을 처리할 때 부딪히는 문제 중에 하나가 바로 여기에 있습니다.
실제 화상에서는 어지간히 강한 빛이 아니면 큰 번짐 효과가 나오지 않습니다. 이와 마찬가지로 HDR 렌더링이라고 하더라도 장면의 밝은 영역의 대역이 너무 낮은 영역에 포진되어 있다고 하면, 원하는 밝은 부분을 추출하기가 쉽지 않습니다. 그런 이유로 위와 같은 디퓨즈 영역까지 블룸이 적용되는 원하지 않는 결과가 발생하게 됩니다. 물론, 의도적으로 이렇게 뽀샤시한 느낌을 주기 위해서 낮은 영역을 포함하기도 합니다.
[밝은 영역 추출하기]
이처럼 밝고 어두운 부분의 영역이 충분하지 않다면, 전체적으로 어두어야 할 부분도 번져버리는 결과가 나타나게 됩니다. 이렇게 올바르지 않은 밝은 영역을 찾는 것을 줄이기 위해서는 방법은 무엇이 있을까요?
- Bloom Curve
물리적으로 올바른 방법은 아니지만, Bloom에 의해 불필요하기 밝아지게 되는 부분을 줄이기 위해서 Bloom Curve를 적용하여 밝은 부분과 어두운 부분의 영역을 보장시킨다. 이는 Bloom을 적용하기 전에 HDR buffer에 curve를 적용해준다.
[Halo3 사례 Gamefest "HDR The BUNGIE Way"]
- Physically Based Lighting
물리적으로 올바르게 밝은 영역의 대역대는 높게 렌더링 하는 방법입니다. 즉, 재질의 specular 부분의 에너지를 높게 적용하도록 라이팅 모델을 적용하는 것입니다. 자세한 설명은 나중에 다시 한번 하기로, 아니... 그냥 이 문서를 보시면 될 것 같습니다.
(http://simonstechblog.blogspot.com/2011/12/microfacet-brdf.html)
[Siggraph2010 "Physically Motivated Shading Models for Game Development"]
* 좀 더 높은 퀄리티의 블러 만들기
우리는 Bloom 효과를 만들기 위해서, Bloom 이미지를 부드럽게 블러시키기 위해서 Gaussian Blur를 사용합니다. 하지만, Gaussian Blur는 커다란 블러 반경에다가 부드럽게 블러를 먹이려고 한다면, 부하가 높아서 리얼타임으로 사용하기가 어렵습니다. 그렇기 때문에 보통 Bloom 이미지를 다운스케일해서 블러시키면 좀 더 넓은 영역을 블러 시킬 수 있기 때문에 많이 사용하지만, 이럴 경우 퀄리티가 많이 훼손되게 됩니다. 이런 퀄리티를 높이기 위해서는 어떻게 해야 할까요?
- Multiple Gaussian Filter
Masaki Kawase 씨가 발표하신 내용으로 좀 더 저렴한 비용으로 높을 퀄리티를 내기 위해서 소개한 방법입니다. 자세한 설명은 이 페이지를 참고하시면 좋을 듯 합니다(http://allosha.tistory.com/50).
[GDC2004 "Practical Implementation of High Dynamic Range Rendering"]
이 기법은 이후 다른 게임들에도 많이 사용되었는데, Halo3의 구현 사례를 보도록 하겠습니다.
Halo의 경우도, 유사하게 단계적으로 블룸 이미지를 다운스케일하여 그 이미지들을 블러시켜서 합성해주는 방법을 사용합니다. 이렇게 하면 일반적으로 Bloom 샘플에서 보여지는 한장의 다운스케일 이미지를 이용해서 Bloom을 처리하는 방식보다 높은 퀄리티로 넓은 범위를 블러시키는데 도움을 줍니다.
- Flickering Artifact
저렴한 비용으로 넓은 범위를 블러시키기 위해서 다운스케일을 많이시키다보면 가우시안 블러를 적용해야 할 블룸 이미지의 픽셀 수가 부족하게 되기 때문에 카메라를 이동함에 따라서, 부족한 픽셀 때문에 블러가 적용되는 범위가 굉장히 영향을 많이 받게 됩니다. 이런 현상은 결과적으로 블러되는 부분이 깜빡 깜빡하게 되는 문제가 발생하게 됩니다.
이를 해결하기 위해서는 다운스케일 할 때, 좀 더 넓은 범위의 픽셀들의 평균으로 내 픽셀의 값을 만들어내면 이렇게 이동에 따른 깜빡거리는 현상을 조금을 줄일 수 있게 됩니다. 하지만, 그렇다고 하더라도 기본적으로는 너무 많은 다운스케일을 하여 픽셀 수가 너무 많이 부족하게 되면 문제가 발생할 수 있기 때문에, 적절히 가우시안 블러의 범위와 다운스케일 사이즈를 결정하는 것이 중요합니다.
* 결론
실제로 Bloom 효과가 렌더링 퀄리티에 미치는 영향은 꽤 큽니다. 그러니, HDR + Bloom의 퀄리티는 전체 화면의 품질을 결정짓는 가장 기본이라고 볼 수 있을 것입니다. 그런 이유로, 지금까지 Bloom 효과를 만들어 낼 때에 고민해봐야 할 것을을 한번 다루어 보았습니다. 우리가 많이 사용하고 있는 Bloom 효과이지만, 의외로 생각할게 많지요?
저도 Bloom을 놓고 고민했을 때, 의외로 정리된 자료가 없고, 원하는 퀄리티가 나오지 않아서, 참 괴로워했습니다(물론, 아직도 원하는 퀄리티를 만들어내지는 못했습니다.. ㅜㅜ). 그래서, 제가 나름 공부하면서 이런 저런 자료들을 보고 적용해본 내용들을 한번 정리해 보았습니다.
어쩌면 저 같이 Bloom 효과에 대해서 많은 고민을 하셨던 분들이 있다면 그 분들에게 제가 고민했던 이런 내용들이 조금이나마 도움이 되었으면 좋겠습니다. ㅎㅎ. (혹시 좋은 결과가 나오시면, 저한테도 그 사례를 공유해주시면 감사하겠습니다. ㅎㅎ)
그럼 이만~ 안뇽~ 우리 딸이랑 놀러 갈게요~ 헤헤~
'프로그래밍' 카테고리의 다른 글
자기만의 게임엔진을 만들어보자! #2 (11) | 2012.06.03 |
---|---|
Screen Space Decal (20) | 2012.06.01 |
사고뭉치를 위한 디버깅 방법 #03 (5) | 2012.05.21 |
PC에서 3D 입체 영상 게임 개발하기 #2 (2) | 2012.05.21 |
WPF로 디아블로 3 자동 로그인 만들어 보기 (31) | 2012.05.20 |