아래에서 퍼옴

http://chulin28ho.egloos.com/5270691

우하하 . 어느덧 4부입니다.
제길 이거 진짜 힘든 강의잖아 OTL

익숙해 지고 나니 별 게 아니긴 한데, 잘 설명하려니까 얽히고 설킨 것들이 너무 많습니다 OTL

어쨌건 지난줄거리 요약

- 불투명인 것들은 Z 버퍼만으로 앞뒤구별이 가능하니, 대충 찍어도 된다.
- 반투명인 것들이 끼어 버리면 문제가 되니, 불투명한 것 먼저 찍고 반투명한걸 나중에 모아서 찍는다.
- 반투명인 것들끼리도 먼저찍히냐 나중에 찍히냐에 따라 문제가 생기기 때문에 반투명한 것들은 순서를 판정해서 뒤에서부터 앞으로 찍어온다.


라는 것입니다.
자 그럼 이번 시간에는...

바로 그 마지막 방법. 반투명한 것들끼리 찍을때 뒤에서 부터 찍는다는 그것 말입니다.
그게 잘 될것 같지만, 생각만큼 잘 되지를 않는단 말입니다 (...)  

자아 예를 들어 봅시다.
아래의 모든 오브젝트는 이제부터 반투명이라고 생각하세요.

그리고 이제 격자 같은거 안그려도 앞뒤 판정은 하실 수 있으시겠죠?


 


네에 이건 뭐 쉽습니다. 당연히 앞에 있는 노란 공이 제일 나중에 그려지겠고,
맨 뒤에 있는 튜브가 제일 먼저 그려지겠죠 하하하.
뭐 이렇게 쉬운걸 문제라고..

하하하 아주 쉽네요


좋습니다. 잘 하셨습니다.
그런데 이 물체들이 누가 앞에 있고 누가 뒤에 있는지를 무엇을 기준으로 판단하는 것입니까?

모든 오브젝트에는 각자가 가지고 있는 피봇(pivot)이라 불리는 포인트가 있지요.
이 포인트와 카메라의 거리로 거리판정을 하는 겁니다. 과연. 뭐 그래픽 하시는 분들이라면 다들 알고 있는 내용.


 

각자 중심이나 아래쪽에 축 하나씩을 가지고 있는데, 그게 피봇점.



그치만 말입니다. 그치만 말예요. 그렇지만 말입니다.

이게 이런 경우도 나온단 말이지요.


 



아래쪽에 넓은 판 하나가 생겼습니다. 주로 '반투명의 물' 을 만들때 사용되는 방식이지요.
자아 위의 그림처럼 반투명의 물과 오브젝트가 있다 칩시다.  그리고 이 반투명들은 모두 Z Read와 Write 를 하고 있습니다.  

카메라는 정직하지요... 반투명인 물체들이 모였으니까 , 뒤에서 부터.. 즉 "카메라로부터 피봇점이 먼 것부터" 그리기 시작합니다.


 

슬쩍 상식적으로 생각해 봅시다. 어떤게 가장 '카메라부터 멀리 있어서 제일 먼저 그려야 할 것' 인가요?

당연히 상식적으로 생각하면 5-4-3-2-1 순서입니다.
반투명인 물 (연두색이지만!) 이 가장 먼저 그려지고 그다음에 4-3-2-1 순으로 그려야 겠지요.

하지만 정말 컴퓨터도 그렇게 생각할까요?

자 언제나 공정하고 냉정한 그래픽연산장치님의 눈으로 쳐다봅시다.
위 그림에서 가장 먼 피봇 점은 5번인가요?
전혀 그렇지 않습니다. 카메라와 피봇 점만 냉정하게 따져보면 , 사실 가장 멀리 있는 것은 4번입니다! 
그리고 그 다음이 5번... 아니 3번인가요?

그다음은 2번, 1번. 이건 뭐 평이하네요.
자 이제  컴퓨터가 그리듯 카메라 뷰에서 그려봅시다.



먼저 가장 멀리 있다고 생각한 4번을 먼저 그립니다.


 

그 다음에 멀리 있다고 판단되었던 물을 그립니다.
그런데 물을 그리려다 보니, 이미 누군가가 물보다 앞쪽에 Z 값을 써 놓았습니다.
그렇습니다. 나뭇잎 4번입니다!! 4번은 피봇으로 따져보면 더 멀리 있지만, 픽셀로 따져보면 더 가까이 있는 것이니까요!!

아아아악 개악마 알파의 저주가 시작되었습니다.


 


게다가 여기서 끝난 것도 아닙니다. 3번과 5번처럼 거리가 애매한 녀석은, 프레임에 따라, 카메라 각도에 따라 서로 우선순위가 엎치락 뒤치락 합니다. 엔진의 거리버퍼가 정밀하지 못하면 더더욱 말입니다.
가끔 절묘하게 동일한 선상에 있다고 판단될때는 여지없이 깨지기도 합니다.
(아래의 그림이 현재 상태에서 정확하지는 않습니다. 보통 아래와 같이 깨지는 경우는 주로 두 평면이 서로 바짝 붙어 있을때입니다)


 


으아아아아악.

나머지 두 개는 문제가 없다고 해도 이미 저 두 잎이 다 망쳐 버렸습니다. 더 해봤자 희망이 없네요.

그렇습니다. 바로 아래와 같은 경우 발생입니다.
물도 반투명, 배에서 나오는 이펙트도 반투명이었습니다.
물의 plan은 꽤 크기 때문에, 카메라는 물보다 이펙트가 멀리 있다고 판단해 버린 것이었습니다 (!!)


이런 경우만 있으면 차라리 괜찮기나 하죠.

아래와 같은건 어쩔껍니까?


 

반투명 안에 반투명이 있습니다.
피봇축이 동일합니다. 어쩔까요 이거?


 

