여태까지 개발한 엔진에서 메시에 할당되는 머터리얼의 정보는 메시 자체에 저장되도록 설계되어있었다. 조금 더 자세히 말하자면 전체 메시에서 서브메시들에 대해 각각 머터리얼 인덱스를 할당해주는 방식이었다. 애초에 셰이더 코드와 관련된 부분이나 텍스쳐 정보도 전부 머터리얼이 들고있으니 문제가 없을 것이라고 생각했다. 무엇보다 서브메시 각각이 Draw Call을 하는 것이 오버헤드를 발생시킨다고 생각했기 때문에 나중에 최적화 작업을 하게 된다면 서브메시를 하나의 버퍼에 묶어서 한 번의 Draw Call로 모든 메시를 렌더링 한다는 원대한 계획도 갖고 있었다.
문제가 발생한건 Skybox를 구현하려고 하면서 부터였다. 일단 엔진에서 기본적으로 생성해둔 구 메시 데이터를 불러와서 Skybox 텍스쳐를 입혀주면 되는 아주 간단한 작업이라고 생각하고 들어갔는데, 머터리얼을 Skybox로 사용할 메시에만 적용하려니 메시 자체에 들어가있는 머터리얼의 값을 바꿔버리니 같은 메시를 사용하는 오브젝트 전부가 바뀌게 된 것이다. 메시를 렌더링할 때는 전체 메시에 하나씩 붙어있는 MeshRenderer를 거치게 되는데 얘를 이용해볼까 하면 서브메시가 여러 개 있는 경우가 있기 때문에 바람직해보이지는 않는다.
이 문제를 해결하려고 두 가지 방법을 생각했다.
- 아예 리소스를 로드하거나 생성할 때부터 프리팹처럼 로드해서 각 메시별로 게임 오브젝트를 생성 및 MeshRenderer 할당
- 각각의 메시가 고유한 머터리얼 정보를 갖되, 임의로 머터리얼 정보를 바꾸면 바뀐 머터리얼로 렌더링
사실 처음에는 1번이 매력적인 해결책으로 보였다. 유니티의 동작방식을 보면 실제로 리소스를 불러왔을 때 프리팹 형식으로 로드가 되며, 메시별로 게임 오브젝트가 생성된다. 이렇게 하면 서브메시들을 오브젝트 단위로 활성화/비활성화가 가능해지기 때문에 후에 게임을 개발하는 과정에서 편해질 것이라고 생각했기 때문이다.
근데 지금 상황에서 굳이 2번 방법을 선택하지 않을 이유가 없어보였다. 로드할 때부터 메시별로 오브젝트를 생성하고 그걸 또 프리팹으로 저장하는 방식을 선택한다는건 리소스 로드 모듈부터 전부 리팩토링 및 구현 작업이 필요하다는 것이다. 지금같이 빨리빨리 기능개발에 착수해야되는 상황에서는 좋아보이지 않다. 2번 방법의 경우 처음에는 써진 그대로 뭉뚱그레 대충 생각했지만 구체화를 하면 할수록 2번 방법이 더 매력적으로 느껴졌다.
일단 서브메시가 고유한 머터리얼 정보를 갖는다. 그렇게 모인 전체 메시를 사용하는 오브젝트가 MeshRenderer를 사용하게 되면 MeshRenderer에서 메시로부터 각각의 서브메시에 대한 머터리얼 할당 데이터를 뽑아내서 배열로 갖고있는다. 이러면 렌더링에 사용되는 머터리얼 정보는 메시에 저장되있는 날것의 데이터가 아니라 렌더링을 위해 복사된 데이터기 때문에 이 배열의 값을 변경하는 것으로 해당 오브젝트에 한해서 머터리얼 및 텍스처 변경이 가능해진다.
다만 내가 머터리얼을 바꾸길 원하는 서브메시를 어떻게 콕 집어서 찾아내느냐가 문제가 되겠다. 이건 사실 GUI가 전혀 없는 환경이기 때문에 더 그런 것 같다. 일단은 그냥 0번 인덱스에 할당하는 메소드와 인덱스를 받아서 그 인덱스의 머터리얼을 바꾸는 메소드 두 개를 모두 구현해두자. 해당 메시의 인덱스를 구하는 방법은 피킹을 구현하던 각 메시를 보여주는 GUI를 구현하던 나중에 해결하는거로 하자..
void SetMaterial(shared_ptr<Material> mat) { _submeshMaterials[0] = mat; }
void SetMaterial(shared_ptr<Material> mat, int index) { _submeshMaterials[index] = mat; }'공부 > DirectX12' 카테고리의 다른 글
| std::max()에 3개 이상의 인자를 사용하는 방법이 안될 때 (0) | 2025.05.25 |
|---|---|
| DirectX12 ImGUI 라이브러리 세팅 (0) | 2025.04.15 |
| 툰 셰이딩에서 얼굴 명암 처리에 대해서 (0) | 2025.04.04 |
| 앞으로의 개발 목표 정리 (0) | 2025.03.29 |
| DirectX 인덱스 버퍼 버그 해결 (0) | 2025.03.23 |