top of page
  • 작성자 사진Nobody

(UnityShader) Polar Coordinate Part 1

최종 수정일: 2022년 5월 29일


이번 포스트에서는 극좌표의 정의를 알아보고 유니티 셰이더로 구현하고 응용하는 방법에 대해서 알아보겠습니다.


직교좌표계

(Coordinate system)


수학에서 평면 위에 있는 어떤 점의 위치를 표현해야 할 때, 서로 수직이며 직교 하는 직선인 x, y 두 축을 사용한 좌표계로 점의 위치를 나타냅니다. 점과 두 축 사이의 거리 값으로 점의 위치를 나타내는 방법이며, 직교 좌표계(Cartesian coordinate system) 혹은 이를 소개한 수학자의 이름을 따서 데카르트 좌표계라고 부릅니다.



점의 위치를 가로 거리 값을 x, 세로 거리 값을 y로 하여 (x,y)의 순서쌍으로 나타냅니다. 예를 들어 위에 찍혀있는 점의 위치는 (2,1)으로 표현 할 수 있습니다. 따라서 x와 y의 거리 값이 둘다 0이면 (0,0)이며 이를 원점이라고 부릅니다.


(UV Coordinate)


렌더러가 셰이더를 통해 오브젝트에 텍스쳐를 매핑할 때 필요한 텍스쳐의 UV 역시 직교좌표계와 똑같습니다. 단지 이름만 바뀌었을 뿐이죠.



극좌표계


좌표계의 정의를 알게 되었으니 이제 아이작 뉴턴이 소개한 극좌표계(Polar coordinate system)를 알아봅시다. 극좌표계에서 사용하는 축은 특이한 형태 입니다.


(직교좌표계 / 극좌표계)


수직인 두 직선을 축으로 사용하는 직교좌표계와 달리 극좌표계는 반직선원점을 축으로 사용하는 좌표계입니다. 반직선인 x축을 극축(Polar Axis)이라고 부릅니다.



임의의 점 (x, y)를 극좌표로 나타내면 다음과 같습니다. 극축과 이루는 각도(Radian) θ와 원점과의 거리 값 r을 순서쌍으로 나타내는 좌표계 입니다.




위 이미지 처럼 셰이더에서 직교좌표계를 사용하는 UV를 삼각함수를 이용하여 극좌표계로 변환 할 수 있습니다.



라디안과 삼각함수


(θ = 1 Rad)


라디안(Radian)과 회전 행렬을 다룬 이전 포스트를 기억하시나요? 읽지 못한 분들을 위해 쉽고 간결하게 설명 드리겠습니다.


여기 반지름이 1인 원이 있습니다. 이것을 단위 원이라고 합니다. 그리고 호의 길이가 반지름과 똑같이 1이 되는 각도 θ로 부채꼴을 잘라냈습니다. 이때 각도 θ의 값이 바로 1 라디안 으로 정의했습니다.


수치로 표현하면 1 라디안은 180˚ / π 입니다.



그럼 이제 반지름을 셰이더에서 사용하는 벡터로 생각해봅시다. 크기가 1인 단위 벡터(0, 1)이 있고 직교 좌표계 위에서 각도 θ 만큼 회전하면 이제 벡터의 방향은 float2(0, 1)이 아니지만 크기는 1으로 같습니다.


(삼각 함수, Trigonometric functions)


이제 벡터를 하나의 직각삼각형으로 생각해봅시다.

  • 단위 벡터의 크기를 빗변 a,

  • 단위 벡터의 x축 좌표를 밑변 b,

  • 단위 벡터의 y축 좌표를 높이 c,

로 가정해서 삼각함수를 대입해서 풀어보면?



네, 저희가 회전 행렬을 유도 할 때 여기까지는 했었죠.


얼마 만큼의 각도 θ로 회전하던 간에, 벡터의 머리 좌표는 항상 (sinθ, cosθ) 입니다. b와 c의 길이가 항상 sinθ와 cosθ기 때문입니다.



반지름이 1인 단위 벡터가 아닌 경우에는 반지름 길이 값 만큼 삼각함수에 곱해주면 똑같다는 것을 알 수 있습니다. 여기까지 읽었을 때 저희 같은 아티스트들은 이런 사실이 직관적으로 이해가 되지 않을 수 있습니다. 그러니 다른 방법으로 한 번 해봅시다.


