이번에는 오브젝트의 정점 좌표를 UV 좌표계로 변환하여 텍스처를 적용해보았다. 이를 위해 다음과 같은 코드를 추가하여 렌더링을 진행했다.
for (int i = 0; i < vertices.size(); i = i + 3) {
for (int j = 0; j < 3; j++) {
glmath::vec3 pos = vertices[i + j].pos;
float r = std::sqrt(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z);
if (r == 0) r = 0.01f;
float theta = std::atan2(pos.z, pos.x);
float phi = std::asin(pos.y / r);
float U = (phi + glmath::pi / 2) / glmath::pi * colPattern;
float V = (theta + glmath::pi) / (2 * glmath::pi) * rowPattern;
vertices[i + j].texCoord.x = V;
vertices[i + j].texCoord.y = U;
}
}
하지만, 렌더링 결과를 확인해보니 특정 부분에서 텍스처가 불규칙적으로 반복되는 현상이 발생했다.
문제는 삼각형의 정점 중 일부가 UV 좌표계의 경계를 넘어가는 위치에 있을 때 발생했다. 예를 들어, 삼각형의 정점 3개 중 하나의 θ(theta)가 1.9π, 다른 하나는 -0.1π인 경우, 실제 값 차이는 0.2π에 불과하지만, UV 좌표계는 0 ~ 2π로 제한되어 있으므로 두 좌표 간의 차이를 큰 값으로 인식하게 된다. 그 결과 텍스처가 경계에서 왜곡되며 잘못된 패턴으로 렌더링되었다.
이 문제를 해결하기 위해, UV 좌표가 경계를 넘어가는지 확인하는 함수를 추가했다. 만약 경계를 넘어간다면, 그 좌표에 2π를 더해줌으로써 자연스러운 텍스처 적용이 가능하게 수정했다.
아래는 수정된 코드이다.
bool Model::isAcrossUVBoundary(std::vector<Vertex>& vertices, int idx) {
bool startAria = false;
bool endAria = false;
for (int i = 0; i < 3; i++) {
if (vertices[idx + i].pos.x <= 0 && vertices[idx + i].pos.z >= 0) {
startAria = true;
}
if (vertices[idx + i].pos.x <= 0 && vertices[idx + i].pos.z < 0) {
endAria = true;
}
}
return (startAria && endAria);
}
void Model::makeTextureCoord(std::vector<Vertex>& vertices) {
float rowPattern = 8;
float colPattern = 8;
for (int i = 0; i < vertices.size(); i = i + 3) {
for (int j = 0; j < 3; j++) {
glmath::vec3 pos = vertices[i + j].pos - m_modelPos;
float r = std::sqrt(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z);
if (r == 0) r = 0.01f;
float theta = std::atan2(pos.z, pos.x);
float phi = std::asin(pos.y / r);
float U = (phi + glmath::pi / 2) / glmath::pi * colPattern;
float V = (theta + glmath::pi) / (2 * glmath::pi) * rowPattern;
vertices[i + j].texCoord.x = V;
vertices[i + j].texCoord.y = U;
}
if (isAcrossUVBoundary(vertices, i)) {
for (int j = 0; j < 3; j++) {
if (vertices[i + j].texCoord.x < rowPattern / 2) {
vertices[i + j].texCoord.x += rowPattern;
}
}
}
}
}
추가적으로, rowPattern과 colPattern 변수를 사용하여 텍스처가 단일 패턴으로만 적용되지 않고, 여러 번 반복되어 적용되도록 설정했다. 이는 텍스처가 더욱 자연스럽게 오브젝트에 입혀지도록 하기 위함이다.
이렇게 수정된 코드로 렌더링한 결과, 이전보다 훨씬 자연스럽게 텍스처가 적용되는 것을 확인할 수 있었다
이렇게 수정된 코드로 렌더링한 결과, 이전보다 훨씬 자연스럽게 텍스처가 적용되는 것을 확인할 수 있었다.
이번 작업을 통해 텍스처가 UV 좌표계의 경계 문제로 인해 왜곡되는 문제를 해결하면서 텍스처 매핑에 대한 이해도를 높일 수 있었다.
SCOP: 프로젝트를 하며 느낀 점 - (9) (1) | 2024.10.01 |
---|---|
SCOP: 3D 오브젝트 이동, 회전, 색상 및 텍스처 적용 - (7) (0) | 2024.09.27 |
SCOP : 기능별 클래스로 리팩토링하기 - (6) (0) | 2024.09.23 |
SCOP : BMP 이미지 파싱과 텍스처 매핑 구현 - (5) (0) | 2024.09.23 |
SCOP : GLM을 대체하는 GLMath 라이브러리 구현 - (4) (0) | 2024.09.20 |