Blog

ENGINEERING NOTE

[Unreal Engine] 3D Pixel Stylized Shader

3D Pixel Style Shader 불가사의 던전 시리즈의 팬게임을 제작하면서 마을은 2.5D/3D 환경으로 구성하되, 픽셀 캐릭터와 어울리는 시각적 감성은 유지하고 싶었다.

Unreal Engine

3D Pixel Style Shader

불가사의 던전 시리즈의 팬게임을 제작하면서 마을은 2.5D/3D 환경으로 구성하되, 픽셀 캐릭터와 어울리는 시각적 감성은 유지하고 싶었다. 그래서 기존 3D Asset과 조명을 활용하면서도 최종 화면을 픽셀 아트처럼 표현하는 3D Pixel Style Shader를 만들어보았다.

Pixelization

3D 그래픽을 2D처럼 보이게 만드는 가장 간단한 방법은 무엇일까? 바로 원본보다 낮은 해상도로 표현하는 것이다.

물론 실제 화면의 해상도를 변경하는 건 아니다. 화면 해상도를 변경하는 대신 UV를 일정한 크기의 격자에 맞춘다. 그러면 같은 격자 안의 픽셀들이 모두 동일한 위치의 색상을 참조하면서 하나의 커다란 픽셀 블록처럼 보이게 된다.

이때 PixelSize는 하나의 블록으로 묶을 화면 픽셀의 크기를 결정한다. 값이 커질수록 픽셀 블록도 커지기 때문에 더욱 낮은 해상도로 렌더링한 것처럼 표현된다.

Stepped Lighting

픽셀 아트에서 명암이 부드럽게 이어지면 3D 그래픽의 느낌이 강하게 남는다. 따라서 연속적인 밝기를 몇 개의 단계로 나누어 단순화한다.

표면의 법선과 빛의 방향을 비교해 밝기를 구한 뒤, 이를 지정한 단계 수에 맞게 제한하면 된다.

단계가 적을수록 밝고 어두운 영역이 뚜렷하게 나뉘고, 단계가 많아질수록 기존의 부드러운 조명에 가까워진다.

  • Pixelization + Stepped Lighting

Edge Detection

해상도와 조명을 단순화하면 비슷한 색상을 가진 오브젝트 사이의 경계가 불분명해질 수 있다.

이를 보완하기 위해 Edge Detection을 수행한다.

외부 Edge

외부 Edge는 현재 픽셀과 주변 픽셀의 깊이 차이를 이용해 검출한다.

현재 픽셀을 기준으로 주변 8개 픽셀의 Scene Depth를 확인한다. 깊이 차이가 임계값보다 크다면 오브젝트와 배경 또는 서로 다른 오브젝트가 만나는 경계로 판단할 수 있다.

검출된 영역은 어둡게 표현해 오브젝트의 실루엣을 강조한다.

내부 Edge

깊이 차이만으로는 하나의 오브젝트 내부에 있는 형태 변화를 찾기 어렵다. 따라서 주변 픽셀의 World Normal을 비교해 내부 Edge까지 검출한다.

두 면에서의 법선 벡터를 내적하면 표면이 얼마나 비슷한 방향을 바라보는지 알 수 있다. 법선의 방향 차이가 임계값보다 크다면 표면의 방향이 급격하게 변하는 지점이라고 판단하여 내부 Edge라고 판단할 수 있다.

이때 깊이 차이가 큰 영역은 제외해 외부 Edge와 중복되지 않도록 한다.

검출된 내부 Edge는 밝게 표현해 오브젝트의 굴곡과 형태를 강조한다.

Depth Detection + Normal Detection

Result

추가 작업

다음과 같은 작업들을 더하면 더 개선할 여지기 있다.

  • Orthographic Camera
  • Stepped Shadow
  • Dithering
  • Anti-Aliasing 조정
  • DOF 조절