물에 비친 상을 위한 쉐이더
이번에 만든 쉐이더의 목적은 물 표면에 비친 상을 표현하기위한 쉐이더이다.
좀 더 정확히 말하면 불투명 스프라이트 위에 반투명 스프라이트들이 존재할 때 반투명 스프라이트들의 픽셀중 가장 깊이가 얕은 픽셀만 혼합되고 깊은 픽셀들은 무시되게 된다.
토이 프로젝트를 개발하는데 필요하여 구현하게 되었다.
이상적인 구현방법
맨 처음 계획한 구현방법은 다음과 같다.
s1 -물 표면 이미지에 사용될 쉐이더
ZWrite On
그외 기존 sprite-default와 동일
s2 - 물 위에 비친 반투명 이미지에 사용될 쉐이더
ZWrite On
ZTest Less
AlphaTest on
s1보다 늦게 렌더링 될 것이 보장
s2의 오브젝트들은 깊이가 얕은 것에서 깊은 순으로 렌더링
그외 기존 sprite-default와 동일
하지만 s1은 back to front, s2는 front to back을 보장하면서 s1이 s2보다 먼저 렌더링되는 것을 보장할 수 있는 방법을 찾지 못했다. 따라서 다음 차선책들을 생각하였다.
참고) 이 방식 및 아래 차선책들의 공통적인 문제는 반투명 s1보다 깊은 s2들은 처리되지 않는다는 문제가 있다. 이러한 순서에 의해 발생하는 문제를 해결하고 싶다면 더 추가적인 쉐이더를 만들어 계층을 더 나누면 된다.
s2에 zTest를 기본값인 LEqaul로 두면 같은 Z값 끼리는 혼합이 발생한다. Less로 두면 이를 막을 수 있지만 유니티 내부처리에 따라 다르겠지만 두 오브젝트가 동시에 렌더링된다면 Zfighting이 발생할 수도 있다. unity에서 실제로 실행해본 결과 Zfighting은 발생하지않아 일단 Less로 두었다.
차선책1 : Tranparency sort axis를 (0,0,-1)로 설정
s1 -물 표면 이미지에 사용될 쉐이더
ZWrite On
AlphaTest on
blender : 덮어쓰기
그외 기존 sprite-default와 동일
s2 - 물 위에 비친 반투명 이미지에 사용될 쉐이더
render queue : Transparent+1
ZWrite On
ZTest Less
AlphaTest on
그외 기존 sprite-default와 동일
이 방식의 문제점은 프로젝트에서 모든 Transparent가 먼것에서 가까운 순으로 렌더링 되므로 알파테스트 이미지 정도만 정상사용 가능하고 중간값의 알파값은 제대로 적용되지않고 불투명으로 처리된다. blender를 알파 혼합으로 사용하면 기본 배경색에 대해 혼합되지만 정상적인 색상이 아닌것에는 다름이 없다.
토이 프로젝트에는 딱히 정석적인 혼합은 사용되지 않을 것이기에 이 방식을 사용할 예정이다.
차선책2 : order in layer
s1 -물 표면 이미지에 사용될 쉐이더
ZWrite On
그외 기존 sprite-default와 동일
s2 - 물 위에 비친 반투명 이미지에 사용될 쉐이더
ZWrite On
ZTest Less
그외 기존 sprite-default와 동일
s2 오브젝트 : sort layer를 s1보다 늦게 두고, order in layer를 더 위에 있을수록 낮게 둔다.
이 방식의 문제점은 s2의 위아래가 정수 order in layer로 컨트롤되기에 디테일한 깊이 컨트롤이 불가능하다는 단점이 있다.
차선책3 : 추가 적인 깊이 버퍼링
s1 -물 표면 이미지에 사용될 쉐이더
ZWrite On
그외 기존 sprite-default와 동일
s2Pre - 물 위에 비친 반투명 이미지 동일한 깊이에 겹쳐진 전처리 이미지에 사용될 셰이더
색상 기록없이 깊이 버퍼링만 실행
그외 기존 sprite-default와 동일
s2 - 물 위에 비친 반투명 이미지에 사용될 쉐이더
ZTest equal
그외 기존 sprite-default와 동일
이 방식의 문제점은 s2를 쓰는 오브젝트들을 복사하여 s2Pre를 적용시켜야하기에 두배의 오브젝트를 사용해야한다는 단점이 있다. 그리고 같은 Z값을 가지는 상들은 혼합될 수 있기에 이를 막으려면 스텐실을 추가적으로 사용해야한다.
'그래픽스 > Unity' 카테고리의 다른 글
[Unity 2D Shader] 2D 스프라이트 팔레트 스왑 쉐이더 (0) | 2023.07.24 |
---|