본 아티클은 UI 및 간단한 VFX 제작에 도움이 될만한 Graphics 에 대한 이해를 돕기 위해 작성했습니다.


아직 한참 공부가 필요한 입장에서 이런 글을 쓰는 것이 혹여나 잘못된 정보를 퍼뜨리지 않을까 불안합니다만.

많은 분들이 게임 그래픽을 쉽게 이해하는데 도움이 되길 바라는 마음으로 작성해봅니다.

혹시 잘못된 부분 지적해주시면 고치도록 하겠습니다.


추후에 실제 Shader Code 작성 및 VFX 제작을 위한 튜토리얼도

시간님이 허락하신다면... 제작해보도록 하겠습니다.


매끄러운 전달을 위해 반말로 작성된 점 양해부탁드립니다.

문의 사항은 포스팅에 댓글로 적어주시면 최대한 답변 드리겠습니다.


감사합니다. :D





3편 - UV 응용 및 결론



똑똑한 독자들의 목소리가 들리는듯 하다.


"이 UV 이미지를 왜곡 시키면 신박한 결과가 나오지 않을까?"


그러하다.

아래의 예시들을 살펴보도록 하자.




[ 둥근 띠 모양으로 수정된 UV map 에 Texture 를 흘렸을 때 ]




[ Stripe 같은 형태로 수정된 UV Map 에 Texture 를 흘렸을 때 ]




[ 포토샵에서 Smudge Tool로 문지른 UV Map 에 Texture 를 흘렸을 때 ]



각 예시들을 살펴보면, 형태와 무관하게 UV의 좌표값 (색상) 에 따라 텍스쳐가 움직이는 것을 확인할 수 있다.


Graphics 에 대해 잘 모를 경우, "이미지가 움직인다" 고 착각하기 쉽다. (내가 그랬었다)

하지만 이것보다는 "각각의 픽셀이 다른 이미지를 표현한다" 고 하는 것이 더 정확하다고 할 수 있겠다.




["픽셀화" 를 몸소 보여주는 북녘의 마스 게임] 



위 이미지에서도 판넬을 든 사람들이 뛰어가는 것이 아니라,

한 위치에 고정된 사람들이 순차적으로 다른 판넬을 들어 이미지가 움직이는 것처럼 보이는 것을 알 수 있다.


자 이제 결론이 코 앞이다. 조금만 힘내자.



《!》 어떻게 하면 폴리곤 하나로 구체를 만들 수 있을까? 《!》



여기까지 성실하게 읽었다면, 이 뒤는 알아서 잘 할 수 있을 것이다.

그럼 이만..




[ 이제 굳이 더 설명안해도 다 알지 않으세요? 쉽죠? 쉽잖아. 네? 그죠? ]

.

.

.


사실 똑똑한 독자들은 이미 다 이해하고 지루해하고 있겠지만,

혹시라도 아직 이해를 못하고 있을 고냥이들을 위해 설명을 덧붙여본다.


셰이더로 특정한 효과를 구현하고자 할 때는,

만들고자 하는 결과물을 논리적으로 정의하는 과정이 중요하다.


( ※ 느낌적인 느낌을 좋아하는 아티스트들이 가장 힘들어하는 부분이다 )


그렇다면, 아래의 이미지를 통해 《구체로 보여지기 위한》 특성을 정의해보자.



1. 구체의 형태에 따라 수평으로 왜곡된다.

2. 구체의 형태에 따라 수직으로 왜곡된다.

3. 원형으로 된 영역 내부에만 이미지가 표시된다.



정리하자면, 수평으로 왜곡되는 좌표 값을 X 값에, 수직으로 왜곡되는 좌표 값을 Y 값에 넣어주면 된다.

UV 이미지로 표현하면 아래와 같다.


[ R + G = UV ] 


자, 이제 위의 이미지를 UV 좌표 값으로 사용했을 때의 모습을 살펴보자!



[ 쨘! ]


이 아름다운 구체의 모습이 보이는가.

하지만 뭔가 이상하다.. 구체를 제외한 바깥 부분이 이상하게 반짝거린다.


