굴절 패스로 물 밑이 실제로 보이기 시작하자, 그 안에 아무것도 없다는 게 눈에 띄었습니다. 물고기를 넣었습니다.
물을 통해서만 보인다는 사실이 설계를 정했습니다
물고기는 굴절 패스가 그리는 씬에 들어갑니다. 그래서 물 셰이더가 앞을 가로막은 물의 양만큼 알아서 감쇠시킵니다.
깊이에 따라 흐려지고, 어두워지기 전에 먼저 초록으로 갑니다. 물의 흡수가 빨강부터 먹기 때문인데, 이걸 위해 따로 만든 코드는 없습니다. 이미 있던 흡수 계산이 물고기에도 그대로 적용될 뿐입니다.
대신 제약이 하나 생깁니다. 수면을 뚫고 나가면 사라집니다. 물 셰이더는 수면 위에서 온 샘플을 기각하는데(안 그러면 마른 육지가 바다에 칠해집니다), 물고기도 예외가 아닙니다. 그래서 무리 행동에 "이 이상 올라오지 말 것"이라는 천장이 필수였습니다.
무리는 서로를 안 봅니다
무리 짓기를 개체 쌍마다 계산하지 않습니다. 무리 전체의 중심과 평균 진행 방향에 대해서만 계산합니다.
쌍마다 보는 게 정석이지만 매 프레임 제곱 비용입니다. 그리고 이 화면 크기에서는 결과가 구분되지 않습니다. 무리로 읽히게 만드는 건 공유된 진행 방향과 촘촘한 간격인데, 둘 다 싼 방식에서 그대로 나옵니다.
역음영을 열대어에 쓰면 안 됐습니다
물고기는 보통 등이 어둡고 배가 밝습니다. 위에서 보면 어두운 바다에 섞이고 아래에서 보면 밝은 하늘에 섞이는 위장입니다.
그대로 넣었더니 리프 물고기가 밝은 모래 위의 어두운 점이 됐습니다. 당연합니다 — 그 무늬는 배에서 내려다볼 때 안 보이라고 있는 것입니다. 그런데 산호초 물고기는 원색으로 요란한 게 정체성입니다. 위장하지 않는 쪽이 실제에 가깝습니다. 어종 색을 살렸습니다.
큰 물고기는 크게 만들어도 크게 안 보입니다
대형종을 모델만 키워서 넣으면 여전히 작은 물고기로 읽힙니다. 마흔 마리가 떼로 다니면 크기와 무관하게 작은 물고기입니다.
크기는 개체 수로 표현했습니다. 한두 마리씩, 더 깊은 곳에, 몸통이 굽이치는 주기를 몸 길이에 반비례시켜 느리게. 실루엣은 등지느러미와 초승달 꼬리가 담당합니다.
돌고래와 물고기의 차이는 장식이 아닙니다
한 종을 크기만 바꿔 재활용하려다 그만뒀습니다.
고래류는 꼬리가 수평이라 몸을 위아래로 굽혀 헤엄칩니다. 물고기는 수직 꼬리로 좌우로 굽힙니다. 멀리서 종을 알아보게 하는 건 실루엣보다 이 움직임이라, 셰이더의 몸통 파동 축 자체를 종 파라미터로 뺐습니다.
돌고래가 안 뛰던 이유 둘
돌고래는 수면 위로 뜁니다. 물 밖에서는 저을 것이 없으므로 착수할 때까지 그냥 던져진 물체입니다. 도약의 궤적이 여기서 나오고, 그래서 키프레임이 필요 없습니다.
두 렌더 패스가 씬을 나누는 방식 덕에 전환도 공짜입니다. 수면 위에서는 물보다 카메라에 가까우니 메인 패스에 그려지고, 아래에서는 굴절 패스가 실어 나릅니다.
처음엔 최고 높이가 수면 위 0.2m였습니다. 원인이 둘이었습니다.
순항 속도 조절기가 매 스텝 초과 속도의 18%를 깎는데, 초당 60번이면 도약 임펄스가 수면에 닿기도 전에 사라집니다. 그리고 무리 유영 깊이가 수심의 28%라 수심 20m에서는 5.6m 아래에 있어서, 도약 판정에 걸리지도 않았습니다.
수면 돌파 종은 얕은 최소 깊이에 붙여 두고, 발사 직후 0.9초 동안 조절기를 껐습니다. 실측 최대 2.6m입니다.
"이게 물고기냐"
지적을 받고 보니 돌고래가 흰 물고기로 보였습니다. 원인이 셋이었습니다.
지느러미가 두께 0인 부채꼴이었습니다. 공짜인 만큼 그렇게 보입니다. 옆에서 보면 사라지고 나머지 각도에서는 오려낸 종이 같습니다. 실제 지느러미는 가운데가 두껍고 가장자리로 갈수록 날카로운 렌즈 단면이고, 그 단면이 앞쪽 가장자리에서 빛을 받는 것이 지느러미로 읽히는 이유입니다. 외곽선을 안쪽으로 밀어 넣은 링을 두께만큼 띄우고 양면을 이어 만들었습니다. 테두리는 0이라 날은 진짜로 날카롭습니다.
몸통을 만드는 수식이 주둥이를 못 만들었습니다. 볼록한 곳이 하나뿐이고 그 지점에 대해 대칭인 형태였습니다. 이마 앞에 주둥이가 나온 형태 — 모든 고래류 — 는 그 수식으로는 그냥 어뢰가 됩니다. 프로파일을 제어점으로 직접 그리게 바꾸고, 단면 중심을 위아래로 띄우는 값을 넣었습니다. 돌고래 이마가 여기서 나옵니다. 중심이 0에 고정된 형태에서는 이마를 올리면 턱도 같이 내려갑니다.
광택이 무늬를 덮고 있었습니다. 반사 피크가 2.61이었습니다. 밝은 배(1.65)도 어두운 등(0.19)도 전부 덮어써서 무늬가 사라졌습니다. 환산하면 피크 반사율 0.318인데, 젖은 표면은 정면에서 0.03쯤입니다. 열 배 넘게 과했습니다.
그리고 돌고래와 상어의 무늬는 부드러운 그라데이션이 아닙니다. 두 개의 평평한 색면과 그 사이의 선입니다. 사람이 실제로 알아보는 건 그 경계선이라, 등쪽 안장과 선을 따로 그리게 했습니다.
남는 것
셋 다 "물리적으로 대충 맞다"에서 멈춘 값이었습니다. 지느러미는 면이면 됐고, 몸통은 매끈하면 됐고, 젖었으니 반짝이면 됐습니다. 그런데 사람이 무엇을 보고 그 동물을 알아보는지는 별개의 질문이었습니다.