본문 바로가기

유니티 쉐이더 스타트업

[ 유니티 쉐이더 스타트업 ] 06 . UV를 이용하는 법 배우기

[ UV의 기본개념 ]

[ UV ]

x , y, z의 3차원의 좌표를 u,v 라는 2차원의 좌표로 나타낸 것

(x,y,z 바로 앞의 알파벳 u,v,w중 높이인 w를 뺀 것)

 

UV float2로 이루어진 숫자이다 .

2차원 좌표이므로 float2 이고 , 0~1까지로 표현 가능하다 .

유니티와 언리얼은 UV의 배치가 다르다 .

 


 

[ UV를 시각적으로 확인해보기 ]

[ UV ]

텍스쳐 한 장 받는 쉐이더로부터 시작하자 .

uv는  두자리 숫자이기에 float2 이다 . 또한 버텍스에 이미 들어가 있는 데이터이기에 유니티로 부터

받아야 한다 . 이와 같이 유니티 내부로 부터 받는 데이터는 Input 구조체 안에 선언해야 한다 .

그러므로 uv_MainTex가 _MainTex의 uv이다 .

또한 해당 uv는 surf함수에서 다음과 같이 사용하였다 .

UV는 Vertex에 들어있는 숫자이다 .그렇다면 IN.uv_MainTex.x는 U를 IN.uv_MainTex.Y는 V를 나타낸다 .


 

[ UV출력해보기 - U ]

0~1(좌에서 우)로 변하는 U의 모습이다 .

 


[ UV출력해보기 - V ]

0~1(아래에서 위)로 변하는 V의 모습이다 .


 

[ UV출력해보기 - UV 동시 출력 ]

=>U와 V를 동시에 출력한 모습이다 .U는 R , V는 G로 표현되었다 .


 

[ UV에 숫자를 더하기 ]

[ UV에 더하기 ]

 

텍스쳐가 왼쪽 아래로 내려왔다 . 이는 모든 vertex의 UV 값이 0.5씩 증가했으므로 ,

UV값이 변했기 때문이다 . 결과적으로는 왼쪽 아래로 이동한 것처럼 되었다 .


[ 텍스쳐 모드 - Repeat와 Wrap ]

현재 텍스쳐의 WarpMode가 Repeat이라 UV를 벗어나는 영역에서도 텍스쳐가 반복될 수 있었다 .

클램프라면 마지막 픽셀에서 늘어나게 된다 .


 

[ UV가 Time으로 흘러가게 하기 ]

[ 시간 관련 변수들 ]

  • _Time (float4)

씬이 열린 다음부터의 시간이다 .

각 값은 x,y,z,w 혹은 r,g,b,a로 대응된다 .

Time.x는 1/20 속도

Time.y는 원래시간

Time.z는 2배의 시간

Time.w는 4배의 시간이다.

 

  • _SinTime (float4)

Sin 그래프의 시간이

각 값 x,y,z,w는 각각 (t/8 , t/4 , t/2 , t)로 대응된다 .(w로 갈수록 그래프가 짧아짐)

 

  • _CosTime (float4)

Cos 그래프의 시간이

각 값 x,y,z,w는 각각 (t/8 , t/4 , t/2 , t)로 대응된다 .

 

  • unity_DeltaTime

Delta TIme이다 . 지금 프레임과 이전 프레임의 시간차이를 나타낸다 .

각 값은 x,y,z,w는 각각 (dt , 1/dt , smoothDt , 1/smoothDt)로 대응된다 .


[ 시간값 더하기 ]

다음과 같이 uv 값에 시간을 더하면 좌측 아래로 흘러감을 볼 수 있다 .


[ 시간값 더하기 - y 방향으로 흐르게 하기 ]

다음과 같이 y 값에만 더하면 y 방향으로 흘러감을 볼 수 있다 .


[ 시간값 더하기 - x방향으로 흐르게 하기 ]

다음과 같이 x 값에만 더하면 x 방향으로 흘러감을 볼 수 있다 .


[ 시간값 더하기 - 인터페이스로 속도 제어 ]

다인터페이스를 만들어 흘러가는 속도를 제어 할 수도 있다 .

위의 효과를 통해 물이 흐르는 듯한 효과를 낼 수도 있을 것이다 .


[ 시간값 더하기 - SinTime 더하기 ]

_SinTime을 색으로 더해보면 회색(0.5)-흰색(1)-회색(0.5)-검정(0)으로 이어지는 SinTime에 따른 변화를 볼 수 있다 .

