티스토리 뷰

프로그래밍

Unreal을 이용한 CelShading

merit nada 2020. 10. 2. 22:27

이번 시간에는 Unreal Engine을 이용해서 CelShading하는 방법에 대해서 알아보겠습니다.

Unreal에서 Rendering을 하는 방법을 공부하던 도중 꽤 괜찮아 보이는 글이 있어서 글을 보면서 따라 해봤습니다.

 

출처: www.raywenderlich.com/146-unreal-engine-4-cel-shading-tutorial

 

Unreal Engine 4 Cel Shading Tutorial

In this Unreal Engine 4 tutorial, you will learn how to use post process materials to create a cel shader.

www.raywenderlich.com

아래 내용은 따라하면서 정리한 내용입니다.

위 글 내용과 거의 비슷하므로 바로 위 글을 보셔도 되고 정리한 내용을 보셔도 됩니다.

 

CelShading이라 함은 아래처럼 Lighting을 몇 단계로 나눠 표현해서 실제로 그림을 그리는 것을 모방하는 Shading입니다. 

만화에서 음영 효과를 내려면 단계별로 색을 어둡게 하는 방식으로 하는데 그런 모습을 그래픽스를 통해서 구현하는 것입니다.

위와 같은 이미지는 단순히 Light의 방향과 Normal을 Dot Product 해서 Real Time에 계산해낼 수 있습니다.

Dot Product의 결과 값이 특정 값 이하이면 특정색, 이상이면 특정색으로 함으로써 구현하는 것이지요.

단, 이렇게 했을 때 단점은 다른 Light의 효과를 같이 주기 어렵다는 것과 Shadow를 만들기 어렵다는 것입니다.

다른 Light의 효과를 주려면 색을 합치는 연산을 해야하고, Shadow를 만들려고 해도 역시 새로운 연산을 추가해야하기 때문이죠.

단순한 CelShading을 구현하거나 추가로 알고리즘을 추가할 용의가 있다면 이런 방식으로 해도 안 될 것은 없습니다.

 

하지만 이 포스팅에서 제안하는 방식은 Post Processing을 이용하는 방식입니다.

Post Processing은 말 그래도 이미지가 나온 뒤에 추가로 작업하는 것입니다.

추가할 수 있는 작업은 무궁무진하고 나타낼 수 있는 효과 역시 매우 다양합니다.

 

아래는 명도 대비를 강조하는 Post Processing 예시입니다.

출처: medium.com/@yousafzai.kamran60/unity-post-processing-with-universal-render-pipeline-8782abd3f619

 

단, Post Processing에 대해서 한 가지 유의할 점은 이미지가 나온 뒤에 추가로 작업하는 것이기 때문에 작업이 2D 이미지 상에서 진행된다는 점입니다.

따라서 그래픽스에서 Post Processing이라는 말이 나오면 '아, 3D 공간이 아닌 2D 이미지 공간에서 무언가 작업을 하는구나'라고 생각하시면 됩니다.

 

그럼 본격적으로 Post Processing을 통해 CelShading을 구현해 봅시다.

 

먼저 컨텐츠 브라우저 탭에서 Material을 생성합니다.

그리고 Material Editor를 연 후 아래처럼 Material Domain Post Processing으로 설정합니다.

Material이란 Shader와 랜더링 파이프라인을 사람이 이해하기 쉽도록 추상화한 무언가입니다.

Post Processing 용도 외에도, 3D 객체에 입히는 방식인 Surface, Deffered Decal 등이 있습니다.

다음으로는 Lighting Buffer라는 것을 만들어야 합니다.

 

Lighting Buffer란 빛을 많이 받은 곳은 하얀색, 적게 받은 곳은 검은색으로 표현하는 Buffer입니다.

CelShading 효과는 Lighting이 끝난 이미지빛에 대한 감쇠가 전혀 없지만 색에 대한 정보가 있는 Diffuse 이미지를 이용해 만들 수 있습니다.

Material에 아래와 같은 노드를 추가함으로써 Lighting Buffer를 만듭니다.

SceneTexture:PostProcessInput0 노드는 말 그대로 PostProcessing에 쓰일 이미지를 뜻하고, SceneTexture:DiffuseColor 노드는 Diffuse Color만을 저장하고 있는 텍스쳐입니다.

 

Deasaturation은 단순히 RGB 색을 하얀색, 회색, 검은색으로 표현하는 RGB to Gray 연산과는 조금 다릅니다.

