프레그먼트에서 무언가를 의미있게 표현하기 위해서는 그 무언가가 픽셀에서 얼마나 떨어져있는지의 거리값을 매우 의미있게 사용한다. 이를 위해 Ray가 필요한데, Ray는 시작점(ro)과 방향(rd)이 중요하다.
void main() {
..
float t = uTime; // 그냥 흘러가는 시간값
// Left-Hand (Z축은 모니터에서 사람을 향하는 방향이 마이너스임)
vec3 ro = vec3(3. * sin(t), 1., -3. * cos(t)); // Ray의 시작점(카메라의 위치), 일단 시간에 따라 Y축으로 회전시켜본다.
}
Ray의 시작점인 ro는 보이는데, 방향인 rd는 아직 보이지 않는다. rd를 정하기 위해 카메라 개념을 이용한다.
void main() {
...
vec3 ro = vec3(3. * sin(t), 1., -3. * cos(t)); // Ray의 시작점(카메라의 위치), 일단 시간에 따라 Y축으로 회전시켜본다.
vec3 lookAt = vec3(.0); // 카메라가 바라보는 지점
vec3 f = normalize(lookAt - ro); // 카메라가 바라보는 방향 벡터
vec3 u = vec3(0,1,0); // 카메라의 Up 벡터
vec3 r = normalize(cross(u, f)); // 카메라의 Right 벡터
float zoom = 1.; // 확대 배율
vec3 c = ro + f * zoom;
vec3 i = c + uv.x * r + uv.y * u; // 교차하는 지점
vec3 rd = normalize(i - ro); // Ray의 방향 벡터
이제 정육면체의 구성 정점 8개를 프레그먼트에 시각화하기만 하면 된다.
void main() {
...
vec3 rd = normalize(i - ro); // Ray의 방향 벡터
float d = 0.;
float off = .5;
d += drawPoint(ro, rd, vec3(0.-off, 0.-off, 0.-off));
d += drawPoint(ro, rd, vec3(0.-off, 0.-off, 1.-off));
d += drawPoint(ro, rd, vec3(0.-off, 1.-off, 0.-off));
d += drawPoint(ro, rd, vec3(0.-off, 1.-off, 1.-off));
d += drawPoint(ro, rd, vec3(1.-off, 0.-off, 0.-off));
d += drawPoint(ro, rd, vec3(1.-off, 0.-off, 1.-off));
d += drawPoint(ro, rd, vec3(1.-off, 1.-off, 0.-off));
d += drawPoint(ro, rd, vec3(1.-off, 1.-off, 1.-off));
gl_FragColor = vec4(d);
}