필요한 준비물
- 환경맵 텍스쳐를 그려줄 육면체
- 환경맵 텍스쳐
육면체 그리기
먼저, 육면체를 그리기기 위해서는 사각형을 그려줘야 한다. 사각형이란 면으로써 점이 선을 이루어 그리는 것이다. 특히, rasterize
환경에서는 사각형은 삼각형 두 개의 모습으로써 구성된다.
사각형을 그릴 때 중요한 특징은 해당 면의 왼쪽 아래
부터 그린다는 점이다. 이는 D3D가 왼손좌표계인 것도 이지만, 더욱 중요한 것은 NDC가 왼쪽아래부터 시작한다는 점이다. 이러한 영향으로 인해 그림을 그릴 때 왼쪽 아래 좌표부터 그리는 것이 자연스러운 것이 되었다고 이야기 한다.
사각형은 면이 하나이므로 왼쪽 아래 부터 시계방향으로 삼각형을 그리는 것을 가정하면 그리기 간단하다.
글로 쓴다면, 왼쪽 아래 -> 왼쪽 위 -> 오른쪽 위 -> 오른쪽 아래 순으로 그리면 된다.
그렇다면, 육면체는 어떻게 해야하는가?
육면체도 사각형 그리기의 반복이다. 그렇지만, 헷갈리는 부분이 존재한다. 바로 뒷면과 오른쪽 면 부분이다.
뒷면이나 오른 면의 경우, '현재 내가 육면체를 바라보고 있는 방향'에서 그리는 것이 아니다. 그렇게 그리는 것은 뒷면을 말 그대로 뒤에서 보고
그리는 것이기 때문이다. 그러므로 우리는 뒷면을 정면에서 본다고 생각하고 그려야 한다. 오른 면의 경우에도 마찬가지이다.
해당 사진에서 오른 면은 방향이 이상해 보이지만, 삼각형이 정상적으로 그려지므로 정상작동하게 된다. 직관적으로 좌표를 바꾼다면, 오른쪽 면을 정면으로 둔 상태에서 왼쪽 아래 좌표부터 부여하면 된다.
참고로 텍스쳐 좌표의 경우에는 이렇다.
환경맵 텍스쳐
텍스쳐는 SRV를 통해서 PS에 바운딩해준 다음 별도의 후처리 없이 입혀주기만 하면 된다.
내 경우, IBLBaker
를 통해 HDR 이미지를 큐브맵으로 만든 다음 입혔다. 그리고 큐뷰맵의 경우에는 world 좌표라고 할게 없으므로, view*proj으로 좌표를 변환시키면 된다.
// for cubemap texture
vector<ID3D11ShaderResourceView *> commonSRVs = {
m_specularSRV.Get(), m_irradianceSRV.Get(), m_envSRV.Get(),
m_brdfSRV.Get()};
m_context->PSSetShaderResources(10, UINT(commonSRVs.size()),
commonSRVs.data());
소스 코드
vector<Vector3> positions;
vector<Vector3> colors;
vector<Vector3> normals;
vector<Vector2> texcoords;
float scale = 25.0f;
//// 윗면
positions.push_back(Vector3(-1.0f, 1.0f, -1.0f) * scale);
positions.push_back(Vector3(-1.0f, 1.0f, 1.0f) * scale);
positions.push_back(Vector3(1.0f, 1.0f, 1.0f) * scale);
positions.push_back(Vector3(1.0f, 1.0f, -1.0f) * scale);
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(0.0f, 1.0f, 0.0f));
normals.push_back(Vector3(0.0f, 1.0f, 0.0f));
normals.push_back(Vector3(0.0f, 1.0f, 0.0f));
normals.push_back(Vector3(0.0f, 1.0f, 0.0f));
texcoords.push_back(Vector2(0.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 1.0f));
// 아랫면
positions.push_back(Vector3(-1.0f, -1.0f, -1.0f) * scale);
positions.push_back(Vector3(1.0f, -1.0f, -1.0f) * scale);
positions.push_back(Vector3(1.0f, -1.0f, 1.0f) * scale);
positions.push_back(Vector3(-1.0f, -1.0f, 1.0f) * scale);
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(0.0f, -1.0f, 0.0f));
normals.push_back(Vector3(0.0f, -1.0f, 0.0f));
normals.push_back(Vector3(0.0f, -1.0f, 0.0f));
normals.push_back(Vector3(0.0f, -1.0f, 0.0f));
texcoords.push_back(Vector2(0.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 1.0f));
// 앞면
positions.push_back(Vector3(-1.0f, -1.0f, -1.0f) * scale);
positions.push_back(Vector3(-1.0f, 1.0f, -1.0f) * scale);
positions.push_back(Vector3(1.0f, 1.0f, -1.0f) * scale);
positions.push_back(Vector3(1.0f, -1.0f, -1.0f) * scale);
colors.push_back(Vector3(0.0f, 0.0f, 1.0f));
colors.push_back(Vector3(0.0f, 0.0f, 1.0f));
colors.push_back(Vector3(0.0f, 0.0f, 1.0f));
colors.push_back(Vector3(0.0f, 0.0f, 1.0f));
normals.push_back(Vector3(0.0f, 0.0f, -1.0f));
normals.push_back(Vector3(0.0f, 0.0f, -1.0f));
normals.push_back(Vector3(0.0f, 0.0f, -1.0f));
normals.push_back(Vector3(0.0f, 0.0f, -1.0f));
texcoords.push_back(Vector2(0.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 1.0f));
// 뒷면
positions.push_back(Vector3(-1.0f, -1.0f, 1.0f) * scale);
positions.push_back(Vector3(1.0f, -1.0f, 1.0f) * scale);
positions.push_back(Vector3(1.0f, 1.0f, 1.0f) * scale);
positions.push_back(Vector3(-1.0f, 1.0f, 1.0f) * scale);
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
colors.push_back(Vector3(1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(0.0f, 0.0f, 1.0f));
normals.push_back(Vector3(0.0f, 0.0f, 1.0f));
normals.push_back(Vector3(0.0f, 0.0f, 1.0f));
normals.push_back(Vector3(0.0f, 0.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 1.0f));
// 왼면
positions.push_back(Vector3(-1.0f, -1.0f, 1.0f) * scale);
positions.push_back(Vector3(-1.0f, 1.0f, 1.0f) * scale);
positions.push_back(Vector3(-1.0f, 1.0f, -1.0f) * scale);
positions.push_back(Vector3(-1.0f, -1.0f, -1.0f) * scale);
colors.push_back(Vector3(1.0f, 1.0f, 0.0f));
colors.push_back(Vector3(1.0f, 1.0f, 0.0f));
colors.push_back(Vector3(1.0f, 1.0f, 0.0f));
colors.push_back(Vector3(1.0f, 1.0f, 0.0f));
normals.push_back(Vector3(-1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(-1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(-1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(-1.0f, 0.0f, 0.0f));
texcoords.push_back(Vector2(0.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 1.0f));
// 오른면
positions.push_back(Vector3(1.0f, -1.0f, -1.0f) * scale);
positions.push_back(Vector3(1.0f, 1.0f, -1.0f) * scale);
positions.push_back(Vector3(1.0f, 1.0f, 1.0f) * scale);
positions.push_back(Vector3(1.0f, -1.0f, 1.0f) * scale);
//positions.push_back(Vector3(1.0f, -1.0f, 1.0f) * scale);
//positions.push_back(Vector3(1.0f, -1.0f, -1.0f) * scale);
//positions.push_back(Vector3(1.0f, 1.0f, -1.0f) * scale);
//positions.push_back(Vector3(1.0f, 1.0f, 1.0f) * scale);
colors.push_back(Vector3(1.0f, 0.0f, 1.0f));
colors.push_back(Vector3(1.0f, 0.0f, 1.0f));
colors.push_back(Vector3(1.0f, 0.0f, 1.0f));
colors.push_back(Vector3(1.0f, 0.0f, 1.0f));
normals.push_back(Vector3(1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(1.0f, 0.0f, 0.0f));
normals.push_back(Vector3(1.0f, 0.0f, 0.0f));
texcoords.push_back(Vector2(0.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 0.0f));
texcoords.push_back(Vector2(1.0f, 1.0f));
texcoords.push_back(Vector2(0.0f, 1.0f));
for (UINT i = 0; i < positions.size(); i++) {
Vertex v;
v.position = positions[i];
v.normalModel = normals[i];
v.texcoord = texcoords[i];
skyBoxMesh.vertices.push_back(v);
}
skyBoxMesh.indices = {
0, 1, 2, 0, 2,
3, // 윗면
4, 5, 6, 4, 6,
7, // 아랫면
8, 9, 10, 8, 10,
11, // 앞면
12, 13, 14, 12, 14,
15, // 뒷면
16, 17, 18, 16, 18,
19, // 왼쪽면
20, 21, 22, 20, 22,
23 // 오른면
};
'Graphics' 카테고리의 다른 글
3. Directional Shadow Mapping (0) | 2024.06.21 |
---|---|
2. Depth Buffer와 안개 효과 (1) | 2024.06.14 |
1. Blinn Phong 모델 (0) | 2024.05.14 |
Texture 사용하기 (0) | 2024.05.14 |
물체 이동과 회전 using 마우스, GUI (0) | 2024.05.14 |