Search Unity

움직이는 아트: 셰이더 그래프로 애니메이션 머티리얼 만들기

, 10월 5, 2018

Unity 2018.2 버전에는 메시를 조정하고 애니메이션화할 수 있는 ‘버텍스 포지션(Vertex Position)이 셰이더 그래프에 추가되어 있습니다. 이 블로그 게시물에서는 직접 버텍스 애니메이션 셰이더를 만드는 방법과, 바람, 물과 같이 일반적으로 자주 사용하는 셰이더를 예로 들어 보여드리겠습니다.

셰이더 그래프를 처음 사용하시는 분은 팀 쿠퍼(Tim Cooper)의 블로그 게시물 또는 유니티의 YouTube 채널에 게시된 앤디 터치(Andy Touch)의 ‘셰이더 그래프 소개(영문)’ 세션에서 주요 기능에 대해 확인할 수 있습니다.

이 씬에는 텍스처나 애니메이션 에셋이 사용되지 않았습니다. 모두 셰이더 그래프를 사용하여 색을 입히고, 애니메이션하였습니다.

셰이더는 씬 에셋이 표현되는 모습을 상당 부분 조정할 수 있는 막강한 렌더링 파이프라인 도구입니다. 일련의 입력 작업과 조작을 통해 표면 컬러, 텍스처부터, 메시의 버텍스 포지션까지 에셋의 다양한 렌더링 프로퍼티에 변화를 주는 셰이더를 만들 수 있습니다. 또한 프로퍼티를 모두 조합하여 풍부하고 정교한 애니메이션을 만들 수 있습니다. 이 블로그 게시물에서는 버텍스 애니메이션을 시작하는 방법, 마스크 및 프로퍼티 사용의 개념을 소개하고, 마지막으로 ‘무인도(Desert Island)’ 씬에 셰이더를 만든 방법을 설명해드리겠습니다.

 

예제 프로젝트 다운로드

GitHub에서 저장소(Repository)를 클로닝(clone)하거나 GitHub의 .Zip 파일을 다운로드하여 예제 프로젝트를 받으세요.

무인도 씬 샘플 프로젝트를 다운로드하여 셰이더를 테스트해보고 직접 체험해 보세요. 이 프로젝트에는 셰이더 그래프 작업에 필요한 모든 항목이 포함되어 있습니다. 이 프로젝트는 Unity 2018.2 버전 이상에서 실행해 주세요.

무인도 씬에 포함된 셰이더는 모두 커스터마이징을 고려하여 제작되었으므로 Inspector에서 원하는 대로 셰이더 값을 조작해볼 수 있습니다. 물론 오브젝트마다 값을 기본값으로 되돌려주는 프리셋 파일이 있습니다.

이 작업은 CC-BY(Creative Commons Attribution) 4.0 국제 라이선스에 따라 허가되었습니다.

셰이더 그래프 설치

프로젝트에서 셰이더 그래프를 사용하기 위한 요건은 다음과 같습니다.

셰이더 그래프를 설치하려면 프로젝트를 2018.2 이상으로 생성하거나 업데이트하고, ‘Window‘ > ‘Package Manager‘ > ‘All‘로 이동한 다음, 목록에서 ‘Shader Graph‘를 찾아 ‘Install’을 클릭합니다.

Scene 뷰에서 머티리얼이 애니메이션되지 않는 경우 ‘Animated Materials‘를 선택했는지 확인합니다.

버텍스 포지션 기본 사항

복잡한 공식을 사용하여 움직임을 부여하기 전에 움직일 것이 무엇인지부터 파악해야 합니다.

씬의 메시에는 다음과 같은 네 가지 유형의 공간이 있습니다.

  • Object(오브젝트): 메시 피벗 좌표계 기준의 버텍스 포지션.
  • View(뷰): 카메라 좌표계 기준의 버텍스 포지션.
  • World(월드): 월드 좌표계 기준의 버텍스 포지션.
  • Tangent(탄젠트): 픽셀 단위 조명과 같이 특별한 용도를 위한 좌표.

 

 

