카툰 렌더링 만들기. (프레넬 외곽선, 램프텍스쳐, 스무스스텝 스페큘라)

2022. 3. 4. 18:27UnityShader/수업 내용

내용에 앞서, 프로젝트 진행 상태는 2Pass Outline 기법을 통해 외곽선을 구현했고,

물체의 노말방향과 조명 벡터를 내적해 음영을 구현한 상태를 가정한다.

 

2Pass를 이용하는 방식은

렌더링을 두번 하는 것이므로 무겁다는 단점이 있다.

또한 Plane으로 끝나는 부분에서는 외곽선이 생기지 않고,

각진 면에서는 선이 끊어진다는 문제점이 있다.

 

이 포스팅에서는 2Pass를 이용하는 방법 대신 Fresnel 방식으로 외곽선을 구현해볼 것이다.

 

 


Fresnel 외곽선 구현

 

림라이트를 만들었던 Fresnel 연산 후 

if문을 사용해 외곽라인을 검출해서 외곽선을 칠해주면 된다.

 

그러나 이 방식은 기본적으로 각 픽셀의 노멀 방향과 시선방향의 차이로 계산되는 외곽선이기 때문에
완전한 평면을 가진 오브젝트에서는 이상하게 보인다는 문제점이 있다.

또한 if문을 너무 많이 써도 부담이 되기 때문에 되도록 지양하는 것이 좋다.

 

 


램프 텍스쳐로 음영 나타내기

 

음영을 나타내기 위해 이전에는 ndotl 내적값 그 자체를 썼다.

이번에는 그 내적값을 uv의 좌표로 사용하여 텍스쳐 특정 위치의 색을 가져오는 용도로 사용할 것이다.

이 텍스쳐를 받아서

이전에 커스텀라이트 함수에서 음영을 연산했던 코드를 주석처리하고

받아온 텍스쳐의 특정 위치의 텍셀을 받아오는 tex2D 함수에 ndotl 내적값을 위치정보로 넘겨준다.

그리고 최종 출력을 연산하는 final.rgb에 r.rgb 값을 곱해준다.

결과

아래는 이전에 음영 연산할 때 사용했던 if문을 써본 결과.

음영 단계 사이의 간격을 마음대로 조절할 수 있다.

 

아래는 이전에 사용했던 ceil을 써본 결과.

 

 


카툰풍 스페큘라 구현

 

 

카툰풍 스페큘라를 구현하기 이전에

기존에 반사광을 구현했었던 블린퐁을 사용해보자.

결과

카툰스러운 몸체에 비해 반사광은 비교적 사실적이다.

어색하다.

반사광도 카툰풍으로 바꿔보자.

음영과 마찬가지로 빛이 퍼져 있지 않고 딱 끊어져서 구분되있어야 카툰스러울 것이다. 

smoothstep 이란 함수를 썼다.

블린퐁 반사광을 만들 때 썼던 ndoth값을 smoothstep함수를 통해서 0.005f ~ 0.01f값 사이로 국한시켰다.

이로 인해 끊어지는 반사광을 구현할 수 있다.

 

그러나 반사광이 너무 과하고 반사광이 어울리지 않는 곳에까지 효과가 미친다는 문제가 있다.

버텍스 컬러를 통해 원치않는 부분에는 반사광이 미치지 않도록 해보겠다.

Input 구조체에서 폴리브러쉬의 칼라를 받고 o.Gloss에 담는다.
SurfaceOutput 에 있는 Gloss의 값을 반사광에 곱한다.

그 결과 폴리브러쉬로 빨갛게 칠한 부분만 반사광이 생기게 된다.

 

여기에 노말맵을 추가해 좀 더 자연스럽게 해보겠다.

 

 


모델 전체에 적용하기

 

 

이제 마지막으로,

캐릭터 몸체를 제외한 모든 부분(머리카락, 눈썹, 악세사리)에도

커스텀 쉐이더 머티리얼을 적용하고 다듬어 보자.

 

이 모델에 기존 적용돼있던 머티리얼은 두 종류다.

하나는 신체에 적용하는 머티리얼,

하나는 악세사리이다.

 

Body_Color 머티리얼에는 우리가 앞서 만들었던 쉐이더 머티리얼을 적용하고,

악세사리 머티리얼에는 외곽선, 음영 처리만 시킨

커스텀 쉐이더 머티리얼을 새로 만들어서 적용해보자.

머티리얼을 적용시키는 방법은, 

적용할 오브젝트를 복수선택한 후 머티리얼을 인스펙터 창에 드래그 앤 드랍하는 것이다.

미리 적용된 컴포넌트의 이름 위에 드랍해야 적용이 되더라.

신체의 모든 부분에 머티리얼을 적용하니, 

눈썹과 머리에 외곽선과 반사광이 적용됐다.

문제는 눈썹의 외곽선은 눈깔의 영역을 침범하고,

반사광이 젤을 바른 것처럼 반딱하게 체모에 적용됐다는 것이다.

이것 또한 폴리브러쉬 버텍스컬러를 통해 해결해보자.

 

먼저 v 구조체에는 버텍스 칼라를 받아올 수 있는 변수가 있다.

이를 활용해 외곽선을 원치 않는 부분을 검은색으로 칠해서 없애보자.

눈썹에는 검은색을 칠했고,

머리에는 녹색만 칠해서 반사광은 없애고 외곽선만 생기게 했다.

 

이제 악세사리의 커스텀 머티리얼을 만들어보자.

외곽선과 음영 처리를 하고, 금속 소재의 악세사리에는 반사광을 줄 것이다.

일단 쉐이더를 새로 만들고, 신체 부분에 적용했던 쉐이더를 복붙해보자.

새 머티리얼을 적용한 상태.
신체 쉐이더를 복붙한 상태.

여기서 반사광은 금속소재에만 주고,

신체에 음영을 줄 땐 램프텍스쳐를 사용했지만,

악세사리에서는 그냥 밝고 어두움의 음영만 주도록 하겠다.

벨트에는 빨강 값을 약간 낮게 줌으로써 빛바랜 청동 벨트의 느낌을 주고자 했다.

 

 

 


최종 결과