불규칙한 형태의 사실적인 포보스 만들기
지금까지 지구, 태양, 토성과 같은 천체를 거의 완전한 구형으로 표현했다. 이들은 매끄러운 구형을 이룰 만큼 충분히 큰 중력을 가지고 있다. 하지만 화성의 위성 중 하나인 포보스(Phobos)는 질량이 작아 울퉁불퉁한 표면을 매끄럽게 만들 만큼 중력이 강하지 않기 때문에 불규칙한 형태를 가진다. 이 글에서는 포보스의 울퉁불퉁한 형상을 렌더링하는 방법을 설명한다.
이 글은 태양계 시뮬레이터 시리즈의 일부다:
- Three.js 좌표계 기초
- Three.js PBR (물리 기반 렌더링) 재질 기초
- 사실적인 지구 만들기
- 사실적인 태양 만들기
- 고리가 있는 행성 만들기
- 불규칙한 형태의 위성 만들기
- 태양을 빛나게 하기
- 은하수 스카이박스 만들기
- 타원 궤도 계산하기
이전 글들1에서는 산, 계곡, 구름을 표현했지만, 이들은 구의 표면에 텍스처로 표현된 것이며, 그 그림자가 구를 복잡한 모델처럼 보이게 했다. 지구 표면의 고도 변화는 그 반지름에 비해 무시할 만큼 작기 때문에 이전 방법들로 충분히 표현할 수 있었다. 그러나 포보스의 고도 변화는 그 반지름에 비해 충분히 작지 않으므로, 지구와는 다른 geometry를 사용해야 한다. 아래 코드를 보자.
uniform sampler2D u_dispTexture;
uniform float u_dispScale;
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
varying mat3 vTbn;
attribute vec4 tangent; // "geometry.computeTangents()" is needed.
void main() {
vUv = uv;
vNormal = normalize(mat3(modelMatrix) * normal);
vPosition = mat3(modelMatrix) * position;
float displacement = texture2D( u_dispTexture, vUv ).r;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position + u_dispScale * (displacement - 0.5) * normal, 1.0);
vec3 t = normalize(tangent.xyz);
vec3 n = normalize(normal.xyz);
vec3 b = normalize(cross(t, n));
t = mat3(modelMatrix) * t;
b = mat3(modelMatrix) * b;
n = mat3(modelMatrix) * n;
vTbn = mat3(t, b, n);
}
기존의 (지구, 태양, 토성 등의) 정점 셰이더 코드와 비교하면, 변경된 부분은 다음과 같다.
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
에서
float displacement = texture2D( u_dispTexture, vUv ).r;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position + u_dispScale * (displacement - 0.5) * normal, 1.0);
로 바뀌었다. 변위(displacement) 텍스처 맵의 값은 평균 반지름이 0인 정규화된 고도로 주어지며, 정점의 위치는 법선 벡터 방향으로 u_dispScale * (displacement - 0.5)만큼 확장된다. u_dispScale의 값은 직접 선택할 수 있다.
| 작은 스케일 | 큰 스케일 |
|---|---|
![]() |
![]() |