왜 구체 바깥 부분에도 색상이 찍히는 걸까?



[ 혹시 '이 부분은 검은색이니 색상이 없는게 아닌가?!' 라고 생각했나? ]




[ 닝겐이여... ]



앞서 살펴봤듯이, 검은색 부분도 (0, 0) 의 좌표값에 있는 텍스쳐를 읽어들인다.

그래서 검은색 부분이 전체적으로 같은 색상으로 변화하는 것이다.


그렇다면 구체 영역 내부만 마스킹을 해야할텐데,

이미지는 R, G, B 세 개의 채널로 이루어져있다는 것을 알고있는가?


그렇다. 우리에겐 아직 B 채널이 남아있다...


B 채널을 소중히 꺼내서 흰 원을 그려넣어주자.

그러면 UV 이미지는 아래와 같이 한층 더 영롱해진다.

[ X (R) + Y (G) + Z (B) ]



위에서 얻었던 결과물의 알파채널에 B 채널을 입력해주면,

아래와 같이 구체를 제외한 부분은 깔끔하게 사라진다.




[ 야호! 깔끔하다! ]


( ※ 알파 채널에서 불투명한 부분은 1 의 값을, 투명한 부분은 0 의 값을 가진다. 

그러므로 알파 채널에 B 채널을 입력하면 흰색 부분은 불투명하게 보이고, 검은색 부분은 투명하게 되는 것이다 )



Quad 하나로 수백개의 폴리곤을 절약했다!!

물론, Vertex Shader 에서 추가적인 연산을 할 경우 자원이 더 들어가지만 상황에 따라 때 충분히 사용해봄직한 기술이다.


한가지 주의할 점은, UV 좌표 를 연산할 때와 비교하면

Image 는 정확도가 떨어지기 때문에 충분히 큰 이미지를 사용하지 않으면 노이즈가 발생한다. 


( ※ 하지만 멀리서 빨리 돌리면 안보이지롱 )


평면인 관계로 UI VFX 에 활용해도 좋고,

Billboard로 사용시에는 World map 에도 충분히 사용할 수 있다.



[ 파티클 시스템에 적용해서 Billboard 로 보여지는 이미지 ]




여기까지다.

여기서 이해한 내용을 잘 응용해서 좋은 작품을 만들어내길 기원한다.


언젠가 개발자에게 당당하게 



"되던뒈여?!!?!?" 



라고 외칠 수 있는 그 날이 오기를..





너무 기초적인 내용이라 좀 지루했을 수도 있을텐데, 끝까지 읽어줘서 넘나 감사합니다.

이런 글을 써보는건 처음이라 좀 매끄럽지 못한 부분도 있을텐데 양해 부탁드려요. ㅎㅎ


글에서 다뤘던 결과를 제대로 만들기 위해서는 Graphics 에 대한 이해와 더불어

3d Tool, Game engine, Script, Shader Language 와 같은 여러가지 툴에 대한 숙련도가 필요합니다.


실무적 내용을 포함한 모든 것을 몇 개의 글로 완벽히 설명하기는 한계가 있기에, (읽다 지쳐 포기하실 수도 있으니)

주로 이론과 이해를 도우며 흥미를 돋우는데 주안점을 두고 작성했습니다.


궁금하신 내용 댓글로 달아주시면 확인하는데로 답변 드리겠습니다. :)

질문 사항이 다른 분들에게도 공유될 수 있게 가급적 공개 댓글로 적어주세요.


