Computer Graphics

Chapter15. 텍스쳐

CodeJB 2021. 6. 14. 18:56

텍스쳐의 필요성

  • 지난 시간까지 살펴보면서 하나의 모델이 만들어지기 까지 수많은 연산 과정이 있었다.
  • 그런데, 울퉁불퉁한 목재, 표면의 굴곡등을 3D 모델링한다면 그만큼 더 많은 연산이 필요할 것이다.(거의 불가능에 가깝다)
  • 반면, 3D모델링을 하지 않는다면 굴곡에 의해 발생하는 음영감을 표현할 수 없어 사실감이 저하된다.
  • 따라서, 3D모델링과 텍스쳐를 적절히 조화시키는것이 매우 중요하다
  • 텍스쳐는 마치 시트지를 붙이듯이 사실감이 높게 적용된 그림을 오브젝트 표면에 입히는 것이다.

  • 라이트 매핑 : 빛의 효과 등을 미리 계산하여 이미지로 만든 후, 물체의 표면 위에 올리는 것도 가능하다

(b)는 빛의 효과를 이미지로 만든 것

  • 주변 매핑 : 물체 외부환경을 매핑하여, 반사되고 있는 반짝이는 물체면을 표현한다.

텍스쳐의 개념

  • 텍스쳐는 특정 모양의 이미지를 3차원 모델의 각 평면에 매핑시키는 것이다.
  • 매핑이라는 것은 A라는 것과 B라는 것을 연결시키는 것.
  • 따라서, 텍스쳐 A의 특정 "지점"과 3D모델 B의 특정 "지점"을 연결시키는 것이 텍스쳐 매핑이다.

텍셀

  • 2차원 텍스쳐 이미지도 마찬가지로 하나하나의 픽셀이 있고, 픽셀 좌표가 존재한다.

텍스쳐 매핑

  • 텍스쳐의 특정 범위를 평면의 특정 범위에 매핑시키는 것이 텍스쳐 매핑이다
  • 텍스쳐의 특정 지점과 평면의 특정 지점을 대응시키는 것이 텍스쳐 매핑이다.

전체 매핑, 일부분 매핑 모두 가능

  • 텍스쳐 매핑은 점대 점으로 대응한다.
  • 텍스쳐 이미지의 해상도가 뷰포트 이미지보다 작을 경우 에일리어싱이 발생할 수 있다.

텍스쳐가 4x4로 작은 이미지면 더 큰 해상도의 뷰포트에 매핑했을 때 당연히 해상도가 안좋아 보일 것이다.

  • 원근 변환을 하는 경우 텍스쳐 매핑의 정확도가 감소한다.
  • 그렇다면, 평면 이미지를 곡면 모델에 매핑하는 방법은 무엇일까?

- 구면의 텍스쳐 매핑 이론

  • 곡면상의 특정 지점에 매핑하는 텍스쳐의 좌표를 곡면상에서 "극 좌표계"로 간주
  • 극좌표계의 점은 반지름(r)과  각(θ)로 표현된다.
  • 3차원 모델의 특정 지점(0,0,1)의 극 좌표계가 (0,1)이라면, 텍스쳐의 (0,1)색상을 가져오는  방식이다.

-다각형 곡면의 텍스쳐 매핑 이론

  • 구면의 텍스쳐 매핑과 유사하다.
  • 각도와 높이, 혹은 각도와 각도로 표현하여 매핑한다.

-중개면을 사용하는 3차원 물체의 텍스쳐 매핑 이론

  • 텍셀과 모델을 바로 대응시키려고 하는데, 3차원 모델이 너무 복잡하다면 연산이 매우 느려지게 될 것이다. 
  • 따라서, 우선 원기둥이나 원 큐브와 같은 모델에 텍스쳐를 매핑시킨다.
  • 매핑된 모델은 "중개면"이 되어, 복잡한 모델에 활용되어 진다,
  • 주전자의 머리가 있다면 그와 가장 가까운 중개면 상의 위쪽 면의 특정 색상과 매핑(꼭 이렇지만은 않음)되는 방식이다.
  • 따라서, 중개면이 무엇이냐에 따라서 매핑 결과가 달라지게 된다.

구현 방법

 

//1. OpenCV를 이용하여 이미지 Read
//2. 색상모델 변경
Mat image[1]; //이미지를 여러개 받아올 수 있도록 배열할당
image[0] = imread("//image path", IMREAD_COLOR);
cvtColor(image[0], image[0], COLOR_BGR2RGB);
    
//텍스쳐는 id로 참조된다.
//텍스쳐의 개수에 따라 id를 배열에 바인딩한다.(id를 부여한다.)
GLuint tex_ids[2] = {1,2};
int nTex = 2;
glGenTextures(nTex, tex_ids);

//부여된 텍스쳐 id를 Texture 2D로 바인딩한다.
glBindTexture(GL_TEXTURE_2D, tex_ids[idx]);

//텍스쳐 사용 설정
glEnable(GL_TEXTURE_2D);

//텍스쳐를 생성한다.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image[idx].cols, image[idx].rows, 0, 
GL_RGB, GL_UNSIGNED_BYTE, image[idx].data); //이미지를 텍스쳐로 쓰겠다

//안티 에일리어싱한다.
//모델의 크기와 텍스쳐의 크기를 대응시키기 위함이다.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);

//모델에 지정되어 있는, 혹은 지정한 vertex 좌표에 텍스쳐 좌표를 대응시킨다.
glTexCoord2f(tx, ty);