텍스처 맵핑
텍스처 맵핑(Texture Mapping)은 3차원 물체의 표면에 이미지를 입히는 기법이다.
3차원 표면에 울퉁불퉁한 모양이나 나무 무늬 등을 그려 넣으려면 조명이나 물체의 재질을 지정하는 방법으로는 한계가 많다. 대량의 정점이 필요하고 정점이 많아지면 속도도 느려진다.
텍스처 맵핑은 미리 만들어져 있는 이미지를 다각형의 표면에 그려 넣음으로써 임의의 무늬를 빠른 속도로 그려내는 획기적인 방법이다.
텍스처 맵핑은 이미지를 읽어야 하고 각 면에 이미지의 어디쯤이 대응될 것인지를 일일이 지정해야 하므로 구현 단계는 다소 복잡하고 어렵다.
이미지의 데이터양도 꽤 많은 편이지만 다행히 현대의 그래픽 카드는 하드웨어 차원에서 텍스처를 지원하므로 속도는 만족할만큼 빠른 편이다.

 

텍스처 맵핑 기능을 사용하려면 먼저 해당 기능을 켜야 한다. 
주로 2차원 평면 이미지로 텍스처를 입히지만 1차원이나 3차원의 이미지를 사용할 수도 있다.
사용할 텍스처의 차원에 따라 개별적으로 활성화시켜야 하며 한번에 하나만 활성화할 수 있다.
통상은 2차원 텍스처를 가장 많이 사용하며 ES 버전은 2차원밖에 지원하지 않는다.
다음은 텍스처로 사용할 이미지를 메모리 버퍼로 로드한다.
여러 가지 방법으로 이미지를 준비할 수 있지만 가장 일반적인 방법은 이미지 파일에서 읽어오는 것이다.
앞에서 준비해둔 함수로 래스터 데이터를 배열에 읽어 놓는다. 이미지를 바로 사용할 수는 없으며 텍스처 맵핑에 적당한 형태로 가공해야 하는데 이때는 다음 함수를 호출한다.

 

인수가 굉장히 많을 뿐만 아니라 각 인수의 의미도 어렵고 선택할 수 있는 값의 종류도 많다.
target은 이미지로부터 어떤 텍스처를 만들 것인가를 지정한다.
평범한 텍스처를 만들 수도 있고 프록시나 큐브맵을 만들 수도 있다.
level은 밉멥 레벨이되 밉맵을 사용하지 않을 때는 0으로 지정한다.
내부 포맷은 텍셀의 포맷을 지정하는데 GL_RGB, GL_BGR 등등 여러 가지 포맷으로 만들 수 있다.
width, height는 텍스처의 높이이되 반드시 2의 거듭승 크기여야 하며 여기에 경계선의 두께를 더해야 한다.
경계선이 없을 경우 32, 64, 128, 256 정도의 크기면 된다. border는 경계선의 두께를 지정하는데 없으면 0을 준다. format, type, data는 래스터 데이터의 포맷과 픽셀의 타입,
그리고 래스터 데이터 배열이다. 텍스처를 적용하기 전에 맵핑에 관련된 여러 가지 옵션들을 변경할 수 있는데 대부분은 디폴트가 무난하므로 디폴트를 일단 적용하면 된다.
자세한 것은 다음 항에서 따로 연구해 보자. 텍스처가 준비된 다음은 도형의 각 정점과 텍스처의 좌표를 대응시킨다.
도형의 어느 부분에 텍스처의 어디쯤을 출력할 것인가를 지정하는 것이다.
텍스처 이미지는 크기가 제각각인데다 크기를 바꾸는 경우도 종종 있으므로 픽셀 단위로 좌표를 지정하면 일관성이 없다.
그래서 0 ~ 1 사이의 실수 좌표로 비율을 지정한다. 정점의 좌표 표현시 보통 xyzw 명칭을 축으로 사용하지만 축 명칭이 같으면 헷갈리므로 텍스처는 strq라는 좌표축 명칭을 대신 사용한다. 이미지의 크기에 상관없이 텍스처의 좌하단은 (0,0)이고 우상단은 (1,1)이다. 정중앙은 물론 (0.5, 0.5)가 될 것이다. 각 정점에 텍스처의 좌표를 지정할 때는 다음 함수를 사용한다.



