Unity/Rendering&Shader

[LIGHT][SHADER] Fake Light - LARA CROFT GO

김성인 2023. 11. 9. 23:34

"라라 크로프트 고" 게임속 라이트

 


 로우 폴리곤의 독특한 그래픽을 보여주는 라라 크로프트 고는 배경의 작은 돌멩이부터, 몬스터, 캐릭터까지 전부 로우 폴리곤으로 제작되어 있다.

 

 재미있는 점은 그에 맞춰 라이트까지 표현되어 있다는 것이다.

 


 게임 속 라이트는 특이점들이 존재한다.

 

하드 엣지 라이트이다.

 

  • 빛에 대한 밝기의 단계, 빛이 미치는 범위의 경계가 로우 폴리곤의 그래픽에 맞춰 칼 갈이 끊어진다.

보통의 라이트는 빛의 감쇄 때문에 경계가 흐릿하다.


광원에서 빛이 발생하여 오브젝트의 표면에 닿는 형태가 아니다.

  • 광원으로부터 빛이 닿지 않을 부분 역시 밝아지는 경우가 자주 존재한다. 하단의 이미지에서 녹색의 영역은 빛을 받는 게 분명하다. 하지만 붉은색 영역은 조금 다르다. 빛이 받는 부분도 존재하지만, 빛이 닿지 않는 부분이 더 많이 존재한다.
  • 물론 반사광 때문에 밝아질 수 있다고 말할 수 있지만, 빛을 받아야 하는 면과 같은 밝기로 밝아지기 때문에, 컴퓨터 그래픽스의 라이트와는 전혀 다르게 만들어진 빛임을 알 수 있다.
  • 오히려 이것은 입체적인 "구" 안에 들어오는 모든 면이 밝아지는 것에 가까운 것 같다.


빛이 닿는 부분(명부)의 색과 밝기로 보아 Additive 형태로 밝아진다.

  • 하단의 이미지는 포토샵에서 작업한 것인데, Additive와는 조금 다른 형태지만 블렌딩 옵션을 Overlay로 두 이미지를 섞었다.  엔진에서는 VFX에서 자주 사용되는 Additive 형태로 블렌딩한 것과 같은 모습이다.

 


 위 3가지 특징으로 도출 할 수 있는 결론은 실제 라이트가 아닌 "3D 이미지로 Additive 블렌딩"을 하는 것이다.

 2D 이미지로 Additive 블렌딩을 하는 것은 문제가 되지 않지만, 3D로 생각하면 이것 저것 문제점이 생기게 된다.



하나씩 이 문제점을 해결 해보자.


블렌딩을 할 때, Additive는 두 가지 타입을 가지고 있다.

 

Blend One One

  • 소스와 대상(이미지의 밑 장, 윗 장) 모두 순수하게 더하기 때문에 색이 너무 강하게 들어간다.


Blend OneMinusDstColor One

  • 소스와 대상 합쳐서 1이 된다. 위의 Add 보다 약하고 부드럽게 색이 들어간다.


컬링을 이용하여 원하는 부분만 남긴다.


스텐실과 뎁스 관련하여 Cyan의 게시물에서 힌트를 얻었는데, Shader에서 pass를 2개로 필요한 부분만 남기면 된다.
그가 공유한 아이디어는 이것이다.

  • Stencil { Ref 1, Comp Always, Pass Replace }, Cull Front, ZWrite Off, ZTest Greater
  • Stencil { Ref 0, Comp Always, Pass Replace }, Cull Back, ZWrite Off, ZTest Greater


Cyan이 공유한 아이디어 : https://twitter.com/Cyanilux/status/1317566480914014212

 

하지만 나는 블랜드 옵션을 Additive로 하여 라이트같이 보이도록 하기 위해서 위의 아이디어를 변경하였다.  내가 생각한 Stencil은 이것이다.

 

  • Stencil { Ref 0, Comp Always, Pass Replace }, Cull Front, ZWrite Off, ZTest Greater
  • Stencil { Ref 0, Comp Equal, Pass Keep }, Cull Back, ZWrite Off, ZTest LEqual

첫번 째 Pass의 색을 Vector4(0,0,0,1)로 변경하면 이렇게 된다.

 

그 다음 Blending 옵션을 OneMinusDstColor One으로 변경하면 Additive로 변경된다.

 

ZTest 관련 문서 : https://docs.unity3d.com/kr/2021.3/Manual/SL-ZTest.html

Stencil 관련 문서 : https://docs.unity3d.com/kr/2021.3/Manual/SL-Stencil.html


2개의 Pass 모두 동일한 Stencil 버퍼를 사용해야 한다.

 완성된 결과물이다.


SRP, URP에서는 스텐실은 렌더러 피처에서 위의 공식에 맞춰 따로 설정 해주어야 한다(조금 귀찮다).


프레임 디버거로 2개의 Pass가 어떻게 렌더링 되고 있는지 확인하면 이해하기 편할 것 같아 첨부한다.

  • RenderTarget, Z 버퍼, Stencil 쪽을 확인하길 바란다.

 

첫 번째 Pass

 

두 번째 Pass


관련 코드와 정리 글 : https://asatala.tistory.com/49