ㅄ같은 인코딩 쫌만 기다려주라 ㅠㅠ



드디어 멋있어 보이는 바다를 완성했다!

진짜 뒤지게 힘들었다.

푸리에 변환을 사용한 파도 생성, 고속 푸리에 변환의 compute shader 구현 등등.

Vulkan 다루는 건 차라리 쉽다고 생각될 정도로 어려운 내용이 많았다.


지금까지 배운 내용을 블로그로 쓸 예정인데.

디씨에는 수식이나 소스코드 입력이 힘들어서 개인 블로그에 쓸 거임.

일단 지금은 사진 몇 장으로만 소개 가능한 부분들만 보여줄게.


일단 원리적으로는 바다는 수많은 sin 함수 모양의 파동이 합쳐져서 만들어짐.



1fb8c034e0c13da87abec2bc19df69323c1a4efeb6873a16d8b5a78e328c1640163ea1489081bc15bda1d17f9ef9ca4843632fe11daff4ca91078cef75d7a7568473303d5379a05a349a6dcfb7d406c695145a7c83368f


푸리에 변환은, 위 그림에서 제일 아래 데이터를 입력하면 각각의 sin 함수로 분리시켜 준다.

이때 푸리에 변환의 결과값은 x축이 frequency, y축이 magnitude인 데이터가 됨.

푸리에 변환은 여기서 설명하는 것보다는 3Blue1Brown의 푸리에 변환 영상 보는게 젤 이해가 빠르니까 참조하고.

여기서는 그냥 복잡한 파도 형상에 푸리에 변환을 적용하면, 각 sin 파동의 진동수별로 기여도가 얼마나 큰지를 알려주는 데이터를 뽑아내는 것만 알아두자.

이것을 frequency domain이라고 부름.


우리, 게임 개발자는, 누군가 만들어놓은 frequency domain을 가져와서, 여기에다가 역 푸리에 변환을 적용해서 바다 파도 모양을 만들어 내는 거임.

이런 식으로 바다를 만드는 기술을 Tessendorf ocean이라고 부름.


그럼 역 푸리에 변환을 적용했을 때 멋진 파도 모양을 만들어내는 함수를 어떻게 구하는가?

이건 거인의 어깨 위에 올라탈 수밖에 없음.

Tessendorf님은 논문에서 Phillips spectrum이라고 불리는걸 썼는데, 이건 과학자가 실제로 바다에 나가서 오랜 시간 파도를 분석한 뒤 수학적 모형으로 만들어 놓은 거임.

그리고 좀 더 최신 기술로는 JONSWAP spectrum이란 게 있는데, 나는 이걸 썼다.

JONSWAP spectrum은 이렇게 생김.


25edef36e9d336a320afd8b236ef203e480021c69b15e3


이 그림이 무슨 의미인가?

그것만으로 포스트 하나를 따로 써야 할 정도로 방대한 내용이 있음.

일단은 단순하게 이미지의 정중앙을 원점으로, 각 픽셀의 원점과의 거리는 파도의 진동수, 원점으로부터의 방향은 파도의 방향, 픽셀의 값은 해당 파도의 에너지 정도로 알고 넘어가자.


18b3c42ff1de3da223ee98a518d604037887ee623472c3ba61


테센돌프님의 제안대로 각 픽셀에 가우시안 랜덤을 적용한 것을 frequency domain 데이터로 사용한다.

이제 각 픽셀에 exp(iwt)라는 dispersion 항을 곱해주는데, e^i 부분을 보면 알수 있듯이 복소수임.

이를 곱하면 시간을 따라 파도가 움직임.


참고로 가우스 랜덤 적용 안하면 어떻게 되느냐...

그건 혐짤이므로 다른 글에 올리겠다. ㅋㅋㅋㅋ


이제 여기다가 역 푸리에 변환을 적용하면 된다.



24bbc468e2db3e8650bbd58b3682776e792293


고속푸리에 변환을 이용해 컴퓨트 셰이더에서 작동하므로 엄청 빠르다.

심지어 갤럭시S 울트라21에서도 꽤 괜찮은 프레임레이트로 구동함.

이것도 나중에 보여줄게.


아무튼 역 푸리에 변환을 이용해 완성된 데이터를 잘 조합하면, 평평한 평면의 각 점을 얼마만큼 이동시켜줘야 바다 모양이 되는지 알수 있게 된다.



29b4c336e9d33ba363bad8a158c12a3a3b31aead4a2ddbebc42c0f06


RGB 채널이 각각 XYZ 방향 displacement다.

이제 테셀레이션을 쓰던가 해서 수많은 버텍스를 만들어낸 뒤 적절하게 displacement를 적용해 주면 바다가 완성된다.


물론 노말은 어떻게 계산하느냐, 거품은 어떻게 만들어내느냐, 바다 표면 색깔이나 광원은 어떻게 하는가 등등.

여기서 다룬 것보다 엄청나게 많은 내용이 더 있다.

그리고 수학적으로도 더 깊에 다룰 것들이 많다.

그런 내용들은 앞으로 천천히 만들어 나갈 예정.