효과를 적용할 Space는 Position 노드의 드롭다운에서 선택할 수 있습니다.

효과를 적용할 축은 Split 노드를 사용하여 선택할 수 있습니다.

Split 노드는 4개 채널로 출력되며, 첫 3개 채널은 Transform 축(R=X, G=Y, B=Z)에 해당합니다. 위의 예시에서는 오브젝트의 y축을 분할하여 1을 더했습니다. 그 결과 오브젝트가 축에서 1만큼 위로 이동했습니다.

경우에 따라 월드 공간에서 오브젝트를 이동해야 할 수도 있습니다. 이 경우 Position 노드에서 World를 선택한 다음, Transform 노드를 사용하여 출력을 다시 오브젝트 공간으로 전환합니다.

마스크 사용하기

위에서 메시를 이동하는 방법에 대해 알아보았습니다. 이제 효과를 제한하는 방법을 살펴보도록 하겠습니다.

Lerp와 같은 노드를 사용하면 두 값을 블렌딩할 수 있습니다. T 입력은 Lerp의 제어값입니다. T 입력값이 0(검정색으로 표현됨)이면 A 채널이, T 입력값이 1(흰색으로 표현됨)이면 B 채널이 사용됩니다. 아래의 예시에서는 슬라이더로 두 입력값을 블렌딩했습니다. 아래의 모든 예시를 슬라이더 대신 사용할 수 있습니다.

텍스처 마스크

흑백 텍스처에는 정교한 높낮이 정보를 가지고 있는데 이를 사용하여 평평한 격자 메시를 픽셀 단위로 밀어내어 디테일을 표현할 수 있습니다. 위의 예시를 보면 흰색 부분은 메시를 높이 방향으로 최대치까지 밀어내는 반면, 검정색 부분은 메시 포지션에 아무런 영향을 미치지 않는다는 점을 확인할 수 있습니다. 검정색 부분의 값이 0이기 때문에, 메시 포지션에 0을 추가해도 움직임이 없는 것입니다.

버텍스 포지션이 포함된 텍스처를 사용하려면 일반적인 Sample Texture 2D 노드가 아닌 Sample Texture 2D LOD 노드를 사용해야 합니다. 텍스처는 고유의 셰이프가 있거나 어느 정도의 디테일 감쇠가 있는 마스크가 필요한 경우 특히 유용합니다.

UV 마스크

 

UV 마스크는 텍스처 마스크와 비슷하지만, 언랩된 UV 공간에서 효과를 적용할 메시 부분을 선택할 수 있습니다. 위의 스크린샷에서는 UV의 u축을 사용하여 왼쪽에서 오른쪽 방향으로 그레디언트를 만들었습니다. 그레디언트에 오프셋을 적용하려면 Add 노드를 사용하세요. 강도를 높이려면 Multiply 노드를, 감쇠를 늘리려면 Power 노드를 사용하면 됩니다.

버텍스 컬러 마스크

각 버텍스에는 버텍스 컬러라고 하는 Vector3 정보가 저장되어 있습니다. 폴리브러시(Polybrush) 패키지를 사용하면 에디터 내에서 버텍스 컬러를 직접 페인트할 수 있습니다. 또는 3ds Max, Maya, Blender, 3D Coat나 Modo와 같은 3D 모델링 소프트웨어를 사용하여 버텍스 컬러를 지정할 수도 있습니다. 참고로 대부분의 3D 모델링 소프트웨어는 기본으로 각 버텍스에 최대치의 RGB 값이 지정된 상태로 모델을 익스포트합니다.

위의 스크린샷에서는 Vertex Colour 노드가 빨간색(R) 채널로 분할된 다음 Lerp 노드의 T 채널에 연결되어 마스크로 기능합니다. Lerp 노드의 A 채널은 입력값이 0인 경우, B 채널은 입력값이 1인 경우 사용됩니다. 실제로 버텍스에 빨간색 버텍스 컬러가 지정된 경우 위의 설정은 y축에 1만 추가합니다.

