top of page
  • 작성자 사진JP Lee

Stylized Texturing Substance Designer tutorial since by 2013 in years.

최종 수정일: 2019년 5월 24일

3 월달 중에 기본적인 노드 별 메뉴얼과 라이트켑쳐 쉐이더를 이용한 유니티 캐릭터 프리뷰 그리고 Lightcapture shader 와 Dynamic texture , parameter node 를 연동 해 보는 튜토리얼(중고급) 작성 하면서 코드 , 노드 공유등을 하고자 합니다.

너무 크게 잡기보다는 가능 한 정도에서 포스팅을 해 볼까 합니다.

노드 별 메뉴얼은 아래 예시 정도 수준에서 작성 될 겁니다.

필터 = 노드 = 라이브러리?

노드는 쉽게 말해 서브스턴스의 Graph 안에 각각 분절 세그먼트 안에서 스스로의 맡은 기능을 하는 것들을 말합니다.

서브스턴스 디자이너 화면 좌하단에 기본적으로 배치 되어 있는 라이브러리 뷰 안에서 모두 찾을 수 있습니다.

쉽게 노드 라고 작성 했지만 해당 노드에 사용 되는 서브스턴스의 라이브러리를 뜻합니다.

탑다운식의 작성은 아니고 가장 접근이 쉬운 라이브러리를 이야기 하고 간단한 응용 어프로치에 대해서 의견을 나누면서 보강 해 나가는 것도 좋을 듯 합니다.

서브스턴스 온라인 메뉴얼 에서는 라이브러리에 담겨 있는 각각의 기능들을 필터 라고 규정 하고 있습니다.

하지만 라이브러리 안에는 세부적으로 필터 이외에도 개별적 함수 , 메시 , sbs , sbsr 등이 모두 포함 되어 집니다.

Substances (graphs from .sbs package and .sbsar) Bitmap images Vector images Functions Meshes

위 리스트는 라이브러리 안에서 엑서스 할 수 있는 세부 가테고리 입니다.

각각의 필터에 대한 정리는 이해 하기 쉬운 Case by sample graph 를 만들면서 정리 되는 것이 좋을 듯 합니다.<픽스 되지 않음>

서브스턴스를 가장 쉽게 이해 하는 것은 영화 종편 작업등에서 쓰이는 카나타 , 퓨전 , 등의 비선형 편집 소프트웨어등과 Graph 개념이 거의 동일 하다는 것입니다.



파운드리 카타나 스크린샷.

3월 작성 해 볼 라이트켑와 서브스턴스 디자이너 연동의 예상 결과물입니다. 도타2 의 영웅 모드 데이터를 이용 하여 설명 합니다.

연구목표는 아래와 같습니다.

Color Adjust function target list. HSV 변조 매개변수(Expose a parameter) Contrast 매개변수

Dynamic texture generating for ligthCap(Matcap bake texture based) shader. 림라이트 영역 헨들러 매개변수 노멀 플립 매개변수 노멀 강도 매개변수

GLSL shader code writing for Substance designer 3D View. 최종 통합 되어 구현 될 유니티에서 사용 할 " Lightcap shader " 와 거의 같은 쉐이딩을 서브스턴스에서도 직접 구현 해 봅니다.

간략한 이해를 돕기 위해 서브스턴스의 " 내부 쉐이더 라이브러리의 구조를 참조 " 합니다.

위 모든 서브스턴스의 필터를 통한 매개변수는 쉐이더 안에서도 작성 할 수 있습니다. 연구의 목표는 연속적인 프로세싱을 최소화 하는 Look up texture table 을 미리 작성 된 서브스턴스의 매개변수로 부터 다이나믹 텍스처 과정을 거처 static computing 화 하는 것에 있다고 볼 수 있습니다.

Substance power user 에게는 불필요 한 내용 일 수 있지만 앞으로 Substance power user 가 되실 분들을 위해 손풀기로 노드를 살짝? 다루어 보면서...