감사합니다.

  1. 빈센 2018.07.12 17:03

    캬 님 짱입니다요

  2. 2018.07.13 03:39

    비밀댓글입니다

    • 2018.07.13 05:47

      비밀댓글입니다

    • 쿠오 2018.07.13 06:05

      앗 비밀글로 남겼다가 답글 주신게 볼 수가 없네요ㅠㅜ 에고 괜히 비밀글로 남겨서 죄송합니다.

    • Woodorl 2018.07.13 07:24 신고

      헐 안보이는군요 누구한테 보이는 비밀댓글이지ㅋㅋ "안녕하세요! 네 몬트리올에 있습니다! 와우 몬트리올에서 일하시는군요 완전 반가워요ㅎㅎ 영화나 애니쪽 CG 하는 한국분은 많은데, UI 일 하시는 분은 못봐서 더 반갑네요!! 저는 온지 이제 막 6개월차 접어드는데, 오신지 오래 되셨나요?" 라는 내용이었어요 ㅋㅋ wizardkwh@gmail.com 으로 답신 주실 수 있으신가요? 동네 주민인데 친하게 지내요!

  3. 와우쭈 2018.07.13 10:11

    심박한 내용 입니다
    또 없죠?

  4. 어쎄씬 2018.07.13 11:20

    멋져요~ ^_^=b

  5. 코코a 2018.07.13 14:27

    고양이를 입양할까하다가 ...두번 세번 보니 조금씩 알것 같아요. 완전 굿

    • Woodorl 2018.07.13 21:45 신고

      후후후 이제 고양이랑 동등한 수준이 되어가고 있군요

  6. 룡딘 2018.07.14 02:40

    와 개꿀잼이네요.
    계속 연재해주시면 좋겟네요.
    감사합니다.

    • Woodorl 2018.07.18 08:03 신고

      재밌게 읽어주셔서 감사합니다. :D
      다음편도 틈틈히 준비해볼게요!

  7. 궁금궁금 2018.07.30 18:53

    보고 따라했는데 저는 이미지가 시작하는 부분은 확대되고, 끝나는 부분은 축소되더군요..
    알려주실 수 있을까요 ㅠㅠ
    전 아래처럼 만들었거든요..

    fixed4 d = tex2D (_UVTex, IN.uv_UVTex );
    fixed4 c = tex2D (_MainTex, float2(d.r - _Time.x * 0.1 , d.g));

    • Woodorl 2018.08.02 08:31 신고

      음.. 어떻게 되는지 이미지를 봐야 뭐가 문젠지 알거 같아요. 최적화를 위해서는 버텍스 셰이더에서 계산을 해주는게 좋긴 하지만, 적어주신 스크립트에는 문제가 없습니다~!

    • 궁금궁금 2018.08.02 11:07

      도무지 해결을 못 하고 있다가,
      사용하신 노멀맵 캡쳐해서 쓰니 되더군요..;; 그런데 다른 문제로, 지구 이미지의 텍스쳐를 아무리 고해상도를 써도 이미지가 자글자글해서 난감하네요. ㅠㅠ

    • Woodorl 2018.08.02 21:05 신고

      아 저 구형태의 UV맵 말씀하시는거죠? 저 맵을 잘 만들어야 정상적으로 작동해요 ㅎㅎ

      그리고 자글자글해지는건 지구 이미지의 텍스쳐 해상도 문제라기보다는 UV맵 이미지의 문제일 가능성이 커요.

      일반적으로 UV를 계산할 때 사용하는 float 함수형이 표현가능한 수는 "1.2E-38~3.4E38" 인데 E38이라고 하면 0이 38개가 붙는 만큼의 숫자 크기에요. (1억이 0이 8개)

      그에 비해 이미지를 사용할 경우에는 끽해야 512일텐데, 비교할수없을만큼 정확도가 낮죠. ㅎㅎ (1024 이상은 비용이 너무 커지는듯)

      정밀한 표현이 가능한 요소보다는 어느 정도 해상도를 희생해도 되는 (혹은 노이즈를 인지하기 어려울 정도의 연출을 동반한) 것들에 사용하시는 것이 좋을거에요!

    • 궁금궁금 2018.08.03 11:34

      자세한 설명 감사합니다. 다만 작성자님 튜토리얼에 있는것처럼 깔끔하게 한번 만들어 보고 싶어서 그랬어요..ㅋㅋ 다시한번 감사드려요!

  8. 지누쓰 2018.07.31 15:45

    항상 우돌님 작업물 감탄하면서 보고있습니다 ㅠㅠ
    제가 VFX를 생각하고 이것저것 공부해야겠다 라고 계기를 가진 원동력입니다..
    언젠가는 저도 우돌님처럼 되고싶네요!
    회사에서는 UI업무랑 이번주 토요일부터 이펙트 과외랑 C#을 공부하고있는데
    우돌님의 C# 강의도 도움이 되네요! 감사합니다 ㅎㅎ

    • Woodorl 2018.08.02 08:33 신고

      하핫 감사합니다! 저도 아직 많이 부족해서 공부할게 산더미 같은데.. 좋게 봐주셔서 감사합니다!

      후후 UI에 이펙트, C# 까지 하시면 곧 엄청난 괴수가 되시겠군여! 기대하겠습니다! ㅎㅎ 나중에 재밌는 작업 하시면 공유해주세요~!



