CubeMap
카테고리: OpenGL
태그: Graphics
Main Reference
- Learn OpenGL
- Rinthel Kwon - OpenGL Lecture
CubeMap
Cube Map | Mapping |
---|---|
큐브맵은 2D 텍스처 6장을 정육면체 형태로 이어붙인 텍스처 맵을 말한다. 주로 주변 환경을 그리거나, 주변 환경을 반사시켜 적은 비용으로 사실감을 높이는데 사용된다.
Example
void CubeTexture::Bind() const {
glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
}
bool CubeTexture::InitFromImages(const std::vector<Image*>& images) {
glGenTextures(1, &m_texture);
Bind();
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (uint32_t i = 0; i < (uint32_t)images.size(); i++) {
auto image = images[i];
GLenum format = GL_RGBA;
switch (image->GetChannelCount()) {
default: break;
case 1: format = GL_RED; break;
case 2: format = GL_RG; break;
case 3: format = GL_RGB; break;
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB,
image->GetWidth(), image->GetHeight(), 0,
format, GL_UNSIGNED_BYTE,
image->GetData());
}
return true;
}
glBindTexture
: 큐브맵 텍스처를 바인딩할 때에는 GL_TEXTURE_CUBE_MAP 지정glTexParameteri
: 큐브맵의 texCoord는 3차원이므로 warpping설정 각 축마다 총 3개 필요glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, ...)
- 큐브맵 텍스처를 생성할 때 이미지 6장을 받아와 하나하나
glTexImage2D
를 통해 gpu 메모리로 보내줘야 함 - target enum에
GL_TEXTURE_CUBE_MAP_POSITIVE_X
부터 큐브맵 전용 텍스처 값이 쭈루룩 지정되어 있음
- 큐브맵 텍스처를 생성할 때 이미지 6장을 받아와 하나하나
- 사이즈가 큰 큐브에 텍스처 입혀주면 간단하게 구현 가능
- 당연하지만 큐브맵으로 이루어진 배경까지 보려면 카메라의 frustum 범위를 큐브에 맞게 늘려줘야 함
Environment Mapping
큐브맵 텍스처를 잘 활용하면 단순한 skybox(배경)이상의 것들을 할 수 있는데, 그 중 대표적인 것이 environment mapping이다. environment mapping은 반사광, 굴절광을 미리 연산하여 큐브맵 텍스처 만들어두고 간편하게 가져다 쓰는 기법이다. 미리 연산한다는 점에서 움직이는 물체에 대한 반사광까지도 완벽하게 표현할 수는 없지만 상당히 자연스러운 반사광을 쉽고 빠르게 구현할 수 있다.
위 그림은 단순하게 skybox의 반사광만을 environment mapping 한 것이다. 실제로는 반사광, 굴절광에 대한 큐브맵 텍스처가 따로 존재하고, 물체 고유의 diffuse, specular값과 결합되어 연산하게 된다. 또한 환경맵을 dynamic하게 만들면, 시간의 흐름에 따른 배경 효과도 구현한 수 있다. 물론 리얼타임 비용이 늘어나겠지만 굉장히 효율적인 방식인 것 같다.
댓글 남기기