아~~~ 대략 이런 것이구나 하는 내용 잠깐 보고 갈께요?! 느낌 아니까~~~

보통 프로그래밍을 하다 보면 API 를 사용 하는 경우가 많습니다. 다만 그 API 를 어떤 식으로 어디에 사용 하는지에 따라 다른 경우 또는 같은 경우 이지만 확장성이 편리 하거나 유지보수를 더 쉽게 할 수 있거나 하는 식으로 프로그래밍 구조가 짜여 지게 되겠죠. 역시 이것은 사람의 성향에 따라 달라지게 되는 것입니다.

Substance 의 normal output node 를 보죠.

아래 그림처럼 회색 이미지를 통해 내부적으로 작성 되어 있는 Normal mapper 필터를 경유 함으로서 자동 변환 됩니다.



하지만 무언가 우리가 생각 하고 있는 것과는 매치가 잘 되지 않는군요?! 단순히 Normal mapper 내부적으로 갖고 있는 파라메터에는 한계가 있어 보이는 군요.!

이제 한단계 더 나아가 볼까요?

좌측 하단의 라이브러리 창에서 검색어 입력 라인에 normal 이라고 검색어를 넣습니다. 아직 숙련 되지 않았다면 필더를 찾는것은 꽤나 어렵게 느껴 질 겁니다. 하지만 Substance designer 의 개발자들이 이름을 잘 지어 놨군요! ^^



검색 된 리스트 에서 Normal Color 를 선태 하고 Graph 창에 드레그 해서 가져 옵니다.

위에서 사용 된 입력 페턴의 가장 검정색 부분에 대해서 생각 해 보죠.

가장 깊은 곳입니다.

이것을 Height 맵으로 이해 한다면 좋겠네요.

노말텍스처는 세개의 컬러 체널을 사용 하여 좌표를 기록 하고 있습니다. R = 좌우 G = 상하 B = 깊이

대략 이렇게 이해 했다면.... Normal mapper 로 생성 된 노말맵의 Z 값을 변조 해야 합니다. Normal Color 내부 파라메터인 Slope 을 이용 하여 Blue 값에 가깝도록 변형 해 보세요.


결과를 위해 Blender 를 사용 하여 합쳐줍니다.

주의 할 것은 여기서는 Normal Combine 을 사용 하지 않습니다.

위의 예제에서 처럼 프로시주얼 페턴의 블랙 부분은 알파 영역으로 취급 되어 Normal Mapper 노드를 경유 하면서 완전히 오퍼시티 영역으로 규정이 되는 것이고 내부적으로 투명 영역은 화이트 처럼 인식 해 버릴지도 모릅니다. 그렇기 때문에 Blender 를 통해서 빈 공간을 채워 줄 노말 칼라를 만들어 주어야 하는 것이고 결과를 위해서 두 소스를 그대로 합쳐 주기만 할 것이기 때문이죠.



이제 어느정도 예상 했던 결과물이 되었죠? Slope 각도에 따라 적당히 제어를 하면서 원하는 결과를 만들어 낼 수 있겠습니다.

결론. 서브스턴스는 하나의 길을 제공 하는 것이 아니라 노드의 결합을 이용 한 무한한 확장이 가능 한 차세대 비선형 동적 텍스처 생성 프로그램 이라고 이해 하시면 좋겠습니다. 수많은 노드 연결 학습으로 여러가지 결과물을 만들어 보는 것이 가장 좋은 학습이겠죠!


서브스턴스 디자이너에서는 몇가지 노말맵 생성기능을 제공 하고 있습니다.

PART-2 에서는 보편적인 Normal Mapper 필터를 잠깐 살펴 봤는데요. PART-3 에서는 Height Normal Blender 필터를 경유 하여 노말맵을 생성 하였습니다.