본 아티클은 UI 및 간단한 VFX 제작에 도움이 될만한 Graphics 에 대한 이해를 돕기 위해 작성했습니다.


아직 한참 공부가 필요한 입장에서 이런 글을 쓰는 것이 혹여나 잘못된 정보를 퍼뜨리지 않을까 불안합니다만.

많은 분들이 게임 그래픽을 쉽게 이해하는데 도움이 되길 바라는 마음으로 작성해봅니다.

혹시 잘못된 부분 지적해주시면 고치도록 하겠습니다.


추후에 실제 Shader Code 작성 및 VFX 제작을 위한 튜토리얼도

시간님이 허락하신다면... 제작해보도록 하겠습니다.


매끄러운 전달을 위해 반말로 작성된 점 양해부탁드립니다.

문의 사항은 포스팅에 댓글로 적어주시면 최대한 답변 드리겠습니다.


감사합니다. :D




2편 - UVW란?




XYZ - 1 = UVW

(충격적인 네이밍 센스.. 역시 개발자들이란..)



UV Coordinate (UV 좌표) 라고 하는 값은 RGB, XYZ 와 같이 UVW 라는 세 개의 값을 갖는다.

하지만 3차원 좌표값을 필요로 하지 않는 특성상 W 값은 제외하고 주로 UV 두 개의 값만을 사용한다.


이것은 텍스쳐가 어떤 좌표에 그려질지에 대한 정보를 갖고 있고,

이미지로 표현하면 아래와 같은 영롱한 색상이 된다.


[ 지긋지긋한 놈.. ]



이러한 색상을 갖게 되는 이유는 각각의 픽셀들이

x 좌표 값을 0~1 까지, y 좌표 값을 0~1 까지 갖고 있는 두 값을 묶어서 (RGB로 표현하면 (x값, y값, 0) 이 된다) 저장하기 때문이다.


( ※ 일반적으로 UV 좌표 값은 2개의 값만 가지는 데이터 타입 (float2, fixed2, half2 등) 을 프로그램 내에서 연산하여 사용한다 )

 float, half , fixed 는 순서대로 값의 정확도에서 차이를 보이는데, UV coordinate 는 정확도를 요하는 값이기에 float 을 주로 사용한다 )

 각 데이터 타입에 대한 설명은 본 아티클의 난이도를 넘어가므로, 이 글에서 다루지 않는다 )


다양한 해상도의 텍스쳐를 모두 문제없이 불러들여야하므로 좌표값의 정확도가 중요하기에,  

저장할 수 있는 정보양에 비해 덩치가 큰 이미지를 사용하기보다는 프로그램 내에서 연산하여 사용하는 것이다.


아래의 그림을 보면 결과적으로 색을 가진 것 같이 보이지만, 

사실 각각의 픽셀들이 (0,0), (0, 0.01), (0, 0.02) .... ~ (1, 1) 등의 값을 표현하고 있다.




[ 각 값 사이에도 무수히 많은 좌표 값들이 존재한다 ]



Pixel shader 단계에서 이 좌표값 (Coordinate) 에 따라 텍스쳐의 이미지를 불러들인다.

간단한 UV scrolling 같은 경우, 각각의 좌표 값에 특정한 속도로 값을 더해주는 개념이라고 생각하면 된다.


이렇게 값을 더해주면 일정 시간이 흐른 후 좌표값이 1을 초과하게 되는데 

