Z 버퍼의 Read / Write 개념 (6부, Z Read/Write) by 김윤정


아이쿠 예예. 좀 어려웠죠.
저번 시간이 살짝쿵 어려웠을 겁니다.
알파 채널의 '개념' 은 익숙해지지 않으면 잘 안 생기는 개념이라, 그걸 응용까지 하려면 확실히 이해하기 힘들죠.

자아 저번 시간에 이어서, 이번에도 개악마 알파 블렌딩과 싸우기 위한 기술을 알아보는 시간입니다.
저번 시간에는 알파 블렌딩과 테스팅을 적절히 사용하여 개악마 알파 블렌딩의 횡포를 줄이는 법에 대해 알아보았습니다
이번엔 좀 다른 방법으로 개악마 알파 블렌딩을 잡으러 레이드 뛰어 보기로 하죠.

개악마를 잡아봅시다



 




자 , 1강과 2강에서의 Z 값 Read(Test) / Write에 대해 기억 나십니까?

이런 그림이 있으면 그려지기 전 자신의 Z 값을 보고, 자신보다 앞에 있는것이 있는지를 읽는/테스트한(Read/Test) 다고 했지요.

그리고 자신보다 앞에 있는게 없어지면 자신의 Z 값을 다시 쓴다(Write) 고 했었습니다.

네에 이것은 확실한 렌더링의 기본 신조. 꼭 지켜야 하는 내용이었습니다. 안지키면 안되는 법전 같은 것이었지요.

그렇지만, 이것을 조작할 수 있지 않을까요? 뭔가, 조작하면 뭔가, 뭔진 잘 모르겠지만,
하여간 뭔가 일어날 수 있지 않을까요?
뭔가 , 뭔가 말입니다.
Z Read(Test)와 Z Write을 맘대로 조작해 보잔 말입니다.

어차피 이렇게 된거 갈데까지 가봅시다 .






1.     Z Read(Test) = Off     Z  Write = On




자아. 만약 오브젝트를 찍을 때, Z Read를 안하고 Z Write를 한다면 무슨 일이 일어납니까?
으으음.. 머리가 좀 아프지만, 고민해 보자면...

Z Read는 왜 하는 것입니까? 자신의 앞쪽에 누가 있는게 아닐까 - 라고 검사하는 짓을 안한다는 말이지요?
즉 '나는 내 앞에 누가 있건 그냥 그려 버리겠다' 라는 겁니다 !

그러면서 Z Write는 하니까, '그대신 내 뒤의 놈들은 내 Z 값을 인식해서 내 앞에 오는 일이 없도록 하여라' 라고 하는 것입니다.
우왕 이기적이네요. 나는 맘대로 그리겠지만 너는 그러지 말아라 라고용?
(하지만 뭐 자신과 똑같은 Z 옵션을 가진 놈이 뒤에 오면 똑같이 무시되겠지만)

자 그림으로 찬찬히 풀어보도록 하죠.

오랫만에 봅니다. 지금 저 plane이 그려졌습니다. plane은 4의 깊이에 있고 Z read와 Z write 를 했습니다. 그래서 화면에 씌여진 Z값은 현재 4의 상태입니다.
그리고 주전자가 이렇게 나중에 그려졌습니다. 분명히 주전자는 뒤에 있습니다. Z 값으로 따지면 말이죠.
그렇지만 이 주전자는 Z Read가 Off 되어 있습니다. 즉 Z Read 과정을 하지 않도록 되어 있습니다.
그럼 나중에 그려진 이 주전자는, 그리긴 그려야 겠고, 기존에 있는 Z 값을 읽지 않기 때문에, 아무 생각없이 그려버리게 됩니다.
마치 저 plane 앞에 있는 것 처럼 말이죠.

즉 이렇게 보이게 됩니다. 분명히 주전자는 뒤에 있는데도 불구하고 앞에 보이게 되는 기현상이 일어나게 됩니다.