정점에 텍스처 좌표를 대응시켜 놓으면 OpenGL이 정점의 위치에 텍스처의 대응되는 픽셀을 읽어 출력할 것이다.
정점들의 중간에는 정점과 텍스처의 거리 비율에 맞게 적당히 늘리거나 줄여서 픽셀들을 대응시켜 다각형 전체에 텍스처를 입힌다. 텍스처와 다각형의 크기가 보통 일치하지 않으므로 스트레칭은 거의 항상 발생한다.
다음 예제는 피라미드에 대리석 모양의 텍스처를 입힌다.
텍스처 맵핑 옵션 텍스처 맵핑은 굉장히 복잡한 연산이어서 선택할 수 있는 옵션들이 아주 많다. 다음 함수는 텍스처 맵핑 환경을 지정한다.

 

target 인수는 어떤 환경을 조정할 것인가를 지정한다.
GL_TEXTURE_ENV, GL_TEXTURE_FILTER_CONTROL, GL_POINT_SPRITE 중 하나이다.
pname은 조정하고자 하는 옵션의 이름이고 param은 옵션의 값이다. GL_TEXTURE_ENV_MODE는 텍셀의 색상과 지오메트리의 색상을 결합하는 방식 지정하는데 다음 여섯 가지 방식이 있다.
방식 GL_MODULATE 두 색상을 곱한다.
GL_REPLACE 색상을 무시하고 텍스처로 덮어쓴다. GL_ADD 두 색상을 더한다. GL_DECAL GL_BLEND 블랜딩 색상과 텍스처를 혼합한다. GL_COMBINE 피라미드의 각 면에 고유의 색상이 지정되어 있는데 결합 모드에 따라 이 색상과 텍스처 색상의 연산이 결정된다. REPLACE로 덮어 쓰면 텍스처의 무늬만 나타나지만 MODULATE나 ADD로 혼합하면 면의 원래색과 논리적으로 섞인다.
팝업 메뉴로 모드를 바꿔 보자. 텍스처 이미지가 다각형을 덮어 버리는 것이 아니라 원래색과 섞이는 효과가 나타난다. 이 모드에서는 똑같은 텍스처라도 다각형의 원래 색에 따라 무늬의 색상이 결정되므로 하나의 텍스처로 노란색, 초록색 대리석을 표현할 수 있다.
다음 함수는 텍스처 파라미터를 지정하는데 이 파라미터에 따라 텍스처를 그리는 랜더링 방식이 달라진다.



 target은 텍스처의 차원을 지정한다.
pname은 파라미터의 이름이고 param은 값이다.
텍스처와 물체의 면적이 정확하게 일치하는 경우가 드물므로 텍스처를 늘리거나 줄여서 입혀야 한다. 텍스처 맵으로부터 입힐 색상을 계산하는 과정을 텍스처 필터링이라고 한다.
GL_TEXTURE_MIN_FILTER는 축소시의 필터링을 지정하고
GL_TEXTURE_MAG_FILTER는 확대시의 필터링을 지정한다.
주로 다음 두 가지 필터가 사용된다.
■ 최단거리(GL_NEAREST) : 비율상 대응되는 위치의 텍셀값을 그대로 사용한다. 알고리즘은 단순하지만 품질은 떨어진다.

■ 선형(GL_LINEAR) : 대응되는 위치 주변의 텍셀값에 대한 평균을 계산한다. 오버헤더가 많지만 품질은 훨씬 더 좋다. 축소시의 디폴트는 GL_NEAREST_MIPMAP_LINEAR이며 확대시의 디폴트는 GL_LINEAR이다.

예제에서는 의도적으로 64 크기의 작은 텍스처를 입혀 놓고 필터링을 토글해 보았다. 차이를 분명히 보고 싶으면 창을 크게 해서 도형을 확대한 상태로 필터링을 바꿔 보면 된다. LINEAR 필터링은 부드럽게 확대되지만 NEAREST 필터링은 품질이 훨씬 더 거칠며 계단 현상도 나타난다. 물론 속도는 반대겠지만 이 정도 도형에서 속도차를 실감하기는 어렵다. 텍스처를 더 큰 것으로 사용하면 확대에 의한 부작용이 감소하므로 품질은 더 좋아진다. GL_TEXTURE_WRAP_S, T, R 파라미터는 각 축에 대한 텍스처 랩핑 방식을 지정하며 다음값중 하나를 지정한다. 랩핑 GL_CLAMP 경계 부근을 반복한다. GL_CLAMP_TO_BORDER 경계 텍셀의 값을 반복한다. GL_CLAMP_TO_EDGE GL_MIRRORED_REPEAT 반사된 모양으로 반복한다. GL_REPEAT 반복한다. 텍스처 범위와 텍셀 범위가 일치하지 않을 경우 반복 및 경계 부근의 처리 방식을 지정한다.
Posted by 코딩하는 야구쟁이
,