Material은 엔진에서 볼 수 있는데 물체의 재질을 표현하는데 사용한다.
DirectX에서는 Parameter 값으로 Material을 표현한다.
cbuffer MATERIAL_PARAMS : register(b1)
{
int int_0;
int int_1;
int int_2;
int int_3;
int int_4;
float float_0;
float float_1;
float float_2;
float float_3;
float float_4;
};
Texture2D tex_0 : register(t0);
Texture2D tex_1 : register(t1);
Texture2D tex_2 : register(t2);
Texture2D tex_3 : register(t3);
Texture2D tex_4 : register(t4);
struct MaterialParams
{
void SetInt(uint8 index, int32 value) { intParams[index] = value; }
void SetFloat(uint8 index, float value) { floatParams[index] = value; }
array<int32, MATERIAL_INT_COUNT> intParams;
array<float, MATERIAL_FLOAT_COUNT> floatParams;
};
첫번째 코드는 Shader 코드인데 저렇게 Shader가 갖는 Parameter 값들을 MaterialParams로 만들어 관리한다.
class Material
{
public:
shared_ptr<Shader> GetShader() { return _shader; }
void SetShader(shared_ptr<Shader> shader) { _shader = shader; }
void SetInt(uint8 index, int32 value) { _params.SetInt(index, value); }
void SetFloat(uint8 index, float value) { _params.SetFloat(index, value); }
void SetTexture(uint8 index, shared_ptr<Texture> texture) { _textures[index] = texture; }
void Update();
private:
shared_ptr<Shader> _shader;
MaterialParams _params;
array<shared_ptr<Texture>, MATERIAL_TEXTURE_COUNT> _textures;
};
Material 클래스 코드인데 shader, params(매개변수들), textures를 가지고 있다.
void Material::Update()
{
// CBV 업로드
CONST_BUFFER(CONSTANT_BUFFER_TYPE::MATERIAL)->PushData(&_params, sizeof(_params));
// SRV 업로드
for (size_t i = 0; i < _textures.size(); i++)
{
if (_textures[i] == nullptr)
continue;
SRV_REGISTER reg = SRV_REGISTER(static_cast<int8>(SRV_REGISTER::t0) + i);
GEngine->GetTableDescHeap()->SetSRV(_textures[i]->GetCpuHandle(), reg);
}
// 파이프라인 세팅
_shader->Update();
}
그리고 Update할 때 CBV, SRV를 업로드하고 파이프라인을 세팅한다.
CreateConstantBuffer(CBV_REGISTER::b0, sizeof(Transform), 256);
CreateConstantBuffer(CBV_REGISTER::b1, sizeof(MaterialParams), 256);
Engine::Init에서는 b0레지스터에 Transform정보를 저장하고 b1레지스터에 MaterialParams 정보를 저장한다.
CONST_BUFFER(CONSTANT_BUFFER_TYPE::TRANSFORM)->PushData(&_transform, sizeof(_transform));
그리고 PushData를 할 때 지정된 타입의 Constant Buffer을 대상으로 한다. 위는 Transform CBV에 PushData하고 있다.
shared_ptr<Material> material = make_shared<Material>();
material->SetShader(shader);
material->SetFloat(0, 0.3f);
material->SetFloat(1, 0.4f);
material->SetFloat(2, 0.3f);
material->SetTexture(0, texture);
mesh->SetMaterial(material);
그래서 최종적으로 Material은 shader, texture, 그리고 parameter들을 가지고 있고 그것을 mesh에 적용시킨다.
'그래픽스' 카테고리의 다른 글
| [DX12] Camera (0) | 2022.07.24 |
|---|---|
| [DX12] Comoponent (0) | 2022.07.24 |
| [DX12] Depth Stencil View (0) | 2022.07.23 |
| [DX12] Texture Mapping (0) | 2022.07.23 |
| [DX12] Index Buffer (0) | 2022.07.22 |