똑같은 직각삼각형을 세개 더 추가하여 위와 같이 배치합시다. 그러면 저희는 반지름을 변으로 가지는 정사각형을 얻게 됩니다.


  • 빨간색 정사각형의 넓이는 r²

  • 초록색 직각삼각형의 넓이는 (r * cosθ * r * sinθ) /2

  • 전체 넓이는 (r * cosθ + r * sinθ)²

따라서 빨간색 정사각형과 초록색 직각삼각형 네개와 더하면 전체 넓이와 같습니다. 식을 세워 봅시다.

(r * cosθ + r * sinθ)² = 4*1/2 * r * cosθ * r * sinθ + r²

한 눈에 보기 굉장히 불편하네요. 식을 치환해서 보기 좋게 바꿔봅시다.


r * cosθ는 모든 벡터의 x축 좌표죠? r * cosθ = x

r * sinθ는 모든 벡터의 y축 좌표죠? r * sinθ = y

로 치환하면 아래와 같이 정리됩니다.


(x+y)² = 2xy + r²

(x+y)² - 2xy = r²

x² + 2xy + y² - 2xy = r²

x² + y² = r²

잠시만요, 이 공식 어디서 많이 보던 것 같은데 눈치 채셨나요?


그렇습니다. 저희는 방금 피타고라스 정리를 증명한 것입니다.


(원의 방정식)


피타고라스 정리를 그래프로 그렸을 때 원이 나옵니다. 반지름 값이 얼마이든 좌표는 항상 (r*sinθ, r*cosθ)인 것을 확인 하실 수 있습니다.


(탄젠트의 경우)


극좌표계는 극축인 x축과 이루는 각도 θ와 원점과의 거리 값 r의 순서쌍으로 나타냅니다. 원의 반지름이 r인데, 곧 원점과의 거리 값이랑 똑같지요. 그러니 각도만 구하면 됩니다.


tanθ 값은 직교좌표계 평면 위에서 임의의 점(x, y)에 대한 기울기(y/x) 라는 사실을 알 수 있습니다.


(y/x)

tanθ = y/x

각도 θ는 직교좌표계 위에 그려질 수 있는 모든 벡터와 극축이 이루는 각도입니다. 모든 벡터가 들어있는 데이터는 직교좌표계인 UV 그 자체입니다. UV의 x축과 y축에 대한 y/x를 계산하면 tanθ가 나옵니다. (x나 y 좌표 값이 0인 경우에는 기울기 값이 무한대가 됩니다)


따라서 탄젠트 함수에 각도 θ를 대입하면 기울기(y/x)가 나오니까 반대로 기울기를 대입하면 각도를 반환하게 거꾸로 계산하면 모든 좌표에 대한 각도를 얻을 수 있습니다.



역삼각함수


이렇게 거꾸로 계산하는 함수를 역함수라고 부릅니다. 삼각함수도 당연히 함수의 일종이며, 저희는 탄젠트의 역함수를 구해볼 것입니다. 먼저 역함수의 개념을 정확히 이해해야 합니다.


쉽게 1차 함수로 예를 들어 봅시다. y = x + a 라는 함수가 있다고 한다면, 위와 같은 모습으로 그래프가 그려집니다.

  • x = 1 이면 y = 1 + a니까 y는 2입니다.

  • x = 2 이면 y = 2 + a니까 y는 3입니다.

y에 대응 하는 x값이 존재하며 항상 하나 밖에 없습니다. 이것을 일대일 대응 한다고 말합니다.


일대일 대응 하지 않는 함수의 예시로 2차 함수 그래프를 보여 드리겠습니다.

  • x = 2 이면 y = 2² 니까 4입니다.

  • x = -2 이면 y = -2² 니까 똑같이 4입니다.

y에 대응 하는 x값이 두개입니다. 이런 경우에는 일대일 대응하지 않습니다.

오직 일대일 대응하는 함수에만 역함수가 존재합니다.


(y = 2x)


이제 y = 2x 의 역함수를 구해봅시다. 역함수를 계산하는 방법은 간단합니다. x를 좌변으로 정리해주면 됩니다.


(역함수 그래프)

y = 2x

-2x = -y

x = y / 2


이렇게 정리 한 후 그래프로 그리려면 좌변에 y값이 있어야 하니, x와 y의 위치를 바꿔주면 됩니다.

y = x / 2

시각적으로 이해하기 쉽게 함수와 역함수에 변수를 하나 추가하였습니다. 두 함수의 관계는 함수와 그 역함수로 동일합니다. 각각 f1과 f2로 부르겠습니다.