이번엔 그 상태에서 Z 값을 Write를 합니다.하지만 화면이 비어있으면 모를까 지금처럼 자신보다 더 앞의 Z 값이 잔뜩 있는 이 상황에서는 어차피 씌여지지 않으니 이 과정은 무의미합니다.
즉 Z Read를 Off 해 버리면, 앞에 뭐가 있건 무조건 자기가 그릴 타이밍에 그려 버립니다.
무식한 녀석이지요.

특별히 이 녀석을 동영상으로 보면 다음과 같습니다.


훌륭하다 멀티미디어




그렇지만 이 녀석이 앞에 있으면 문제는 달라지는데, 이 녀석 뒤쪽에 일반적인 오브젝트가 그려지면,
 
이번엔 또 그려지는 순서와는 상관없이 아주 정상적인 오브젝트처럼 앞뒤가 결정된다는 것입니다.
왜냐면 이녀석은 Z read는 안하지만 write는 해 놨기 때문이지요.


이런 무식한 녀석을 어디다 쓸 수 있을까요? 남들보다 무조건 앞에 그려버릴 일이 세상에 어디 있을까요? 그러면서 자기 Z 값은 쓰기 때문에, 자신보다 나중에 생기는 일반적인 오브젝트는 자신의 뒤로 가려져야만 합니다.


전혀 쓸모없을 것 같군요. 물론 좋은 점도 있습니다. 자신의 앞 쪽에 무슨 Z 값이 있건 없건 자신은 무조건 그려 버리기 때문에,
알파 블렌딩을 사용할 때 나오는 짤림 현상이 일어나지 않습니다.

이런 현상은 더이상 일어나지 않습니다


그래서 이펙트 담당자들이 이 기능을 쓰고자 하는 유혹을 자주 느낍니다. 이펙트만 놓고 뷰어에서 봤을 때, 짤림 현상이 없이 잘 나오거든요!!! 그래서 잘 되었구나.. 라고 생각한 채 게임에 넘기면, 이번엔 게임에서 이런 현상이 나타나게 됩니다.

네에. 기둥이나 다른 캐릭터, 건물 등을 뚫고 이펙트가 보이게 된다는 거지요. 위의 경우는 기둥을 뚫고 이펙트가 보이는 현상인데, 만약 기둥이 이펙트보다 나중에 그려졌다면 아무 문제가 없지만 '반투명한건 불투명보다 나중에 그린다' 는 원칙에 따르면 저렇게 보일 수 밖에 없는 것입니다. OTL
이펙트면 그나마 낫지요. 머리카락 같은거였다면 난리가 납니다. (얼굴을 뚫고 그려지는 머리카락들...)
네 실패입니다. 이 방법은 알파 블렌딩에 맞지 않습니다.



하지만 정말로 이 기능이 필요가 없느냐? 만약 이 기능을 쓴다면 이런 데 쓸 수 있을겁니다
바로 인터페이스!
인터페이스야말로 모든 게임의 오브젝트의 위에 그려져야만 하고, 그리는 순서를 바꿔줌에 따라 맨 앞에 나와야만 하는 것이므로, 이 옵션에 가장 잘 맞는 데이터입니다.
사실 뭐 게임에서는 굳이 Z 값을 이렇게 안해줘도 프로그래머들이 알아서 처리해 주곤 하지만 말이죠.














2.     Z Read(Test) = On     Z  Write = On


아... 이건 뭐 여태까지 5강동안 설명해 온 것이지 않습니까?
이게 기본이자 진리입니다. 알파 블렌딩이고 테스팅이고 불투명이고 사실은 이걸 써야만 합니다.
이게 안되니까 다른 짓을 하는 겁니다 지금. 하하하.
납득해 주세요.

















3.     Z Read(Test) = Off     Z  Write = Off

