그래픽(기타)

유니티 SRP 셰이더 그래프 - 7

에페아 2020. 1. 19. 23:58

1. 빛 연산

2. 모델 최적화

3. 커스텀 라이트

 

1. 빛 연산

일단 빛연산 들어가기에 앞서서, 내적에 대해 알면 굉장히 편합니다

 

그럼 내적이 무엇이냐

벡터의 곱셈 방식 중 하나인데,

https://m.blog.naver.com/jinohpark79/220011526532

 

21. 곱해서 더한다? 내적(dot product)의 의미

이번 공간은 내적의 의미에 대해 알아보려고 합니다. * 이번 공간에 앞서 알아두면 좋은 포스트 - 없음. 1....

blog.naver.com

이 분이 설명하신 걸 참고해서 말하자면, "두 벡터가 서로의 성분을 얼마나 갖고 있는가" 에 대한 스칼라 값이 나오는 계산 방식입니다

스칼라는 그냥 수 하나 말하는 거에요

 

계산은 계산할 각각의 두 벡터 크기와 cosθ를 모두 곱한 값입니다

 

하지만 우리는 계산할 때 우리 가 원하는 값을 얻기 위해 단위 벡터만 사용할 거니까

실제 계산은 1 * 1 * cosθ, 즉 cosθ을 그대로 사용하면 됩니다

 

그럼 이게 어떻게 나오냐

 

대충 한 이거 비슷하게 값이 나옵니다 빨간 벡터와 각각의 벡터를 내적했을 때 나오는 값이에요

 

점점 수직이 될 수록 안닮아가니까 값이 0에 가까워지고, 그 이상 넘어가면 비슷하긴 비슷한데 방향이 반대라 마이너스라고 이해하면 편할 것 같아요

 

그럼 이거랑 빛이랑 무슨 상관이 있느냐

빛을 받을때 보면 빛이 오는 방향과 물체가 바라보는 방향이 마주볼 때 가장 밝죠

이런 식으로요

그리고 아예 수직관계일 때는 아예 빛을 안받고요

이것과 비슷하게요

여기서 이제 저 빛의 방향을 반전시켜서 물체가 바라보는 방향 벡터와 내적연산을 하면

얘는 1이 나올 것이고

얘네 둘이 내적시키면 0이 나오겠죠

 

그 내적 값에 따라 밝기를 넣어주면

이런 식의 결과를 예상할 수 있습니다

 

2. 모델 최적화

1 - 스무싱그룹에 대한 내용

2 - 언랩

 

1 - 스무싱그룹에 대한 내용

이 내용은 위와 연결되는데

위에서 빛연산을 할 때 라이트벡터와 모델의 벡터가 있었죠

근데 이 모델의 벡터는 더 구체적으로 모델에 있는 버텍스의 노말 벡터를 이용해서 계산을 합니다

그래서 맥스에서 노말 벡터를 보면

이런식으로 버텍스에 있는 걸 볼 수 있죠

그래서 이렇게 버텍스에 빛과 연산해서 들어가는 칼라를 기반으로 중간부분을 부드럽게 섞어주는데요

근데 여기서 스무싱그룹을 완전히 다 빼버리면 어떻게 될까요

노말 벡터가 더 늘어났네요

그냥 단순히 노말 벡터가 늘어난 걸로 봐선 안돼요. 노말 벡터는 버텍스 하나당 하나만 가질 수 있거든요

즉, 지금 사진에 보면 노말벡터가 버텍스마다 3개가 붙어있으니까 버텍스하나에 벡터가 3개가 들어가는게 아니라 버텍스가 기존보다 2배가 늘어난 겁니다

이전엔 그냥 색 하나 가지고 블렌딩하면 끝났는데, 이렇게 면마다 색이 확 나눠져있으면 면마다 색을 지정해줘야되니까요

이렇게 되면 엔진으로 넘어갈 때도 같은 모델이라 할지라도 버텍스가 늘어나서 최적화에 영향을 주겠죠?

 

2 - 언랩

자 그래서 최적화를 위해 스무싱그룹을 모두 1로 맞춘 후 엔진으로 가져오기로 했습니다

그런데 가져와서 버텍스 수를 보면

24개에요 분명 스무싱그룹도 먹였고 익스포트할때 체크도 제대로 했는데.

 

언랩을 어떻게 하느냐에 따라서도 버텍스에 영향을 줍니다