PART-3 의 목표는 서브스턴스에서 기본적으로 제공 하는 렌더링 엔진의 노말맵 연산에 사용 되는 Binormal 과 UV Space 간의 계산을 위한 노말맵의 녹색 체널에 대한 이야기를 살짝 다루면서 서브스턴스의 맥락과 이해에 좀 더 접근 해 보는 것에 두었습니다.

쉽게 말하면 원래 서브스턴스에서 내부적으로 제공 하는 DirectX 모드 와 OpenGL 모드에 따른 Y 체널 Invert Function 을 사용자 노드로 다시 구현 해 보는 것이죠.

이번 구현에서는 쉬운 이해를 위한 방법을 선택 하고 있고 좀 더 어려운 매개변수 개방을 위한 내부 함수(Internal built-in Function)로 변수 개방을 하지 않습니다.

이해를 위해서 간단한 노드를 구성 했어요.



그냥 딱 봐도 정상적으로 출력 되고 있어 보입니다.

테스트를 위해서 일단 렌더링 엔진을 확인 해 봐야겠습니다.




예문 작성을 맥에서 하고 있기 때문에 OpenGL GLSL 로 설정을 하였습니다.

SSE2 는 인텔 CPU 에서 제공 하는 가속 렌더링 아zl텍처 입니다. 서브스턴스는 내부적으로 Bool 타입을 green channel inverting function 을 제공 하고 있습니다.



Normal Format 을 보면 다이렉트 엑스와 오픈지엘을 선택 해 줄 수 있어요.

하지만 어차피 개념적인 이해를 위한 예제 이기 때문에 이것은 생각 하지 않겠습니다.

우리는 노멀맵이 세개의 체널로 부터 작성 되고 있다는 것을 알고 있습니다. 즉 녹색 체널을 반전 시켜야 하죠.














노드를 좀 더 활용 해 보기 위해서 channel split 으로 RGBA 체널을 분리 시키고 다른 필터를 경유 시킨 후에 Channel merge 하여 병합 후 Output 노드로 연결 하겠습니다. 무엇을 해야 할까요? 녹색 체널을 반전 하기 위해서 분리 노드와 병합 노드 사이의 G체널에 Invert 와 관련 된 필터를 연결 해 보는 것이죠.

역시 좌측하든의 라이브러리 창에서 invert 로 검색 해 보는 겁니다.




우리는 회색 체널을 반전 해야 하기 때문에 Invert Grayscale 필터를 사용 할 것입니다.




























Invert Grayscale 필터를 연결 해 보니 노말맵의 위아래가 바뀐 결과를 볼 수 있어요.

왜 이런 체널 인버트를 해야 하는지는 Binormal 연산이 탄젠트 공간과 UV 공간 좌표계의 계산에 의해 이루어 진다는 겁니다.

다이렉트 엑스는 좌하단이 0.0 이고 오픈지엘은 좌상단이 0.0 의 UV 공간 좌표계를 사용 합니다.

쉽게 생각 하면 위아래가 뒤집혀 있다는 거죠.

렌더링 아키텍처에 따른 올바른 법선맵핑 연산을 위해서 가볍게 ... 뭐 아.. 그렇군. 정도로 이해 하시면 될거 같습니다.

보통 쉐이더 작성시에는 Y 값에 대해서 마이너스 값으로 치환 대입 하여 처리 하고는 하죠.

하지만 쉐이더에서는 지속적인 계산을 수행 해야 하기 때문에 중간 작업용 UberShader 등에서는 이런 Bool 타입 파라메터가 있고 if 문 등으로 처리 할 수 있지만 연산은 그다지 달갑지 않은 탓에 다이나믹 텍스처를 통해 초기 한번만 처리 하고 결과를 리턴 할 수 있도록 하는 것이 좋을 듯 합니다.


가볍게 노드란 이런 것이구나 살펴 봤다면 이제 substance designer 의 filter 와 custom shader 를 추가 하면서 간단한 mobile shading 을 해 볼 것입니다.