함수와 역함수의 성질은 x값 대신 함수를 집어넣어서 그래프를 그려보면 알 수 있습니다.

f1(f2)인 경우의 그래프와 f2(f1)인 경우의 그래프를 보면 y = x 형태가 되어 정의역과 공역이 같은 항등함수 모양이 됩니다.


이제 삼각함수의 역함수인 역삼각함수를 구해봅시다.


(sine)


sin이나 cos의 그래프를 그려보면 각도 값에 따라 물결 모양이 반복되는 그래프가 그려집니다. 이런 경우에는 y에 대응하는 x값이 무한합니다. 위에서 언급 했듯이 함수는 일대일 대응이어야 역함수가 존재 할 수 있는데 어떻게 해야 할까요?



저희는 범위를 제한하는 꼼수를 씁니다. x축 정의역을 [-π/2 ~ π/2]로 제한해서 역함수를 만들어보는 것입니다.


삼각함수는 항상 반복되는 주기를 가지고 있으니 반복되는 부분을 자르면 치역의 범위는 [-1 ~ 1]이 되어 y에 대응하는 x값은 항상 하나 뿐 입니다. 그래서 일대일 대응이 성립합니다.


(arcsin)


sin 함수의 역함수는 arcsin이라고 부릅니다.


sin 함수에 각도[-π/2 ~ π/2]를 대입하면 반환하는 것은 직각삼각형의 높이 값[-1 ~ 1]입니다. 역함수의 정의에 따라 반대로 높이 값[-1 ~ 1]을 대입하면 각도[-π/2 ~ π/2]를 반환합니다.


(sin(90˚)은 y축 값이 1, arcsin(1)은 π/2 = 90˚)


따라서 y = x 그래프를 기준으로 대칭 이동한 것과 똑같은 결과물을 얻을 수 있습니다.


(arccos)


코사인의 경우는 반복되는 부분인 정의역을 [0 ~ π]로 제한합니다.


cos 함수의 역함수는 arccos 이라고 부릅니다.


cos 함수에 각도[0 ~ π]를 대입하면 반환하는 것은 직각삼각형 밑변의 길이 값[-1 ~ 1]입니다. 역함수의 정의에 따라 반대로 길이 값[-1 ~ 1]을 대입하면 각도[0 ~ π]를 반환합니다.


(cos(180˚)은 x축 값이 -1, arcsin(-1)은 π = 180˚)





드디어 대망의 탄젠트의 역함수를 구해보겠습니다. 탄젠트는 곧 기울기(y/x)입니다. 그래서 각도가 90(π/2)일 때, 기울기 값은 무한히 커집니다. 음수인 -90(-π/2) 경우에는 반대로 무한히 작아집니다. 밑변의 길이가 0인 삼각형을 상상해보세요.


똑같이 반복되는 구간인 x축 정의역을 (-π/2 ~ π/2)로 제한해서 역함수를 만들어보겠습니다. y값은 무한히 커지고 작아지기 때문에 실수 전체를 공역으로 두지만 y에 대응하는 x값은 항상 하나라서 일대일 대응 한다는 것을 알 수 있습니다.




tan 함수에 각도(-π/2 ~ π/2)를 대입하면 반환하는 것은 기울기 값(-∞ ~ ∞)입니다. 역함수의 정의에 따라 반대로 기울기 값(-∞ ~ ∞)을 대입하면 각도(-π/2 ~ π/2)를 반환합니다.


tan 함수의 역함수는 arctan 이라고 부릅니다.


(부채꼴 호와 반지름의 관계)


arcsin, arccos, arctan 등등 역삼각함수의 이름에 공통적으로 'arc'가 들어가는데요, 그 이유는 위에서 1 라디안을 정의할 때 쓴 부채꼴의 호가 바로 arc입니다.


호의 길이 L과 반지름의 길이 r의 비(L/r)가 1 라디안이며, 역삼각함수는 각도를 반환하는 함수이기 때문에 이런 이름이 붙었습니다.


(tan(45˚)은 기울기 값이 1, arcsin(1)은 π/4 = 45˚)


이제 저희는 모든 직교좌표계에 대한 기울기(x/y)를 대입해서 극축(polar axis)을 기준으로 한 각도 값을 arctan 함수로 구할 수 있습니다.


모든 수학적 이론의 준비를 마쳤습니다. 이제 셰이더 코딩을 해봅시다.


(파트2에 계속)



조회수 625회댓글 0개

최근 게시물

전체 보기
bottom of page