월드 오리엔테이션 마스크

Normal Vector 노드를 사용하면 메시 면의 방향에 따라 입력값을 마스킹할 수 있습니다. Split 노드를 사용하면 효과를 적용할 축을 선택할 수 있습니다(R=X, G=Y, B=Z). 위의 스크린샷에서는 위쪽을 바라보는 면에만 양의 값이 지정되도록 y축을 사용하여 마스킹했습니다. 이 과정에서 반드시 Clamp 노드를 사용하여 0~1의 범위를 벗어나는 값은 0 또는 1로 잘라냅니다(0 이하의 값은 0으로, 1 이상의 값은 1로).

월드 포지션 마스크

이 노드들을 사용하여 오브젝트가 y축에서 월드 포지션 0보다 위쪽에 위치하는 경우 입력값을 마스킹할 수 있습니다.

프로퍼티

셰이더를 만들 때 원하는 효과를 얻을 수 있는 적절한 입력값을 찾기가 어려울 수 있습니다. 이러한 어려움을 해결하고 향후 프리팹과 프리셋을 통한 커스터마이징을 원한다면 프로퍼티를 사용해야 합니다.

프로퍼티를 사용하면 셰이더가 컴파일된 후 셰이더 값을 수정할 수 있습니다. 프로퍼티를 만들려면 ‘+‘ 표시를 클릭합니다(오른쪽 이미지 참조). 다음의 여섯 가지 프로퍼티가 있습니다.

  • Vector(1~4): 값 스트링으로, Vector1용 슬라이더 옵션이 포함되어 있습니다.
  • Color: 컬러 피커로 RGB 값을 입력할 수 있으며, HDR 버전(선택 사항)도 사용할 수 있습니다.
  • Texture2D(및 Texture2D Array): 2D 텍스처 샘플
  • Texture 3D: 3D 텍스처 샘플
  • Cubemap: 생성된 큐브맵 샘플
  • Boolean: 설정/해제 옵션으로 0 또는 1에 상응합니다.

적용 예시

펄럭이는 깃발

깃발 셰이더는 깃발을 오브젝트 공간 사인(sine) 곡선을 따라 좌우로 움직이게 하고, UV 마스크를 사용하여 깃발의 좌측은 고정합니다.

이미지 원본 보기

  1. UV 마스크를 반전시킨 다음 복제하여 y축 전체에서 자연스러운 그레디언트를 구현한 예입니다. 이 방법을 사용하면 깃발의 중심이 노에서 멀어지면서 구부려집니다.
  2. 오브젝트 공간 사인 곡선이 생성되며, 곡선의 진폭, 빈도와 속도를 제어하는 프로퍼티가 포함됩니다. 곡선은 x축에서 UV 마스크로 마스킹되어 깃발의 왼쪽이 움직이지 않도록 구현합니다.
  3. Gradient NoiseStep 함수와 Alpha Clip Threshold로 차례로 출력한 다음 일부 픽셀을 폐기하여 찢어진 깃발을 표현할 수 있습니다.

바람에 흔들리는 풀과 야자수 잎

바람 셰이더는 월드 공간 Gradient Noise를 단일 축 상에서 이동시켜 잎사귀와 풀을 부드럽게 밀고 당깁니다.

이미지 원본 보기

  1. 월드 포지션을 사용하여 y축과 x축에 Gradient Noise를 배치합니다. Vector2를 사용하면 오프셋 속도와 방향을 제어할 수 있습니다.
  2. 프로퍼티는 오프셋의 밀도와 강도를 제어하는 데 사용됩니다. Gradient Noise에서 0.5를 감소시키면 메시가 균일하게 밀고 당겨집니다.
  3. UV 마스크를 사용하여 잎사귀와 풀의 밑부분이 움직이지 않도록 합니다. 마지막으로 Transform 노드를 사용하여 월드 포지션을 오브젝트 포지션으로 전환하면 됩니다.

입을 다문 조개

이 셰이더로 카메라와 조개 사이의 거리를 계산한 다음, 위쪽의 절반을 회전할 때 이 값을 마스크로 사용할 수 있습니다.