first step 으로 저는 Lookup texture based Rimlighting texture 를 만들어 볼겁니다.

이것은 포토샵에서 간단하게 만들 수도 있지만 좀 더 substance designer 의 filter 와 Dynamic texture 의 강력한 기능 그리고 매개변수를 노출 하면서 Unity 에서 어떻게 B2M 과 같이 사용 할 수 있는 것인가를 이해 하기 위해 다양한 방법으로 접근 해 볼 것입니다.

먼저 제작 목표가 될 Lookup texture based Rim lighting texture 입니다


위에서 보여지는 텍스처는 링크에서 보시는 것과 같은 Rim Lighting 의 Pre calculated lookup texture 로 사용 됩니다.

lookup texture 를 사용 하는 이유는 모바일 그래픽의 경우 Pow. function ( 거듭제곱 ) 을 자주 사용 하는 것은 섬세하지만 연산에 있어서 Cost 가 무척 높기 때문이죠.

참고로 sqrt 는 제곱근 입니다.사실 Pow function 의 내부를 들여다보면 꽤나 복잡한? 연산을 수행 하고 있습니다.

Pow function 에서의 옵티마이징에는 여러 방법이 있습니다. Pow function 알고리즘을 직접 구현 할 때 int 타입으로 만들고 거듭제곱의 테이블을 미리 정의 하는 것이죠. 다만 우리가 사용하는 쉐이더 컴파일러에서 제공 하는 Pow function 은 none int 타입입니다. 보통 Specular exponent 등을 구현 할 때 사용 하죠. 이것은 여러 방법으로 최적화 할 수 있지만 대략 그런 것이 있구나 정도만 언급 하도록 하죠.

아무튼...

위와 같은 이미지를 얻어 내기 위해서 substance designer 의 어떤 기능을 활용 할 것인지... 그것이 중요 하겠죠.

하지만 여기서 가장 중요 한 부분은 SVG 가 아닙니다.

어떻게 하얀색 튜브를 만들어 낼 것이냐 이죠.

이제 라이브러리를 좀 살펴 볼께요.

흐음...

검색 하다 보니 맘에 드는 것이 나타 납니다.








바로 이것 입니다.

해당 필터에는 여러가지 옵션이 붙어 있습니다.

substance designer 의 개발자들이 이 필터를 그냥 만들진 않았을 것이라는 희망을 갖고 시작 하게 되었죠.


사실 이런 방식으로 제작 하지 않아도 됩니다. 기초 예제 라서 다른 여러가지 노드를 사용 하는 방식으로 제작 해 봤습니다.

Splatter Circular 를 Graph 에 Drag 해서 하나 만들어 보면 Number 라는 파라메터가 있습니다.

기타 Radius 에 대한 옵션도 있죠.

포인트는 Number 에 있습니다.

시각적으로 크게 어색하지 않는 수 만큼을Type 입력 하면 위와 같이 Circle tube 가 만들어 집니다.

좋습니다.

이제 가운데 부분을 부드럽게 Blur 링 파라메터를 추가 하고 싶으실 겁니다.

그리고 이것은 Dynamic Texture 형태로 유지 되어야 하고요.

단순히 Bitmap 으로 뽑아서 사용 하려고 이렇게 어렵게 substance designer 를 사용 하는 것은 아닐겁니다. :)


SVG node 를 하나 만들고 Shape tool 을 사용 하여 그림처럼 Black circle 을 만들어 줍니다.

이건 뭐에 쓸까요?

네... 저는 첨에 만들었던 Splatter Circle 의 중심에 SVG 로 만든 노드를 Blending 할 생각 입니다.














Rim light texture 를 만들때 안쪽은 Blur 를 줘서 부드럽게 사라지는 느낌을 주기 위해서 Blur HQ 노드를 중간에 연결 했습니다.

그리고 이것을 Blending node 에서 알맞게 사용 할 수 있도록 Grayscale 로 바꾸어 줬죠.