이 때 초과한 값을 어떻게 처리하느냐에 따라 아래의 예시와 같이 다르게 보인다.


먼저, 1을 초과한 좌표 값을 다시 0부터 반복되게 하면 해당 픽셀에서 불러들이는 이미지의 좌표값이


0.1 0.2 0.3 0.4 .... 0.8 0.9 1.0 0.0 0.1 0.2 .... 0.8 0.9 1.0 0.0 0.1 0.2 0.3 ....


이런 식으로 반복되게 되고, [스크롤 예시1] 과 같이 보인다.

( ※ Unity Image Setting 에서 Repeated 와 같다고 생각하면 된다 )




[ 스크롤 예시1 - X 값에만 특정한 값을 더해주어 수평으로 움직임 ]



위와 다르게 1을 초과하더라도 좌표값을 초기화하지 않을 때는, 

말하자면 좌표 범위를 초과한 상태가 되고 [스크롤 예시2] 와 같이 마지막 픽셀이 반복적으로 보이게 된다. 

( ※ Unity Image Setting 에서 Clamp 와 같다고 생각하면 된다 )



[ 스크롤 예시2 ]



자, 그럼 UV 좌표에 값이 다른 방식으로 작용했을 때 어떻게 되는지 살펴보자. 



[ UV 좌표 X 1 ~ 5 ]


UV의 Tiling 을 조절할 때에는 UV 좌표 값에 특정 값을 곱해주면 된다.

1보다 작은 수를 곱해주면 확대, 1보다 큰 수를 곱해주면 축소된다고 볼 수 있다.

( ※ 최적화를 위해 나누기는 가급적 사용하지 않는다 예를 들어, a / 10 보다는 a x 0.1 을 사용하는 것이 좋다 )





[ 삼각 함수를 적용한 이미지 ]




이러한 UV 값은 활용하기에 따라 무한한 활용성을 가지는데,

약간의 이해있으면 아래와 같이 이미지 없이 그림을 그리는 것도 충분히 가능하다.



[ Sprite 없이 Shader Language 로만 만든 이미지 in Unity (영상 링크) ]



이제 이 UV 좌표 라는 데이터가

얼마나 많은 활용성을 가진 개념인지 대충 감이 오는가?


이 외에도 Shader 는 수 없이 많은 정보를 이용해서 시각효과를 만들어낸다.

World 에서의 좌표, 카메라로부터의 거리, Vertex가 받는 빛을 활용하기도 한다.


Shader 의 가능성에 설레는 독자의 심장 소리가 여기까지 들리는듯하다


피의 복수의 두번째 장이 끝이났다.

그럼 이제 막장으로 넘어가보록 하자..




궁금하신 내용 댓글로 달아주시면 확인하는데로 답변 드리겠습니다. :)

질문 사항이 다른 분들에게도 공유될 수 있게 가급적 공개 댓글로 적어주세요.


감사합니다.

  1. 와우쭈 2018.07.13 10:06

    복수는 누구에게 하는건지 궁금합니다



본 아티클은 UI 및 간단한 VFX 제작에 도움이 될만한 Graphics 에 대한 이해를 돕기 위해 작성했습니다.


아직 한참 공부가 필요한 입장에서 이런 글을 쓰는 것이 혹여나 잘못된 정보를 퍼뜨리지 않을까 불안합니다만.

많은 분들이 게임 그래픽을 쉽게 이해하는데 도움이 되길 바라는 마음으로 작성해봅니다.

혹시 잘못된 부분 지적해주시면 고치도록 하겠습니다.


추후에 실제 Shader Code 작성 및 VFX 제작을 위한 튜토리얼도

시간님이 허락하신다면... 제작해보도록 하겠습니다.


매끄러운 전달을 위해 반말로 작성된 점 양해부탁드립니다.

문의 사항은 포스팅에 댓글로 적어주시면 최대한 답변 드리겠습니다.


감사합니다. :D





1편 - Vertex Shader & Pixel Shader



스크린 안의 세상이 어떻게 그려지는지 생각해본적 있니




밑도 끝도 없이 UI 부터 까고보는 사람들..



