2D 타일 게임에서 부드러운 물 구현하기

2020-01-30

물을 시뮬레이션하기!

목차

  1. 2D 타일 게임에서 빛 전파 구현하기 - Point Light
  2. 2D 타일 게임에서 빛 전파 구현하기 - Directional Light & Color Light
  3. 2D 타일 게임에서 부드러운 물 구현하기

Cellular Automata

Cellular Automata 가스퍼의 글라이더 건 - Game of Life

Game of Life는 가장 널리 알려진 셀룰러 오토마타의 일종입니다. 단순한 규칙으로 무수히 복잡한 패턴들을 만들어낼 수 있죠. 각 셀에서 인접한 8개의 이웃을 확인하여 셀을 살아있거나 죽어있는 상태로 유지하게 됩니다. 이렇듯 자신의 상태를 이웃의 상태에 따라 결정하는 것을 셀룰러 오토마타라고 합니다.

물 시뮬레이션

격자 형태의 세계에서 물을 시뮬레이션 하는 방법은 다양하게 있지만, 셀룰러 오토마타는 계산이 가벼워 게임에서 사용하기 적당합니다. 물을 시뮬레이션하기 위해서 우선 생각해야 할 점은 물을 약간 압축 가능한 타일로 생각하는 것입니다. 만약 물 타일이 2개 이상 쌓여있다고 할 때 아래 타일은 위 타일보다 물을 더 많이 가지고 있을 수 있죠. 알고리즘을 대략 살펴봅시다.

아래로 물 이동

만약 아래로 물을 이동할 수 있다면 물을 이동합니다. 이를 더이상 가능하지 않을 때 가지 반복합니다. 아래 셀로 유입될 수 있는 물의 양은 현재 셀에 있는 물의 양에 따라 계산합니다. 아래 셀이 물이 더 적을 때만 이동할 수 있습니다.

양옆으로 물 이동

아래로 물을 이동시켰다면 남은 물을 양옆으로 이동시켜야 합니다. 만약 왼쪽 셀이 벽이고, 오른쪽 셀이 아직 물을 더 가질 수 있다면 오른쪽 셀로 물을 이동시키는 거죠. 위 영상에서는 양옆 셀 모두 이동이 가능하므로 이동을 합니다.

압력에 따라 물을 위로 이동

현재 셀에 허용된 물보다 더 많은 물이 포함되어있다면 위쪽으로 흐르게 됩니다. 물을 압축이 가능한 타일로 생각했기 때문에 단지 중력만 가지고 있는 모래와 큰 차이를 가지게 됩니다.

부드러운 물 표현하기

Before After
fixed4 frag (v2f i) : COLOR
{
    i.color.a = step(i.uv.y / i.uv.w, i.color.a);
    return i.color;
}

처음에는 물을 표현할 때 타일 기반 게임이기 때문에 렌더링을 단지 물의 양에 따라 알파를 다르게 그렸습니다. 하지만 그러면 물의 높낮이를 나타낼 수 없죠. 따라서 불투명도를 조절하기보다는 쉐이더에서 Step 함수를 이용해 그리면 높낮이를 표현할 수 있습니다.

유용한 링크

코드 (Git Repository)

simple-fluid-simulation