Graphics Programming

OpenGL의 큐브맵 좌표 본문

Season 1/OpenGL

OpenGL의 큐브맵 좌표

minseoklee 2016. 10. 20. 21:52

큐브맵은 스카이박스와 환경 매핑(Environmental mapping)을 구현할 때 유용한 기능이다.


큐브맵을 샘플링할 때는 큐브맵 샘플러와 방향 벡터가 필요하다.


#version 430 core


layout (binding = 0) uniform samplerCube texCube;


in VS_OUT { vec3 tc; } fs_in;


layout (location = 0) out vec4 color;


void main() {

  color = texture(texCube, fs_in.tc);

}


원점에서 방향 벡터를 따라갈 때 도달하는 텍셀을 샘플링하는데, 이 벡터가 문제다.


모델의 기하 정보를 기술할 때 OpenGL은 오른손 좌표계를 사용한다. 즉 화면 오른쪽이 +x축, 위쪽이 +y축일 때 화면에서 나오는 방향이 +z축이다. 그런데 OpenGL은 정점 좌표를 NDC로 변환하고 나면 왼손 좌표계를 사용한다. 화면으로 들어가는 방향이 +z축이다.




그리고 큐브맵 샘플링에 쓰는 방향 벡터는 바로 왼손 좌표계를 사용한다. 이것 때문에 스카이박스와 환경 매핑을 구현할 때 방향이 어긋나게 된다. 반대쪽에 있는 면을 샘플링하거나 면은 맞는데 좌우 또는 상하가 뒤집혀서 그려지는 것이다.


그러면 방향 벡터의 z 좌표만 -1을 곱하면 되는 걸까? OpenGL 4.5 코어 프로필의 명세를 보자. (8.13절 Cube Map Texture Selection)




positive z의 네 모서리 (-1, -1, 1), (1, -1, 1), (-1, 1, 1), (1, 1, 1)를 그대로 화면 좌표와 샘플링 벡터로 쓴다고 가정하자. 방향 벡터의 z = 1일 때 s와 t를 계산해보면 s = 0.5 * (x + 1), t = 0.5 * (-y + 1)이 나온다. 그런데 텍스처 원점 (0, 0)은 왼쪽 아래다. 위 식대로면 (x, y) = (-1, 1) 즉 왼쪽 위 모서리에서 텍스처 원점을 추출하게 된다. 그려보면 이미지가 상하로 뒤집힌다.


방향 벡터의 z 성분 뿐만 아니라 y 성분에도 -1을 곱해야 올바른 면을 올바른 각도로 그릴 수 있다. 여기서... y 성분에 -1을 곱했기 때문에 positive y/negative y면은 또 반대로 추출된다. 그래서 텍스처에 이미지를 업로드할 때 두 면의 이미지를 교환해야 한다. 이렇게 무슨 이유에선지 OpenGL은 좌표계를 이거 썼다가 저거 썼다가 샘플링 좌표 계산도 뒤죽박죽이다.


분노의 요약짤


Comments