_CosTime을 색으로 더해보면 흰색(1)-회색(0.5)-검정(0)으로 이어지는 SinTime에 따른 변화를 볼 수 있다 .


 

[ UV를 이용한 불 이펙트 ]

[ 불 이펙트 만들기 ]

  • 파티클 사용하기

많은 파티클을 사용하면 자연스러운 표현이 가능하지만

저사양 기기에서 파티클은 심각한 부하를 일으킬 수 있다 .

 

  • 시퀸스 이미지 사용하기

여러장의 불 애니메이션 이미지를 반복해서 Plane에 플레이 .

좋은 품질의 다수의 시퀸스 이미지가 있다면 원본 퀄리티를 살릴 수 있지만 ,

최적화를 위해서 시퀸스의 숫자를 줄인다면 품질이 저하되는 단점이 있다 .

 

  • 쉐이더 사용하기

그럴듯한 결과를 보여주지만 당장 실무에 사용하기에는 반투명 쉐이더 생성시 고려해야할 라이팅 계산,최적화,알파 블렌딩의 옵션이고려되어 있지 않다 . 일단 맛만 보는 단계라 생각하자 .


 

[ 불 텍스쳐 적용 ]

다음의 쉐이더를 적용한 마테리얼을 Quad에 넣어준다.

해당 쉐이더는 텍스쳐 한장만을 출력하는 기본상태이며 Albedo가 아닌 Emission에 텍스쳐를 받으므로

빛의 영향을 받지 않는다 .


 

[ 불 텍스쳐의 알파값 적용 ]

불 이미지는 알파채널이 있음에도 불구하고 제대로 투명해 지지 않는다 .

알파 채널을 활성화 하려면 근본적인 부분을 건드려야 하기에 배경 지식이 필요하다 .

또한 상당히 무거운 연산중 하나이다 .

 

일단, 다음 두줄의 적용으로 임시로 작동하게 처리한다 .

Tags { "RenderType"="Transparent" "Queue"="Transparent"}
 #pragma surface surf Standard alpha:fade

 

[ 다른 한장의 이미지 추가 ]

 

위 아래로 움직이는 텍스쳐를 하나 더 받는 쉐이더를 적용하자 .


 

[ 두 이미지를 합치기 ]

두 이미지를 곱하여 움직이는 이미지를 생성하자 .

현재 텍스쳐 두장의 곱하기 연산 뿐이라 매우 가볍고 효과도 좋다

 

다만 , 현재 코드는 매우 무거운 standard 라이팅이 돌아가고 있고 ,

뒤 이미지와 겹쳐도 밝아지지 않는 불안전한 이펙트이다 .

일단 이미지의 활용이 다음과 같이 됨만 알아두자 .


 

[ 다른 방식으로  불 이펙트 만들 ]

[ 두개의 텍스쳐 받기 ]

일단 , 두개의 텍스쳐를 받고 , c 이미지는 d 이미지의 r 값을 uv에 더하도록 하자 .

위의 경우를 보기 쉽게 하기 위해 다음의 이미지를 넣어보자 .

결과는 이렇다 .

즉 , 흰색부분 (1) 만 좌측 하단으로 이동한 것.

즉, 이미지의 밝기에 따라 이동하는 것이 다름을 알 수 있다 .


[ 이미지 흐르게 하기 ]

두번째 이미지의 uv 값을 y축으로 이동시키는 처리를 하고 다음의 텍스쳐를 넣어보자 .

노이즈가 있긴 하지만 흐름을 볼 수 있다 .


 

[ 한계 ]

다만 , 다음의 쉐이더는 실무적용에는 무리가 있다 .

이는 위의 Standard라는 구문때문인데 이는 , 현재 물리 기반 라이팅이 작동하고 있다는 뜻이다 .

상당히 무거운 공식이며 , 해당 쉐이더에는 물리기반라이팅공식이 사용되지 않음에도

이 공식이 구동됨을 의미한다 .

 

즉, 전혀 사용하지 않지만 굉장히 무거운 고급 라이팅 계산 공식이 구동되고 있음은 시스템 자원의 낭비이다 .

결국 해당 쉐이더는 사용할 수 없는 비효율 적인 쉐이더이다.

 

추후 , 라이팅 연산에 대한 공부후 라이팅을 처리하지 않는 코드로 고치면 부담없이 사용 가능하다 .