뭐가 잘못된건지 설명도 안해주는 개발자들..




이제 그 설움의 시간에 마침표를 찍고...


피의 복수를 시작해보자..


(미안하지만, 이거 다 읽어도 피의 복수까진 못한다)


.

.

.



총 3개로 이루어진 본 아티클의 목적은 아래의 Custom Shader 에 대한 이해를 돕는 것이다.




[ Custom Shader in Unity ( 영상링크 ) ]




자 그럼 이제 신나고 설레는 Graphics 의 세계로 들어가보자!


여기 이미지가 있다.



[ 유아이 이미지가 이상하다!! ]


이것을 보고 어떤 생각이 드는가?





초보라도 좌절하지 말자. 당연한거다.

중수는 복습하는 의미에서 읽어줬으면한다.

고수님들은.. 여기서 나가주세요.. 초보랑만 있고싶습니다.


이 글의 대상 독자는 초보 - 중수이다. 자신감을 가지자.



[ 출처 좌 : Pinterest, 우 : Alberto Rodriguez ]


Game graphic 에서 화면에 출력되는 이미지들은 Mesh 위에 그려진다. (UI도 예외는 아니다)


Mesh 의 최소 단위는 삼각 폴리 (Triangle Polygon) 인데, 면을 구성하는 점의 최소 개수는 3개이기 때문이다.

( ※ 놀랍게도 점이 2개 이하면 면이 존재할 수 없다! )


우리가 만든 UI도 결국 삼각 폴리의 덩어리 위에 그려지는 것이다.


그렇다면 폴리곤과 픽셀들은 어떠한 과정으로 그려질까?




[ Shader 의 전체 과정. 저 두 놈에만 집중하자 ]



화면에 Graphic 을 출력하는 Shader 에서 우리가 주로 다루는 두 가지 프로세스가 있는데,

첫번째는 Vertex Shader 이고, 두번째는 Pixel Shader 이다.


Vertex Shader 란 Vertex (3d 프로그램에서의 정점) 를 화면에 그리는 과정으로,

3개의 점을 가져와 삼각형 한 판씩을 그린다고 생각하면 된다.


[ Vertex 를 기준으로 렌더되는 폴리곤 ]



Pixel Shader 는 Vertex Shader 단계 이후에 Pixel 을 입히는 과정인데,

이미지를 각각의 픽셀에 그리는 것이다.



[ 해상도를 기준으로 한 픽셀씩 렌더된다 ]



Vertex Shader 같은 경우 Vertex의 개수만큼 연산을 하고,

Pixel Shader 같은 경우 Pixel의 개수만큼 연산을 한다. (256 해상도의 픽셀은 256 X 256 = 65,536 번만큼 계산)






[ Pixel Shader 내에서의 연산은 훨씬 무겁다 ]


이러한 이유때문에 최적화를 위해서 가능한한 Vertex Shader 내에서 연산을 하는 것이 좋다.

Vertex Shader 로 화면에 Vertex 들을 배치하고 난 뒤에, 이미지를 그리는 과정에서 필요한 것이 텍스쳐와 UV 맵이다.


( ※ 둘 사이에 Geometry 를 생성하는 프로세스도 있으나, 본 아티클에서는 다루지 않는다 )

( ※ 당연히 픽셀들이 저렇게 개기는 일은 없다; ]

( ※ 편의상 좌우상하로 표현했지만, 모든 값은 X, Y (3d 좌표의 경우 Z) 를 기준으로 입력되어야한다 )



과연 UV맵은 무엇일까!!

2편이 너무 궁금해지는걸!





궁금하신 내용 댓글로 달아주시면 확인하는데로 답변 드리겠습니다. :)

질문 사항이 다른 분들에게도 공유될 수 있게 가급적 공개 댓글로 적어주세요.


감사합니다.

  1. 와우쭈 2018.07.13 10:04

    재미있어요

https://realtimevfx.com/t/an-example-of-sending-custom-data-from-shuriken-to-a-vertex-shader-in-unity-5-5/1515




[Unity] Wave Distortion Shader Code 

https://pastebin.com/WC5giTZC

+ Recent posts