자, 둘 다 꺼버렸습니다 !! ㄷㄷㄷ
일단 슬쩍 생각해도 뭔가 정상적이지는 않을 것 같습니다.
그렇다고 피해가지는 맙시다.


차근차근 생각해 보지요. 뭔 일이 일어나겠습니까?
일단 Z read를 하지 않습니다. 즉. 1번과 같이 자신이 그릴땐 아주 소신있게 그려버리는 녀석입니다.
자신의 앞에 뭐가 있건 상관 안합니다.
"사나이 앞길을 막지 마라!" 이것이 Z read Off 입니다.

그런데 이번엔 Z write도 하지 않습니다! 이건 뭥미?
Read는 하지 않고 Write는 하면 인터페이스처럼 사용가능하다고 했습니다. 즉 자신의 뒤에 그려지는 녀석은 자신의 뒤에 가려집니다.
그렇지만 Write도 하지 않으면, 자신보다 나중에 그려지는 녀석이 Z read를 해 보니까, 자신의 앞에 아무것도 없다고 나오게 됩니다!!!! Z 값을 아무도 안 써 놨으니까요!!!!

자신보다 늦게 그려지는 놈한테 덮여집니다!!! 아아 괴이합니다!!!!

다시 한 번 설명하지요.
이런 상태에서

이렇게 주전자를 나중에 그려도,

주전자가 앞에 그려진다는건 똑같습니다.

근데 이 주전자가 앞에 있는 상태에서,  나중에 뒤에 있는 공이 그려진다면?

그렇다면 나중에 그려지는 공은, Z 를 read하려고 시도하겠지만, 주전자가 Z 값을 Write 해 놓지 않았기 때문에
공 입장에서는 앞에 아무것도 없다고 인식하게 될 것입니다.
그러니 나중에 그려진 공이 기존의 주전자를 덮어버리겠지요.

아아 괴이합니다. 이거야말로 괴이합니다. 정말 쓸모가 없게 생겼군요.
생각하기도 복잡하고, 쓰기에도 애매한 놈이 됩니다. 이거 알파 블렌딩에 쓸 수 있는 녀석이 있긴 한 겁니까?

아니 잠깐 진정좀..


알파 블렌딩에 쓸 생각은 일단 접어둡시다. 그전에 이걸 쓸 데가 있기나 한지 궁금하군요.

말씀드리자면, 쓸 데는 거의 없지만 있기는 합니다.
바로 스카이박스 (또는 스카이돔) 입니다.




이 스카이 박스는, 보통 맨 처음에 그려집니다.
그리고 이 스카이 박스에 가려져서 보이지 않는 오브젝트 따위는 존재하지 않습니다.

즉 이 스카이 박스를 그릴 때에는 Z 값을 읽는 (read) 하는 행위가 무의미합니다. 오히려 쓸데없는 계산이 되어 버리기 때문에,
아예 read 안하는 것이 낫습니다.

또한 이 스카이 박스에 가려지는 오브젝트 따위는 없습니다. 무조건 맨 뒤에 그려져야 하는 거지요.
그러므로 괜한 z값 연산을 할 필요가 없는 관계로 쓰는(write) 하는 작업도 무의미합니다.

즉 꼭 그래야 한다기 보다 (Z read on Write on 해도 결과는 같거든요) '할 필요가 없는 연산을 줄여버린다' 라는 의미에서 쓸모가 있는 방법이라고 할 수 있습니다.
그렇다고는 해도 굉장히 마이너한 방법임에는 틀림이 없지만 말이죠 (...)








 


4.     Z Read(Test) = On     Z  Write = Off

이제 남은건 이것밖에 없습니다.
그래! 분명히 마지막에 남은 이것이 해답이라서 맨 마지막에 소개하는걸 꺼야!!!!
라고 생각하시는 분들 반드시 계시겠지요?

글쎄요


어디 한 번 봅시다. 정말 그런지 후후후.
 