저 모델의 언랩 상태를 보면

사각형 하나에 제대로 다 펴진 것처럼 보이지만, 실제로는

이런 식으로 다 떨어져있어서 사각형마다 4개의 버텍스 * 6개 니까 24버텍스가 나오게 되버린 것이죠

 

그래서 언랩에서도 신경을 써줘야 합니다

그럼 이렇게 버텍스 수를 줄일 수 있죠

 

3. 커스텀 라이트

위에서 빛연산 이론을 해봤으니 실제로 구현해봅시다

 

1 - Lambert

2 - Half Lambert

 

1 - Lambert

일단 필요한 정보들부터 체크해 봅시다

버텍스에 들어있는 노멀 벡터와 라이트벡터가 필요했었죠

 

일단 노멀벡터는 그냥 이름 그대로 치면 노드에 있어요

근데 라이트벡터는 노드에 구현이 안되있어서 직접 우리가 가져오는 걸 구현해야되는데

이때 쓰는 게 Custom Function 노드입니다

이렇게 되있어요

Input은 노드에 어떤 값을 넣게 만들건지,

Output은 노드에서 어떤 값을 출력할건지를 정하는 겁니다

그리고 Type은 File과 String이 있는데 File은 아래에 Source에서 파일을 선택해가지고 그걸 읽어서 실행시키고,

String은 직접 그냥 저기다가 타이핑하는겁니다

 

이름부터 Function인 것처럼 함수를 만드는 겁니다 코드로 짜는거에요

 

우선 이렇게 셋팅을 해줍니다

이 함수를 통해서 라이트 벡터와 라이트의 색상을 가져올 것이기 때문에 Output에다가 Vector3의 Direction, Color를 추가해줬습니다

Input은 딱히 필요하지 않기 때문에 그냥 비워뒀고요.

그리고 막 긴 내용을 타이핑할 게 아니기 때문에 Type을 String으로 선택해줬습니다

 

넣을 코드 내용은

더보기

 

# if SHADERGRAPH_PREVIEW //그래프에서 보고있는 중이라면

Direction = float3(1,0,0); //Direction의 값을 이런식으로 설정하고

Color = float3(0,1,0); //Color의 값을 이런식으로 설정한다

# else //그래프에서 보고있는게 아니라면

Light light = GetMainLight(); //메인 라이트를 가져와서 light에 넣고

Direction = light.direction; //Direction의 값을 메인 라이트를 넣어둔 light의 direction으로 넣고

Color = light.color; //Color의 값을 메인라이트를 넣어둔 light의 color로 넣는다

# endif //조건문 종료

이 내용을 써줍니다

"//" 뒤에 써둔 내용은 주석으로, 코드 내에서 그냥 무시되는, 메모하는 용으로 써놓는 것이기 때문에 안써도 상관 없습니다

 

암튼 이렇게 쓰면 메인라이트의 방향과 색상을 가져올 수 있습니다.

이제 이걸 노멀 벡터와 내적을 시키면...

이런식으로 나오게 됩니다

아까 그래프에서 볼땐 Direction의 값을 float(1,0,0)으로 한다고 했었죠?

그래서 내적 연산 할때 오른쪽이 밝고, 왼쪽이 어둡죠.

 

그래서 이걸 마스터노드에 연결시키면

이런식으로 라이트를 먹는 걸 볼 수 있습니다

 

2 - Half Lambert

제목에서도 볼 수 있듯이, 기본은 Lambert이고 개량형입니다

 

지금보면 어두운 부분이 너무 확 나눠진 감이 있는데

이걸 좀 보정해주는 방식입니다.

 

원리는 간단해요

 

이걸 보면 값의 범위가 1~-1인데 우리가 볼 땐 0 아래는 다 검게 되니까 실상은 절반까지만 가도 까매져버린단 말이죠

그래서 범위가 -1 ~ 1 이었던 걸 0 ~ 1로 만들어버리는 겁니다

 

한번 직접 만들어봅시다

이렇게 노드를 짜서 적용시키면

이런식으로 나오는데 변화가 막 눈에띄게 보이진 않죠

그래서 여기다가 제곱을 해줍니다

0을 제곱하면 0, 1을 제곱하면 1이니까 범위는 변하지 않으면서 중간값에 변화가 커진 걸 볼 수 있습니다

적용시키면

이렇게 되고요

반응형