For me
[DirectX12] 8) Material 본문
수많은 물체를 Resources(mesh, shader, texture)를 매 물체마다 만들고, 로딩하고, 연결하는 과정은 좋지않음.
=> Material이라는 개념을 사용하여 관리
Engine 에서 다음과 같이 선언
▶ CreateConstantBuffer(CBV_REGISTER::b2, sizeof(MaterialParams), 256);
CommandQueue에서 RenderBegin에서 다음과 같이 선언
▶GEngine->GetConstantBuffer(CONSTANT_BUFFER_TYPE::MATERIAL)->Clear();
Material에서는 ConstantBuffer, ShaderResourceBuffer 를 업로드하여 파이트라인 세팅까지 하나로 관리함.
Material.h
더보기
#pragma once
#include "Object.h"
class Shader;
class Texture;
enum
{
MATERIAL_ARG_COUNT = 4,
};
struct MaterialParams
{
MaterialParams()
{
for (int32 i = 0; i < MATERIAL_ARG_COUNT; i++)
{
SetInt(i, 0);
SetFloat(i, 0.f);
SetTexOn(i, 0);
}
}
void SetInt(uint8 index, int32 value) { intParams[index] = value; }
void SetFloat(uint8 index, float value) { floatParams[index] = value; }
void SetTexOn(uint8 index, int32 value) { texOnParams[index] = value; }
void SetVec2(uint8 index, Vec2 value) { vec2Params[index] = value; }
void SetVec4(uint8 index, Vec4 value) { vec4Params[index] = value; }
void SetMatrix(uint8 index, Matrix& value) { matrixParams[index] = value; }
array<int32, MATERIAL_ARG_COUNT> intParams;
array<float, MATERIAL_ARG_COUNT> floatParams;
array<int32, MATERIAL_ARG_COUNT> texOnParams;
array<Vec2, MATERIAL_ARG_COUNT> vec2Params;
array<Vec4, MATERIAL_ARG_COUNT> vec4Params;
array<Matrix, MATERIAL_ARG_COUNT> matrixParams;
};
class Material : public Object
{
public:
Material();
virtual ~Material();
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;
_params.SetTexOn(index, (texture == nullptr ? 0 : 1));
}
void SetVec2(uint8 index, Vec2 value) { _params.SetVec2(index, value); }
void SetVec4(uint8 index, Vec4 value) { _params.SetVec4(index, value); }
void SetMatrix(uint8 index, Matrix& value) { _params.SetMatrix(index, value); }
void PushGraphicsData();
void PushComputeData();
void Dispatch(uint32 x, uint32 y, uint32 z);
shared_ptr<Material> Clone();
private:
shared_ptr<Shader> _shader;
MaterialParams _params;
array<shared_ptr<Texture>, MATERIAL_ARG_COUNT> _textures;
};
Material.cpp
더보기
#include "pch.h"
#include "Material.h"
#include "Engine.h"
Material::Material() : Object(OBJECT_TYPE::MATERIAL)
{
}
Material::~Material()
{
}
void Material::PushGraphicsData()
{
// CBV 업로드
CONST_BUFFER(CONSTANT_BUFFER_TYPE::MATERIAL)->PushGraphicsData(&_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->GetGraphicsDescHeap()->SetSRV(_textures[i]->GetSRVHandle(), reg);
}
// 파이프라인 세팅
_shader->Update();
}
void Material::PushComputeData()
{
// CBV 업로드
CONST_BUFFER(CONSTANT_BUFFER_TYPE::MATERIAL)->PushComputeData(&_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->GetComputeDescHeap()->SetSRV(_textures[i]->GetSRVHandle(), reg);
}
// 파이프라인 세팅
_shader->Update();
}
void Material::Dispatch(uint32 x, uint32 y, uint32 z)
{
// CBV + SRV + SetPipelineState
PushComputeData();
// SetDescriptorHeaps + SetComputeRootDescriptorTable
GEngine->GetComputeDescHeap()->CommitTable();
COMPUTE_CMD_LIST->Dispatch(x, y, z);
GEngine->GetComputeCmdQueue()->FlushComputeCommandQueue();
}
shared_ptr<Material> Material::Clone()
{
shared_ptr<Material> material = make_shared<Material>();
material->SetShader(_shader);
material->_params = _params;
material->_textures = _textures;
return material;
}
'DirectX12' 카테고리의 다른 글
[DirectX12] 10) Camera (0) | 2023.01.17 |
---|---|
[DirectX12] 9) Scene (0) | 2023.01.16 |
[DirectX12] 7) Component (0) | 2023.01.16 |
[DirectX12] 6) Timer (0) | 2023.01.15 |
[DirectX12] 5) Input (0) | 2023.01.15 |