머리카락의 경우도 위험합니다. 저렇게 덮개 모양으로 만드는 데다가, 두꺼워 보이게 하기 위해 여러 겹을 겹치곤 합니다.
저런 머리카락 형태의 문제는, 머리카락의 앞이마 부분은 안쪽머리가 가장 뒷쪽이지만,
뒤통수 부분은 안쪽머리가 가장 앞쪽이라는 겁니다. 엉망이죠.
알파 블렌딩을 충분히 사용하면 저 머리카락은 차마 볼 수 없을만큼 엉망이 됩니다.
 

게다가 머리카락의 텍스쳐는 주로 끝부분이 부드럽게 빠지게 하기 위해 알파 블렌딩을 사용하기 때문에, 어쩔 수 없이 머리카락 전체는 반투명(알파 블렌딩) 을 사용할 수 밖에 없게 됩니다.
그래서 이 문제를 해결하기 위해 주로 쓰는 방법은, 알파 블렌딩을 사용하는 부분을 최소화 하는 겁니다.
아래 그림에서 보면, 머리카락이 제대로 나오지 않은 것을 알 수 있지만, 쉽게 눈치채지 못할 만큼의 면적으로 블렌딩을 했기 때문에 눈속임으로 넘어갈 수 있을 정도가 됩니다.

(좀 더 좋은 예제 있었는데.. 찾으면 업데이트 하겠습니다)


결론은, 실무에서 사용하면 뒤죽박죽이 될 수 밖에 없다는 겁니다.
그래픽 디자이너가 결벽증을 가지고 있는 친구가 아닌 담에야 피봇축을 일일히 가운데에 맞출리도 만무하고,
위와같이 오브젝트가 크거나 덮고 있는 형태면 방법도 없습니다.

네, 방법이 없습니다. 개악마 알파 블렌딩의 패악질을 이길 방법이 없습니다.

사실상 대부분의 게임들이 이런 문제로 골머리를 앓고 있습니다.
그리고 프로그램적으로 완벽히 해결하는 방법은 이제 없습니다.(DX11이 나오면 어찌 될까나..)
나머지는 이 단점을 가지고 어떻게 응용해 나가냐는 거지요.
그리고 그 모든 방법에는 장점이 있고 단점이 있기 때문에,
해결하는 방법은 여러 개이고 그 방법을 때에따라 적절히 섞어가면서 사용합니다.
여기서 그래픽 디자이너와 프로그래머와의 궁합이 얼마나 되느냐 - 커뮤니케이션이 잘 되느냐 - 에 따라 결과물이 판가름나게 됩니다.



일단 위의 경우를 피하기 위해 그래픽팀에서 많이 사용하는 방법은 다음과 같습니다.

- 물체를 잘게 쪼갭니다 :
어찌보면 완벽한 방법입니다. 쪼개면 쪼갤수록 피봇축이 정밀해져서, 앞뒤 판정이 정확해 질 테니까요.
하지만 그런 식으로 가다가는 모든 폴리곤을 쪼개야 할겁니다 OTL
이것도 적절한 수준으로 쪼개는 수 밖에 없지요.

- 알파 부분을 최소화해서 그립니다. :
상당히 소극적인 방법입니다. 잎을 그릴 때 잎 모양으로 아예 모델링 해 버린다던가, 머리카락을 그릴 때에는 정말로 머리카락의 '맨 끝만' 알파 블렌딩을 사용하는 방법입니다. 소극적이지만 효과적입니다.

- 알파 테스팅을 사용합니다. :
이건 다음 시간에 설명하지요.

- Z Write를 사용하지 않습니다. :
역시 다음 시간에 설명하겠습니다.



그리고 프로그램팀에서 많이 사용하는 방법은 다음과 같습니다.

- 렌더링 레이어를 만듭니다 :
강제로 그리는 순서를 그룹화 시켜서 제어하는 겁니다. 예를 들어 반투명이라고 하더라도 'water' 속성인 녀석들은 무조건 반투명 중 제일 먼저 그린다 - 라는 식으로 제어하는 것입니다.
그런 식으로 이펙트나 기후 등 종류에 따라 그리는 순서를 제어합니다. 완벽하진 않지만 크게 제어가 가능한 방법입니다.

- 여러 Pass를 사용하여 그립니다 :
머리 카락등에서 방향에 따라 여러 번에 나누어 그리는 방법입니다. 그래픽에서 얼마나 잘 쪼개주느냐에 따라 다른 결과가 나올 수 있습니다. 때문에 매우 고난이도의 방법이지요.





자아 . 일단 성급하게 결론내려보면 다음과 같습니다.
- 불투명인 것들은 Z 버퍼만으로 앞뒤구별이 가능하니, 대충 찍어도 된다.
- 반투명인 것들이 끼어 버리면 문제가 되니, 불투명한 것 먼저 찍고 반투명한걸 나중에 모아서 찍는다.
- 반투명인 것들끼리도 먼저찍히냐 나중에 찍히냐에 따라 문제가 생기기 때문에 반투명한 것들은 순서를 판정해서 뒤에서부터 앞으로 찍어온다.
- 그래도 피봇으로 앞뒤를 판정하기 때문에, 완벽하게 앞뒤를 구분하는것은 사실상 불가능하다.


이것이 프로그래머와 그래픽 디자이너의 머리를 싸매게 만드는 알파 블렌딩의 저주입니다.

자 그럼 다음 시간에는, 이 문제의 해결책들중 하나인 알파 테스팅과 Z Read/Write 에 대해 좀 더 자세히 설명해 보겠습니다.
5부, 알파 테스팅과 Z Read/Write 에서 뵙지요. (아아 슬슬 지쳐간다...)

Posted by 노을삼킨별
,