본문 바로가기

Graphics

셰이더에서의 Sin(time) 그래프의 이해

 

개요

일반적으로 셰이더에서 애니메이션 효과를 줄 때, 단골로 등장하는 함수가 있습니다.
삼각함수 중 하나인 sin() 입니다.

물론 sin() 함수를 사용하지 않고도 애니메이션 효과는 만들 수 있겠지만, 사람은 일반적으로 보간이 들어간 커브 형태의 움직임을 더 자연스럽게 느끼고는 하니까요.

 

선형 애니메이션과 보간된 애니메이션

 

이번 포스트에서는 sin() 함수를 통해서 부드럽게 알파가 깜빡이는 효과를 언리얼 메테리얼 노드로 만들어 보겠습니다.

글 순서는 이론적인 부분부터 예제까지 차례대로 적기는 했지만, 저같은 수포자는 예제를 따라해본 뒤 이론적인 부분을 보며 원리를 이해하는게 더 와닿았었습니다. 만약 저와 같은 수포자시라면, 실전부터 박치기하고 역주행하는 쪽을 추천드립니다. 학창시절에 수학을 등 뒤로 했던 업보가 이렇게... 😂

 

그럼 sin() 그래프가 어떻게 생겼고, 어떻게 움직여야 하는지 알아보러 갑시다!

 


 

삼각함수 sin() 과 time 변수

삼각함수에 대한 설명은 저같은 수포자가 하기엔 너무나도 어려우니, sin() 그래프를 어떻게 만들고, 어떻게 변경하는지에 대해서만 중점을 두고 적어보려 합니다.

수식으로는 y = sin(x) 형태를 띄고,
x값에 따라 y값이 0과 1 사이를 아래와 같이 부드럽게 움직인다고 간단하게 받아들이고 넘어갑시다.

 

sin(x) 그래프

 

그래픽 계산기

먼저 이번 글의 필수 준비물을 소개하겠습니다.

위 이미지를 그릴 때 사용한 그래픽 계산기 입니다.
sin() 그래프를 조정하거나, 타일별로 크기 조절이 되는 셰이더 포스팅과 같은 UV 타일링 등을 작업할 때 보조 도구로 사용하고는 합니다.

셰이더를 작성할 때, 코드나 노드를 보며 생각했을 땐 머리에 뚜렷하게 그려지지 않기 때문에, 그래픽 계산기로 그린 그래프를 통해서 이렇게 움직이겠구나, 이렇게 나타나겠구나를 떠올려볼 수 있어요. 물론 그래픽스 디버깅 도구로도 알 수 있겠지만, 저는 디버깅 도구까지는 사용해보지 않았습니다.

사용법은 간단합니다. 화면 좌측의 입력 칸에 sin(x) 와 같은 형태로 수식을 입력하면 그래프가 그려지게 됩니다.

 

time 변수

time 변수는 일반적으로 게임이 시작된 뒤 (씬이 로드되고 플레이되기 시작할 때) 시간에 따라 선형으로 증가하는 값입니다. 즉, 계속 증가하는 time 변수에 따라서 y의 값도 계속 달라지게 됩니다. 조금 앞의 sin(x) 그래프에서의 x가 time 변수이고, x값과 초가 동일하다면, 1초(x값이 1)에는 y 값이 0.75 가량으로, 2초에는 0.875 가량으로 변화하게 되겠죠.

이렇듯, time 변수는 셰이더를 통해서 움직임, 즉 변화를 만들고 싶을 때 사용하게 됩니다. 변하지 않는 값(상수)으로는 움직임을 만들 수 없으니까요.

 

삼각함수 sin(x) 에서의 x 값은 각도값이기 때문에, x값과 y값이 딱 들어맞지 않아 조금은 직관적이지 않을 수 있습니다. x가 1일때, 2일때, 3일때 y가 0이 되는 것처럼 맞아 떨어지게 하려면, 식을 x에 pi 값을 곱한 sin(x * pi) 로 변경해주면 됩니다.

다만 애니메이션을 작업할 때 느낌을 보고 결정하지, 정확한 수치값을 비교해보며 작업하지는 않아 아래와 같이 pi를 통한 y값 보정은 작업할 때 사용하지는 않고 있습니다.

 

sin(x * pi)

 


 

sin() 그래프 변형하기

세부적으로 들어가기에 앞서, 셰이더 애니메이션을 위해서 우리에게 필요한 삼각함수 sin() 을 변형하는 식은 다음과 같습니다.

y = a × sin(bx) + c
= 진폭의 크기 × sin(주기의 길이 × x) + 중간 직선의 높이
= 알파값 애니메이션되는 범위의 크기 × sin(애니메이션 속도 × x) + 애니메이션되는 기준치

 

 

전체적인 구성만 기억에 남겨둔 채로, 하나하나씩 살펴보겠습니다.

 

sin() 그래프의 이동

단순한 수직·수평 이동부터 시작해보겠습니다.
수직과 수평 이동 모두 값을 더하는 것으로 이루어지는데, 아래와 같이 이동값 a를 어디에 더하는지만 다릅니다.

수평이동
sin(x + a)

수직이동
sin(x) + a

 