아 그런데 이제 좀 퇴근해야겠군요. 이거 쓰는것도 꽤나 힘든 일이랍니다
다음 시간까지 Z read on , Write off 가 정말로 알파 블렌딩을 해결하는 해답이 될지 생각하는게 숙제입니다.




6부작에서 끝내려 했는데 너무 양이 많군요. 애석하게도 7부까지 가야만 하겠습니다.
쓰다보니 조금 지치네요. 읽으시는 분도 꽤 지치셨을 겁니다. 이게 한번에 쉽게 이해되는 개념은 아니거든요.
뭐 이제 거의 다 왔으니까






그럼 다음 시간인
최종회 : Z 버퍼의 Read / Write 개념 (7부, Z Read On / Write Off) 

시간을 기다려 주세요.  

핑백

덧글

  • 식충대마왕 2010/03/19 09:36 #

    좋은 글 잘 읽었습니다!!!
    저희 인터페이스 디자이너 카페에 이 글들을 링크하고 하고 싶은데, 해도 되는지요?
    http://cafe.naver.com/ui.cafe
  • 김윤정 2010/03/19 09:57 #

    아! 인터페이스 카페 말씀이시군요. 저도 가입되어 있긴 합니다 ㅎㅎ (잘 안가지만)
    링크야 얼마든지 가능합니다 :)
  • Makethis 2010/03/19 17:05 #

    아아... 겜브리오를 사용하는 그래픽 디자이너로서... 그냥 작업물 확인하기 위해 어셋뷰어에 작업물 띄우는 정도라만
    알파를 사용하고잇는데...

    프로그래머들이 알파가 먹내 안먹네 뚫네 어쩌네 하는게 이 내용이었군요.

    글 읽고 개념 잡고 갑니다.

    더불어 7강 완료되면 블로그에 출처 밝히고 링크졈 따갈게요.

    고생하십니다.
  • 김윤정 2010/03/19 18:08 #

    감사합니다 :) 좋은 게임 만드세요.
    이거 잘 적용해 주시면 프로그래머들이 무척 고마워 할 겁니다
  • 2010/03/20 13:55 # 비공개

    비공개 덧글입니다.
  • 김윤정 2010/03/20 14:19 #

    아유 과찬이십니다 ... 저도 그분 존경합니다. :)
  • 2010/03/31 21:18 # 비공개

    비공개 덧글입니다.
  • 김윤정 2010/04/01 00:28 #

    감사합니다. 도움이 되셨다니 ^^...
    말씀하신 문제가 아직 안쓴 마지막 강의에서 나오는 부분입니다. A+B+C 랑 A+C+B 랑 같을 것 같은데 알파가 끼니 전혀 다른 결과가 나오게 되지요. 결론부터 말하자면 사실 이건 어느 정도 해결 불가능 (...) . 그래서 말씀하신대로 일정한 레이어 (순서) 를 그룹화 시켜서 해결하는 방법을 사용하긴 합니다만, 파티클끼리와 같이 레이어 그룹이 정해지지 않는 경우에는 강제로 렌더링 순서를 정해주는 수동적인 방식을 사용해야만 합니다. 참 이게 한방에 안끝나죠 ^^
  • 김윤정 2010/04/01 12:00 #

    즉 마지막 줄 숙제를 아주 잘 하신 겁니다 :) 역시!!
  • 2010/06/13 01:35 # 비공개

    비공개 덧글입니다.
  • 2010/06/13 01:37 # 비공개

    비공개 덧글입니다.
  • 김윤정 2010/06/13 01:38 #

    우왕 오타 지적 감사합니다 ㅎㅎ 비몽사몽에 쓴 경우가 많아서 오타가 있네요 . 굳이 비밀글로 안말해 주셔도 됩니다. 뭐 공적인 문서로 쓴 것도 아니고... ^^;;;
※ 로그인 사용자만 덧글을 남길 수 있습니다.


MyADD

<script> (adsbygoogle = window.adsbygoogle || []).push({}); </script>