이미지 원본 보기

  1. 게임 오브젝트와 카메라의 포지션을 Distance 노드에 입력하여 마스크를 만들 수 있습니다. One Minus 노드는 거리를 반전하여 조개에 가까워지면 양의 값이 도출되도록 합니다. Clamp 노드는 1보다 높고 0보다 낮은 값을 모두 폐기합니다.
  2. 이 UV 마스크는 조개의 윗부분만 회전시키지만, 대부분의 경우 버텍스 컬러 마스크를 사용하면 원하는 효과를 더욱 유연하고 간편하게 적용할 수 있습니다.
  3. Lerp 노드를 사용하여 조개가 입을 열고 닫는 과정을 블렌딩합니다. 게임 오브젝트의 y축과 z축에 회전을 적용하고 x축을 중심으로 회전시키면 됩니다.

헤엄치는 물고기

이 셰이더에서는 오브젝트의 축에 생성된 사인 곡선을 사용하여 물고기가 꿈틀거리며 헤엄치는 모습을 표현할 수 있습니다. 그런 다음 물고기의 머리 부분을 마스킹하여 움직이지 않게 합니다.

이미지 원본 보기

  1. 오브젝트 공간에서 y축과 z축을 따라 사인 곡선을 생성합니다. 곡선의 빈도와 속도는 프로퍼티로 제어할 수 있습니다.
    여기서는 x축과 y축을 모두 사용하므로 물고기가 x축 값의 너비와 y축 값의 높이만큼 꿈틀거립니다.
  2. 사인 곡선의 출력값을 곱하여 꿈틀거리는 동작의 진폭/거리/강도를 제어하고 오브젝트의 x축에 추가합니다.
  3. Lerp 노드를 사용하여 UV 채널의 x축을 통해 물고기의 앞부분을 마스킹합니다. Power 노드와 프로퍼티를 사용하여 물고기의 뒷부분에만 꿈틀거리는 효과를 적용할 수 있습니다.

파도

마지막으로 파도 셰이더입니다! 이 셰이더는 스케일과 각도가 서로 다른 3개의 사인 곡선을 사용하여 메시의 상단을 오프셋합니다. 3개의 사인 곡선은 파도의 최고점과 최저점의 컬러를 생성하는 데에도 사용됩니다.

 

이미지 원본 보기

  1. 3개의 사인 곡선이 월드 공간에 생성됩니다. 각 곡선은 프로퍼티를 사용하여 파도의 진폭, 빈도, 속도, 수렴과 회전을 제어합니다.
  2. 다음으로 Add 노드 2개로 3개의 사인 곡선을 결합하고 월드 스케일 그레디언트를 곱한 후 곡선의 최고 지점 높이를 분할합니다. 그런 다음 결합된 곡선을 오브젝트 포지션에 더합니다.
  3. 두 가지 버텍스 마스크를 사용하여 먼저 곡선을 돔 상단까지로 제한하고, 그다음 파도의 거품 부분이 그려질 때 곡선을 다시 아래로 끌어내립니다.

사인 곡선 생성하기

이미지 원본 보기

  1. x축과 z축을 분할하여 두 방향으로 곡선을 생성할 수 있습니다. 두 멀티플라이어를 사용하여 각 곡선의 영향력을 설정할 수 있습니다. 예를 들어, Z 채널에 0을 곱하면 x축에만 사인 곡선을 출력합니다.
  2. World Position 노드를 x축과 z축으로 분할한 다음 Vector2에서 결합하면 월드 공간에 UV 공간이 생성됩니다. 이렇게 하면 Gradient Noise가 월드 전체에 걸쳐 고르게 만들어집니다.. 이 출력값을 시간에 더하면 사인 곡선을 오프셋하여 직선을 분할할 수 있습니다.
  3. Sine 노드를 사용하면 월드 공간과 시간을 통해 단순한 사인 곡선이 생성되어 여기서 사용한 곡선의 최고점을 절대 노드로 만들어 음의 값을 반전시킬 수 있습니다. 그런 다음 One Minus 노드를 사용하여 이러한 값들을 반전하여 곡선의 최고점이 상단에 위치하게 하면 됩니다.

