텍스쳐의 필요성과 목적, 기본적인 활용 방법에 대해 공부한다.
0. 목적
1. Texture?
2. Mesh에 적용 과정
3. Quad에 UV좌표 적용
0. 목적
texture 활용에 필요한 기본적인 내용들을 공부할 것이다.
++그러면 왜 texture를 배워야 할까?
vertex만으로도 게임 만드는 것이 가능하지만, mesh 연산 증가 및 이미지 교체 과정 비효율적이다.
= 대상 표면 자세한 모습 렌더링할때는 vertex 색상이 아닌 Texture(이미지 파일, fragment 단위로 달라짐.) 사용.
1. Texture?
컴퓨터 그래픽에서 사용되는 이미지로, fragment 단위로 달라지는 정보를 제공하는 이미지 파일이다.
2. Mesh에 적용 과정
Texture Mapping -> Texture Sampling
- Texture Mapping : Texture(2D)를 3D Mesh에 입히는 과정. 보간된 값에서 추출된 Texture Coordinates를 Texture 상의 특정 위치로 Mapping하는 것.
(Mesh Vertex를 구성하는 Texture Coordinates / UV Coordinates 필요.)
(해당 Coordinates : vertex 단위로 지정된 다음 Mesh Face 위에서 보간 실행.
- Texture Sampling : Texture Mapping 과정 후 Fragment shader이 해당 좌표를 사용해 Texture에서 특정 좌표의 색상 값을 찾는 과정.
3. Quad에 UV좌표 적용
3.1. Quad?
= 그래픽스에서의 사각형, 정사각형
= 연산을 최소화하고, 간략하게 표현하기 위해 삼각형들을 합쳐서 만듦. (기존에 존재하던 vertex에 점 1개만 추가)
3.2. UV 좌표
= fragment shader이 텍스쳐에서 색상을 찾는 데 사용하는 2D 좌표.
(XY좌표라고 생각하면 됨)
= 좌측 하단이 (0.0, 0.0), 우측 상단이 (1.0, 1.0)
3.3. Quad 생성
= 기존에 만들었던 triangle에 vertex 추가.
<openframeworks에서 구현 방법>
= 인덱스 버퍼 사용.
= 기존 mesh에 vertex 추가.
(인덱스 버퍼 : 특정 mesh의 버텍스 순서를 정의하는 정수의 배열)
void ofApp::setup(){
quad.addVertex(glm::vec3(-1.0, -1.0f, 0.0f));
quad.addVertex(glm::vec3(-1.0f, 1.0f, 0.0f));
quad.addVertex(glm::vec3(1.0f, 1.0f, 0.0f));
quad.addVertex(glm::vec3(1.0f, -1.0f, 0.0f));
/*
addColor는 인덱스 버퍼가 vertex를 참조할 때 모든 vertex 속성을 참조한다는 것을 보여준다는 것을 위해 사용한 코드이다.
(인덱스 버퍼의 첫 요소=2번 줄과 12번 줄의 위치, 색상 속성을 같이 참조.
-> 위치는 같아도 다른 색상 속성이 필요하면 새 vertex를 만들어야 하므로 비효율적.)
vertex 색상을 사용하는 것이므로 fragment shader로 색상을 가져오기 위해 이후 수정된다.
*/
quad.addColor(ofDefaultColorType(1, 0, 0, 1));
quad.addColor(ofDefaultColorType(0, 1, 0, 1));
quad.addColor(ofDefaultColorType(0, 0, 1, 1));
quad.addColor(ofDefaultColorType(1,1,1,1));
/*
기존 vertex를 재사용하기 때문에 동일한 좌표 추가.
*/
ofIndexType indices[6] = {0,1,2,2,3,0};
/*
ofMesh의 인덱스를 정렬.
*/
quad.addIndices(indices, 6);
}
3.4. 쉐이더 텍스쳐에 적용하기(1) - 모든 프래그먼트에 UV 좌표 부여.
= 모든 프래그먼트에 좌표를 부여한 후 좌표를 색상으로 출력한다.
UV좌표를 추가하기 위해 addColor()를 수정한다. (화면 상단으로 갈수록 텍스쳐 좌표의 V값이 커진다.)
quad.addTexCoord(glm::vec2(0,0));
quad.addTexCoord(glm::vec2(0,1));
quad.addTexCoord(glm::vec2(1,1));
quad.addTexCoord(glm::vec2(1,0));
3.5. 쉐이더 텍스쳐에 적용하기(2) - vertex, fragment shader 작성
(1) vertex shader : UV좌표 전달. (uv_passthrough.vert 파일)
(2) fragment shader : UV좌표 시각화를 위해 색상으로 출력. (uv_vis.frag 파일)
3.5.1. vertex shader
= layout을 이용해 버텍스 설정을 location에 연결한다.
= fragment shader이 필요로 하는 데이터를 보간할 수 있도록, 파이프라인에 적절한 형태의 데이터를 제공하는 게 목표.
#version 410
layout (location = 0) in vec3 pos;
layout (location = 3) in vec2 uv;
out vec2 fragUV;
void main()
{
gl_Position = vec4(pos, 1.0);
fragUV = uv;
}
++ openframeworks가 location에 vertex 속성을 저장하는 기본 규칙(엔진에 따라 규칙이 조금씩 다를 수 있음)
= 0 : 위치
= 1 : 색상
= 2. 노말(normal)
= 3. UV 좌표
location 순서를 바꾸거나 다른 vertex 정보를 저장하려면 수동으로 처리해야 함.
3.5.2. fragment shader
= UV 좌표를 fragment 생상의 RGB로 출력.
= 꼭짓점 사이에서 블렌딩되어 출력.
( 게임 개발 과정에서 텍스쳐에 문제가 발생하면 이렇게 디버깅하는 경우 존재.)
#version 410
in vec2 fragUV;
out vec4 outCol;
void main()
{
outCol = vec4(fragUV, 0.0f, 1.0f);
}
= 색상, 텍스쳐 등 모두 벡터(실수의 집합)으로 취급하므로 vertex shader과 유사하게 작성한다.

<해당 코드 출력 결과>