이 부분은 짧게 설명하기도, 이해하기도 어려운 내용이기에 건너뛸까도 고민했지만, 주니어 디자이너로 부딪혔던 '기술적 한계'들을 어떻게 해결했는지 설명하고 도움을 주는 것이 이 블로그의 목적이기에 이 글로 한 번 짚고 넘어가게 되었습니다.
Unity의 Shader Graph를 자유자재로 다루려면 데이터의 행렬에 대해 이해할 필요가 있습니다. Shader graph의 모든 데이터 값은 행렬로 되어있습니다. Shader graph에서 생성할 수 있는 '노드'들은 이 데이터에 속성을 부여합니다. 그리고 각 노드 아래 프리뷰 창에서 데이터를 시각화해줍니다.
데이터와 노드
nx3 행렬 데이터 즉, Vector 3을 예로 들어보겠습니다. Position 노드에서 1열, 2열, 3열 데이터는 각각 x, y, z 축을 의미합니다. Color 노드에서는 1열, 2열, 3열 데이터가 R, G, B 채널을 의미합니다. 하지만 두 노드에서 좌표 '0,0,0'과 가산혼합에서의 '검은색'은 똑같은 (0,0,0) 데이터를 가지고 있습니다. 모든 노드들의 데이터 형태는 같지만, 노드들이 좌표, 컬러, UV로 사용할 수 있는 데이터 배열을 만들어 주고 이름을 붙여줍니다(데이터를 보간하거나 사칙연산해주기도 합니다.).
데이터 시각화 원리
각 노드들은 입력 데이터를 컬러 채널로 인식해 '프리뷰'를 보여줍니다. 1개 열의 데이터(Float)는 명도값으로만 나타내줍니다(0=검정, 1=흰색). Output 데이터가 2개 열 이상일 때부터 1열은 R 채널, 2열은 G채널, 3열은 B채널로 인식해 컬러를 출력합니다.
(Ex. (1,0,0) = 빨간색)
그래서 실제로 출력하고자 하는 색의 RGB 값만 알면, 컬러 노드를 추가할 필요 없이 Vector 3 데이터만 가지고 색을 만들 수 있습니다.
각 열을 분리시켜 주는 Split 노드를 이용해 Position 노드의 그라디언트 컬러 프리뷰가 어떻게 시각화되는지 확인해 보겠습니다. 우선 Position 노드를 Split의 인풋에 넣고 각 열을 분리시켜 보면 1열 데이터(R)들은 X축 방향으로 증가하는 값의 배열, 2열(G)은 Y축 방향으로 증가하는 값의 배열, 3열(B)은 Z 축 방향으로 증가하는 값의 배열이라는 것을 확인할 수 있습니다.
Unity는 Y-up 좌표계를 사용합니다.
Split으로 나눠놓은 X, Y 데이터들을 다시 Combine으로 결합해 보면, Red(X축 값)와 Green(Y축 값)이 가산혼합되면서 노란색이 보이게 됩니다. 이렇게 해서 Position 노드의 프리뷰가 빨강, 노랑, 녹색, 검정의 그라디언트로 보이게 되는 것입니다.
Position 노드를 그대로 Shader의 Base color에 연결해 보겠습니다.
3D 상의 육면체에 위 셰이더로 만든 머티리얼을 적용시킨 모습입니다. 위의 내용을 바탕으로 보면, World Position 원점 기준으로 좌표 데이터가 Position 노드의 프리뷰처럼 RGB 가산혼합으로 시각화되는 것을 이해할 수 있습니다.
이렇게 데이터와 노드의 기능들을 이해하게 되면 적은 노력으로 많은 것을 할 수 있습니다. 예를 들어 위에서 Position의 Out을 Split으로 분리한 다음 G, B 채널을 바꿔서 Combine으로 결합하면, 기존의 Position 프리뷰와 다른 결괏값을 갖게 됩니다. Position의 2열과 3열의 위치를 바꿨으니((x, y, z) -> (x, z, y)), 이제 이 쉐이더 그래프에서 Combine 데이터를 World Position으로 사용하면 Y축과 Z축의 방향이 바뀌게 됩니다.
데이터의 사칙연산
각 노드의 Input과 Output 옆에 숫자로 몇 행의 데이터가 들어가고 나오는지 표시됩니다. 슬롯과 연결선에서 파란색은 Float, 녹색은 Vector 2, 노란색은 Vector 3, 빨간색은 Vector 4 데이터를 의미합니다.
실제로 열의 개수가 다른 행렬 데이터는 서로 사칙연산할 수 없지만 Shader graph에서는 데이터를 연결하면 열의 개수를 알아서 변환해 주기 때문에 편리합니다. 3열의 데이터 Output을 1열 데이터 자리에 연결하면 선의 색이 변하면서, Output의 첫 번째 열만 입력합니다. ex)(3,2,1) -> (3)
반대로 2열의 데이터 자리에 1열의 데이터 인풋을 넣을 때도 알아서 2번째 열을 만들어 줍니다. ex)(1) -> (1,1)
데이터 응용
데이터와 노드 기능을 잘 이해한다면, 적은 리소스로 원하는 것을 쉽게 달성할 수 있습니다. 예를 들어 따로 마스크 맵을 만들 필요 없이 아래 텍스처의 RGB 중 B 채널을 Alpha에 연결하면 텍스처의 B채널 값이 있는 부분만 출력하고 나머지 부분을 투명하게 만들 수 있습니다.
B 채널 값에 One Minus 노드를 연결해 역으로 만들어 주면 반대로 B채널을 제외하고 나머지 부분을 출력할 수 있습니다.
이 처럼 데이터와 노드를 이해하게 되면 쉐이더 그래프를 좀 더 자연스럽게 익힐 수 있습니다. 사실 이 내용에 대해 이해하지 않더라도 작업하는 데는 문제가 없을 수 있지만, 쉐이더 그래프에 익숙해지고 난 후에 돌이켜 보면 '아, 내가 이런 원리로 작업하고 있었구나' 라는 것을 알 수 있습니다.
'Unity Shader Graph' 카테고리의 다른 글
Unity Shader Graph : Position 노드 (2) | 2023.03.08 |
---|---|
Unity Shader Graph : Time 노드 (0) | 2023.03.08 |