채도를 감소하는 것이라고 하는데 정확한 계산식은 모르겠습니다.

Divideelement wise divide입니다.

 

마지막에는 Clamp를 통해 0보다 작거나 1보다 큰 값들을 잘라냅니다.

 

연산 결과는 아래와 같습니다.

원래 의도대로 빛을 많이 받은 곳은 하얀색, 적게 받은 곳은 검은색으로 표현하는 Lighting Buffer가 만들어진 것을 볼 수 있습니다.

 

이제 Lighting Buffer와 if 연산을 통해 2개의 톤을 가진 CelShader를 만들 수 있습니다.

가장 단순하게는 Lighting Buffer가 특정 값 이상이면 Diffuse Color를 그대로 쓰고 Lighting Buffer가 특정 값 이하이면 Diffuse Color를 좀 어둡게 해서 쓰는 것이지요.

Lighting에 의해 연속적으로 감쇠되던 Diffuse Color를 2개로 나눠서 감쇠하는 것이라고 생각할 수 있습니다.

Material을 다 만들었지만 아직 끝난 것이 아닙니다.

 

이제 이 Material을 실제로 씬에 적용해야 합니다.

Unreal은 PostProcessVolume이라는 것을 이용해 PostProcessing을 적용할 공간을 만들 수 있습니다.

Volume 안에 카메라가 들어왔을 때만 PostProcessing이 적용되도록 하는 것이지요.

먼저 post process volume을 검색해서 actor를 찾고 씬에 배치합니다.

씬에 배치하면 World Outliner에 생성되는데 여기서 배치된 actor를 골라서 디테일을 수정해야 합니다.

총 2가지를 해야하는데 첫 번째는 post process volume에서 사용할 Material을 아까 만든 Material로 설정해야 하고

두 번째는 Post Process가 적용될 범위를 설정해야 합니다.

직접 크기를 설정할 수도 있지만 infinite Extent를 이용해 전체 공간에 적용되도록 하는 것이 좋습니다.

 

적용하고 보면 결과가 약간 이상한데 그 이유는 Blendable Location이 잘못 되었기 때문입니다.

Blendable Location이란 PostProcessing이 진행되는 순서를 정하는 것으로 Material Editor에서 설정할 수 있습니다.

 

Blendable Location은 After ToneMapping이 기본 셋팅인데 이렇게 하면 약간 어두운 느낌이 듭니다.

Blendable Location을 Before ToneMapping으로 하면 됩니다.

 

ToneMapping 이전에 PostProcessing이 적용되도록 하면 위처럼 깔끔한 이미지가 나옵니다.

 

단, 아직 문제가 있습니다.

캐릭터 뿐만 아니라 뒤에 벽도 CelShading이 되버리는 것입니다.

물론 해결법이 있습니다.

Custom Depth라는 것을 이용하면 원하는 Mesh에만 효과를 적용할 수 있습니다.

 

Custom Depth를 이용하려면 먼저 구분하려는 객체의 Render Custom Depth Path를 true로 셋팅합니다.

이걸 켠 후 Material에서 Custom Depth를 이용해 구분하면 됩니다.

 

Custom Depth를 이용해 구분하는 방법은 아래와 같습니다.

 

Scene DepthCustom Depth를 비교하고 CelShading을 해야한다고 판단되면 위에서 CelShading한 결과를 선택하고 CelShading을 하지 않아도 된다고 판단되면 Post Process Input을 그대로 출력하는 것입니다.

 

Scene Depth는 모든 pixel에 값이 depth 값으로 채워지고,

Custom Depth는 Render 하도록 설정된 Mesh들만 값이 채워지고 나머지는 0으로 되는 듯 합니다.

 

이 특성을 이용해 특정 Mesh에만 CelShading이 되도록 하는 것입니다.

이로써 Unreal에서 CelShading을 하는 방법을 알아보았습니다.

알고리즘 자체는 어려울 것이 없지만 Unreal에서 제공하는 기능들을 잘 알고 조합해야 제대로된 효과를 낼 수 있습니다.

 

이 외에도 Unreal에서는 많은 기능들을 제공해서 원하는 효과를 쉽게 쉽게 낼 수 있습니다.

앞으로 기회가 된다면 Unreal에서 제공하는 기능들을 이용해 또 다른 효과들을 구현해볼 예정입니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함