phantom.shader
[ 서론 ]
유튜브를 배회하다 우연히 본 동영상.
보다시피 돈주고 사야하는 Asset임.
공식적인 명칭인지는 모르겠지만 팬텀 쉐이더 (phantom shader) 를
오늘 한번 만들어 보겠음.
[ 본론 ]
1.어떻게 구현했을까?
-시선(카메라) 에서 캐릭터를 향하는 Ray test 후 캐릭터 쉐이더 교체?
구현이 간단하지만 모든 배경오브젝트를 per frame 테스트 하는건 큰 부담이될듯
캐릭터에 쉐이더 하나 넣자고 bounding volume을 설정하는건 배보다 배꼽이 더큰상황.
더군다나 모든 ray test 대상이 되는 배경오브젝트에 tag 나 component 로
힌트를 심어줘야 하는데 이건 아무리 생각해도 노가다고 비효율적이다.
- 동영상을 보면 pro 버젼의 post image Effect 기반임을 알수있다.
- 캐릭터가 차폐물에 가려진 부분만 pixel 단위로 phantom effect 가 나온다.
실시간으로 가려진 부위를 검출하여 그부분의 material 을 찾아낸뒤
shader 를 교체한다는건 정말 무책임한 brutal force (무대포) 라는 이야기다.
따라서 쉐이더 교체는 아닐 확률이 높으므로 최후의 보루로 남겨두자.
2. 눈에보이는것만 얘기하자
- phantom 은 알파블랜딩 되고있다.
- 가려진부분만 phantom 이 pixel 단위로 렌더링된다
- 통상적으로 우리가 사용하는 z-buffer test 는 less 이고
통과한 픽셀에 한해서 z값이 버퍼에 기록된다.
엇 그럼 z-buffer test 를 less 가 아닌 greater 로 바꾼다면 ?
그리고 2pass로 나눠서 캐릭터와 phantom 을 각각 1pass씩 쓴다면?
3. 만들어보자.
- 총 2pass로 나누어서 첫번째 pass 에서는 캐릭터를 간단히 렌더링하고
두번째 pass 는 phantom 을 렌더링하자.
- 어? 그런데 이게 뭐지?
장갑하박쪽과 손가락쪽 그리고 다리부분이 뭔가 이상하다.
사진을 자세히 보면 겹치는곳이 2번이상 z-buffer 연산이 일어나는 convex 한 부분들이다.
언뜻이해가 안간다면 중간이 뚫린 donut 과 sphere 의 차이를 생각해보면 된다
노가다 아저씨의 몸통이나 허벅지부분은 문제가 없지만
손가락이나 장화부분처럼 z test를 두번이상 하게되면
시선과 제일 먼 픽셀을 렌더링 하게 되므로
꼬이게 되버린다.
이를 해결하기위해 pass간 stencil buffer test 를 넣었다.
shader code만 옮기자면
// pass character
stencil {
ref 18
comp always
pass replace //비교에 성공하면 스텐실 버퍼 에 ref 값을 기록해라
}
// pass phantom
stencil {
ref 18
comp notequal
pass keep // 비교에 성공하면 스텐실버퍼값을 유지해라
}
캐릭터 패스에서 18로 기록 하고
팬텀 패스에서는 18이 아닌곳만 랜더링하게 해놨기때문에
겹칠 수가 없다.
그리고 early ztest 를 하기때문에
ztest 에 성공한 부위만 stencil test 를 하게된다.
이제 잘나온다.
3. 만들었다!
- 원리만 심플하게 보이기 위해 유니티 스탠다드 에셋에 있는
노가다아저씨의 디폴트 메트리얼에 쉐이더만 바꿔꼈다.
phantom pass에서는 unity shader tutorial 에 있는 rim lighting 처리 방식으로
아주아주 간단히 phantom느낌이 나게 처리해봤다.
[ 결론 ]
- phantom shader 를 어디다 써야할까?
- 병원이나 공항검색대 같은곳에 x-ray 를 연출
- 동영상에 나온것처럼 던젼이나 벽에 가려졌을때 실루엣 표시
- fps 게임등에서 유료 아이템 구매시 벽뒤에 가려진 enemy를 표시
[ 개선사항 ]
- stencil buffer 에 masking처리후 테스트를 사용해서
특정 오브젝트에서만 phantom이 나올수있게 처리하는것도 좋겠다.
캐릭터를 가리는 모든 오브젝트에 phantom 효과가 렌더링 되면 그건 더이상할테니..
- 장기적으로 보면 post image effect 로 가는게 좋다.
보통은 주인공이 가장화려하기 때문에 material 도 많이 사용하고 shader 도 따로 만들어서 쓰는 경우가 많다.
기존에 만들어 놓은 shader 를 조금이라도 수정해서 쓴다는건 부담스러운 일일수 밖에 없다.
따라서 phantom 효과가 필요한 오브젝트에 한해 component를 추가하고
카메라에 attach 된 post image process script 에서 한방에 처리해주는게 제일 심플할듯싶다.
쉐이더는 첨부파일이나 링크 참조.
덧글|덧글 쓰기|신고