추가 자료

셰이더 그래프 사용 방법을 알아보려면 먼저 앤디 터치(Andy Touch)의 GDC 세션(영문)을 확인할 것을 권장합니다. 다양한 셰이더 그래프 예시는 앤디의 GitHub 예시 라이브러리(영문)를 참조하세요.

모든 노드에 관한 설명(영문) 등 셰이더 그래프에 관한 상세 정보가 포함된 문서는 GitHub의 셰이더 그래프 개발자 위키(영문)를 참조하세요. 유니티의 그래픽스 실험 기능 프리뷰(영문) 포럼에서 관련 주제에 참여해 보세요! 마지막으로 셰이더 그래프를 이용하여 멋진 작품을 만드셨다면 꼭 공유해 주시기 바랍니다. 언제든 @John_O_Really로 트윗 보내주시기 바랍니다.

21 코멘트

코멘트 구독

코멘트를 달 수 없습니다.

  1. Hey this was awesome
    Can you post some more tutorial pages like like love your work

  2. Hi !
    Shader Graph 4.3.0. Headache not being able to connect my graph right to position in major cases
    How did you achieve that ?

    tried via a sub graph. and duplicating all over my main graph
    can move things on my noise ; time and many multiply; add etc.

    please Help

  3. 블로그 번역 잘 보고 있습니다. 더 다양한 분야로 확대되었으면 좋겠네요.

  4. Question: I copied your example of the flag to the letter except for the textures for color. I am using the HDRP and 2018.3.0b9 and it is saying it can not compile – it is giving me 4 of these: incorrect number of arguments to numeric-type constructor d3d11 (460)(1565)(2138)(2767) any help would be appreciated. Thank you!

  5. Is there a way to “disable receive shadow” in the water surface?
    I mean, the water do not receive the shadow from the trees… sice the shadows are being cast to the surface below the water as well (because of tranparency).
    Thanks

  6. It is or it will be possible to use Shader Graph for Vertex Paint materials in Unity?????

    1. It would be awesome!
      It is one of the coolest features in “the another” game engine material editor :)

    2. You’ll be glad to know the froth on the water uses vertex painting! You can see a quick gif it in action here: https://twitter.com/John_O_Really/status/1042075859262353408

      All you need to do is set up a vertex mask with a lerp like the blog shows. I hope this is what you’re looking for :)

      1. This is really exciting!
        But how can i “paint” the mesh (like in the gif) after setup the shader / material?

        1. To paint vertex colours inside Unity I’m using Polybrush https://unity3d.com/unity/features/worldbuilding/polybrush

          You can download it for free here: https://assetstore.unity.com/packages/tools/modeling/polybrush-beta-111427

  7. Anthony Rosenbaum

    10월 8, 2018 2:07 오후

    Will the Shader Graph work with the normal rendering pipeline oneday?

    1. Ciro Continisio

      10월 8, 2018 5:29 오후

      No, it’s not planned. Too much (duplicate) work to maintain it for both pipelines, and in any case SRPs are going to be THE pipeline at some point in the future (not immediately, but that’s the plan).

  8. We need more of this. Please do more.

  9. Vladislav Ivanchuk

    10월 8, 2018 9:54 오전

    Shader graph UI is ugly as possible…

  10. Say, how do you guys. Take a screenshot of the entire graph in high resolution?

    1. I used a high resolution monitor to take most of the screenshots. For the largest one I stitched 2 together, although it probably would have been worth taking more than 2! :)

  11. All I can say… this reminds me of ‘Johnny Castaway’…. someone do it.

  12. how all of this will perform on mobile?

  13. How we can get water like to “Ori and the Blind Forest” ???

  14. AWESOME AWESOME AWESOME!
    We need more samples like this!!
    Looking forward to HD Pipe samples!
    Thanks a lot!