그래픽 계산기의 좌측 입력 란에 a 를 입력하거나, 수식에 a 를 넣으면 변수 a가 생성됩니다. 설정을 통해서 a의 최소치와 최대치를 조절할수도 있습니다.

 

수평(x축) 이동과 수직(y축) 이동

 

셰이더 애니메이션을 위해 sin() 함수를 사용할 때, 수평이동을 사용할 일은 거의 없습니다. time 값을 통해 x값이 증가하며 애니메이션되면, 결국 그래프는 수평으로 계속 움직이기 때문입니다.

수직이동을 통해서는, 그래프(y값)의 최소값이 몇이 될지를 설정해줄 수 있습니다.
예를 들자면, sin(x) + 0.5 의 그래프에서 시작점(x=0)의 y값은 0.5가 되겠죠.

 

sin() 그래프의 크기 조절

이제 핵심인 크기 조절입니다.
크기 조절도 이동과 동일하게, 값을 곱해 구현되고 곱하는 a 값의 위치가 어디냐에 따라 x 스케일이냐 y 스케일이냐가 달라집니다.

x스케일
sin(a * x)

y스케일
a * sin(x)

 

x스케일과 y스케일

 

x축의 크기 조절 시 sin() 함수 안의 x 에 값을 곱해주게 되고, 주기가 변경되는 것을 볼 수 있습니다.
a 값이 0일땐 그래프가 평평해져 주기가 없다가, 값이 커지면서 점점 주기가 짧아지게 됩니다.

주기가 줄어들면  0~1 을 반복하는 애니메이션의 길이도 짧아지고, 늘어나면 애니메이션의 길이도 길어들겠죠. 즉, 주기 = 애니메이션 속도라고 생각하면 간단합니다. 주기가 줄어들면, 1초에 한번 깜빡이던 불빛이 1초에 두번 깜빡이는 식으로 바뀌는 거죠.

 

y축의 크기 조절 시엔 sin(x) 에 값을 곱해주게 되고, a 값에 따라 진폭이 달라집니다.
a 값이 0일땐 그래프가 평평해 진폭이 없다가, 값이 커지면 진폭 또한 커지게 됩니다.

진폭이 변경되면, 값의 강도가 변경되게 됩니다. 알파 애니메이션으로 비유하자면, 진폭이 커지면 0와 0.5 사이에서 변화하던 알파값이 0에서 1.0 사이에서 변화하게 되는 식입니다.

 


 

sin(time) 을 활용한 깜빡이는 알파 애니메이션 예제

그럼 예제로는 간단하게, 알파값 0.5와 1 사이에서 깜빡임을 반복하는 셰이더 애니메이션을 만들어 보겠습니다.

먼저 알파값이 0.5와 1 사이를 움직이니, 그래프의 전체 높이를 0.5로 만들어 줘야겠죠.
sin(x) 는 -1과 1 사이를 움직이니 전체 높이는 2이고, 이를 0.5로 만들어 주려면 0.25 를 곱하면 됩니다.

 

0.25 를 곱해 전체 높이를 0.5로 만든 그래프

 

위와 같이 sin(x)에 0.25를 곱하면, 그래프는 -0.25와 0.25 사이에서 움직이게 됩니다.
애니메이션되는 알파의 최소값이 0.5여야 하니, 수직이동때 배운 것처럼 이동값을 sin(x) 에 더해줍니다. 현재 그래프의 최저점인 -0.25 를 0.5로 만들어주기 위해서는, 0.75 를 더하면 되겠죠.

 

0.75를 더해 0.5와 1 사이에서 움직이는 그래프

 

위의 수식을 메테리얼 노드로 옮긴다면 아래와 같은 구조가 됩니다.
Amplitude 파라미터는 애니메이션되는 크기(알파값 애니메이션의 최소 최대치)를, Position 파라미터로는 애니메이션의 중간 직선을 조절할 수 있습니다.

 

수식을 메테리얼로 나타낸 예
적용된 알파 애니메이션

 

알파값이 0.5와 1 사이에서 애니메이션되긴 하는데, 조금 느립니다. 이럴 때, 주기를 줄이면 되겠죠. (x스케일)

그래프 변형하기 챕터의 첫 단락에서 다룬 주기 역할의, 애니메이션 속도를 조절해줄 Speed 파라미터를 추가해줍니다. 그 다음, 수식처럼 time 값과 Speed 값을 곱해주면 됩니다.

 

Speed 파라미터를 추가한 메테리얼 노드
Speed 파라미터 조절 예

 

Speed 변수에 원하는 적당한 값을 넣어줍시다. 이제부턴 느낌의 영역이니 그래픽 계산기는 뒤로 던져도 됩니다.

 


 

이미지 출처

선형 애니메이션과 보간된 애니메이션의 차이
진폭과 주기 - 칸 아카데미

 

 

 

'Graphics' 카테고리의 다른 글

색수차 효과 셰이더 만들기  (0) 2023.12.30
색상 간의 혼합 - 기초 블렌딩 연산  (0) 2023.10.09
SDF (Signed Distance Field)  (0) 2023.09.17
색체계와 색의 구성요소  (0) 2023.07.15
디지털 색상과 수  (0) 2023.06.25