pbr 적용했다.
subpass간 attachment 늘리고 uniform buffer 추가만 하면 될 줄 알았는데 고생을 많이 했다.
직전 쓴 블로그의 흐름대로 적용했지만
초기 설계와는 조금 다르게 된 부분에 대해 다루겠다.
1. attachment 개수 변경
직전에는 geo pass가 light pass로 넘겨주는 attachment가 7개
(position, normal, albedo, roughness, metallic, height, ao) 라고 했는데
4개로 바뀜 (position, normal, albedo, pbr)
pbr attachment로 roughness, metallic, ao를 통합했다. 각 1채널 밖에 없기 때문이다.
height map은 geo pass의 vertex shader에서 미리 계산 후 들어간다.
물론 height map이 없는경우 height default값을 써서 그냥 들어간다.
2. vertex 구조체 변경
이게 내가 놓친 부분이다.
normal map을 사용하려면 TBN행렬을 써야한다.
TBN 행렬에서 tangent를 사용하게 되는데 이 정보는 vertex에 저장되어 있어야 한다.
그래서 vertex 구조체에 tanget를 추가한 후
mesh 클래스에서 vertices와 indices를 버퍼에 집어 넣기 전에 tangent계산을 해주고 tangent를 집어 넣어준다.
이 과정을 생략하고 진행해서
터지고 난 뒤 안해줄 걸 알았다.
엄청 많은 걸 바꿔야하는줄 알고 한숨부터 나왔는데
생각보다 별거 아니였다.
결과
m_material = Material::createMaterial(
{glm::vec3(1.0f, 1.0f, 0.0f), nullptr, false},
{nullptr, false},
{0.5f, nullptr, false},
{1.0f, nullptr, false},
{1.0f, nullptr, false},
{0.0f, nullptr, false}
);
m_backpackMaterial = Material::createMaterial(
{glm::vec3(1.0f, 1.0f, 1.0f), m_backpackAlbedo, true},
{m_backpackNormal, true},
{0.5f, m_backpackRoughness, true},
{0.8f, m_backpackMetallic, true},
{1.0f, m_backpackAo, true},
{0.0f, nullptr, false}
);
이런식으로 material을 초기화 한 후
m_objects.push_back(Object::createObject("sphere", m_sphereModel, m_material,
Transform{glm::vec3(0.3f, 1.3f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)}));
m_objects.push_back(Object::createObject("backpack", m_backpackModel, m_backpackMaterial,
Transform{glm::vec3(-1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.3f, 0.3f, 0.3f)}));
이런식으로 object를 만든다.
그러면
pbr 적용 완료!
우선 느낀점 혹은 개선점은
생각보다 object 파일, 특히나 pbr이 있는 object 파일을 찾기가 쉽지가 않다.
확인하려고 이것 저것 뒤져보다 그냥 opengl에서 공부하면서 쓴 오브젝트 가져다가 썼다.
Object 파일 찾으면서 좋은 사이트 하나 찾았는데
https://polyhaven.com/
Poly Haven • Poly Haven
The Public 3D Asset Library
polyhaven.com
여기는 object는 다루지 않고 blender 파일과, gltf 파일을 사용하는데
gltf 뭔지 몰라서 찾아봤더니
요즘 대부분 gltf를 쓴다더라
assimp에서도 지원이 된다해서 받아봤는데
뭔가 이상하게 잘 안된다. 계속 로드하는 부분에서 터져서
이거 고쳐봐야하고
그렇다면 우리 엔진도 시대에 맞춰 gltf를 사용 가능하게 만들어야하는데
라이브러리 쓰면 딸깍이겠지만
과제 요구사항에 모든 라이브러리는 사용 금지되어있기때문에
언젠가는 gltf까지 파싱을 해야할 거 같다..
아마 내가하게 될 거 같다 ㅠㅠ
+
지금 구조가 object file안의 material을 참조하는게 아니라
내가 직접구현한 material을 참조하기 때문에
object 제작자의 의도를 맞추려면 texture를 각각 받아 material을 만들어줘야한다.
여기까지는 오케이. 나도 의도 했다.
근데 object만든 사람이 sub mesh를 만들어 texture를 두개 이상 받아오는 순간 골이 아파지는데
이러면 내가 만든 구조인 1 object - 1 material - 1 descriptorset 구조가 깨지게 된다.
지금 descriptorset을 renderer에서 통합 관리하고 있는데
저거에 맞춰 하려면 object가 혹은 그 안의 mesh가 각각의 descriptorset을 가지고 있는게
더 효율적이거나, 더 최악은 그렇게 해야만 돌아갈 수도 있다.
당장 지금 생각나는 베스트 시나리오는
object를 만들면 자동으로 uniform buffer와 descriptorset이 완성되어
uniform update를 object에서 진행하는 것이다.
대신 sub mesh있는 경우를 따져봐야하는데..
하.. 좀 더 생각하고 블로그에 써야겠다..
앞으로 할 게 늘었다.
1. obj file 공부 - 초창기 과제에서 하긴 했으나 material 쪽 어떻게 받아와야하나 집중적으로 생각해봐야겠다.
2. gltf 어떻게 받아야 하는지도 공부해야한다.
3. object하나에 여러 material이 올 수도 있는 구조 생각 -> submesh를 어떻게 판별하여 material을 나눠 줄 지 생각해봐야한다.
4. 다시 생각해봐도 object 만들 때부터 descriptorset 만들어 주는게 좋을 거 같다. -> 여기에 대한 구조 설계
'Computer Graphics > Vulkan' 카테고리의 다른 글
Vulkan - 12. 다중 광원 적용, 광원 타입 적용 (0) | 2025.01.15 |
---|---|
Vulkan - 11. gltf 형식의 모델 로드, normal map 수정 (0) | 2025.01.14 |
Vulkan - 9. pbr 적용 전략 (0) | 2025.01.03 |
Vulkan - 8. 키보드 마우스 입력 추가와 imgui 적용 (1) | 2025.01.02 |
Vulkan - 7. deferred shading + phong shading 삽질 기록들 (0) | 2024.12.30 |