resume Assign instead of local2world and materialinstanceId in VertexInputStream
This commit is contained in:
parent
08a348392d
commit
a5e76988c7
2
CMCore
2
CMCore
@ -1 +1 @@
|
||||
Subproject commit 3d27b60c13162ac2167cc84e9846088a18664312
|
||||
Subproject commit d70d31288f601061a69f93b4970af6692e53a34b
|
@ -1 +1 @@
|
||||
Subproject commit f220bd8370781f791b3c3a27bd7daa4dc96817e6
|
||||
Subproject commit a6a368031209ce23dc14e88acf45dd8298a19886
|
@ -64,7 +64,7 @@ private:
|
||||
|
||||
bool InitVertexLumMP()
|
||||
{
|
||||
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance3D",Prim::Lines);
|
||||
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance3D",false,Prim::Lines);
|
||||
|
||||
cfg.local_to_world=true;
|
||||
|
||||
@ -92,7 +92,7 @@ private:
|
||||
|
||||
bool InitBlinnPhongSunLightMP()
|
||||
{
|
||||
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"BlinnPhong3D",Prim::Triangles);
|
||||
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"BlinnPhong3D",true,Prim::Triangles);
|
||||
|
||||
cfg.local_to_world=true;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
class RenderL2WBuffer;
|
||||
class RenderMIBuffer;
|
||||
class RenderAssignBuffer;
|
||||
|
||||
/**
|
||||
* 同一材质的对象渲染列表
|
||||
@ -20,8 +20,7 @@ class MaterialRenderList
|
||||
|
||||
private:
|
||||
|
||||
RenderL2WBuffer *l2w_buffer;
|
||||
RenderMIBuffer *mi_buffer;
|
||||
RenderAssignBuffer *assign_buffer;
|
||||
|
||||
struct RenderItem
|
||||
{
|
||||
@ -37,13 +36,9 @@ private:
|
||||
void Set(Renderable *);
|
||||
};
|
||||
|
||||
MaterialInstanceSets mi_set;
|
||||
DataArray<RenderItem> ri_array;
|
||||
uint ri_count;
|
||||
|
||||
VkDeviceSize l2w_buffer_size[4];
|
||||
|
||||
void StatMI();
|
||||
void Stat();
|
||||
|
||||
protected:
|
||||
|
@ -16,7 +16,7 @@ struct Material2DCreateConfig:public MaterialCreateConfig
|
||||
|
||||
public:
|
||||
|
||||
Material2DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const Prim &p):MaterialCreateConfig(da,name,p)
|
||||
Material2DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const bool &mi,const Prim &p):MaterialCreateConfig(da,name,mi,p)
|
||||
{
|
||||
rt_output.color=1; //输出一个颜色
|
||||
rt_output.depth=false; //不输出深度
|
||||
|
@ -17,7 +17,7 @@ struct Material3DCreateConfig:public MaterialCreateConfig
|
||||
|
||||
public:
|
||||
|
||||
Material3DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const Prim &p):MaterialCreateConfig(da,name,p)
|
||||
Material3DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const bool &mi,const Prim &p):MaterialCreateConfig(da,name,mi,p)
|
||||
{
|
||||
rt_output.color=1; //输出一个颜色
|
||||
rt_output.depth=true; //不输出深度
|
||||
|
@ -19,6 +19,8 @@ struct MaterialCreateConfig
|
||||
|
||||
AnsiString mtl_name; ///<材质名称
|
||||
|
||||
bool material_instance; ///<是否包含材质实例
|
||||
|
||||
RenderTargetOutputConfig rt_output; ///<渲染目标输出配置
|
||||
|
||||
uint32 shader_stage_flag_bit; ///<需要的shader
|
||||
@ -27,12 +29,14 @@ struct MaterialCreateConfig
|
||||
|
||||
public:
|
||||
|
||||
MaterialCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const Prim &p)
|
||||
MaterialCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const bool mi,const Prim &p)
|
||||
{
|
||||
dev_attr=da;
|
||||
|
||||
mtl_name=name;
|
||||
|
||||
material_instance=mi;
|
||||
|
||||
shader_stage_flag_bit=VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
prim=p;
|
||||
|
@ -5,12 +5,14 @@
|
||||
#define STD_MTL_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace mtl{
|
||||
#define STD_MTL_NAMESPACE_END }}}
|
||||
|
||||
#define STD_MTL_NAMESPACE_USING using namespace hgl::graph::mtl;
|
||||
#define STD_MTL_NAMESPACE hgl::graph::mtl
|
||||
#define STD_MTL_NAMESPACE_USING using namespace STD_MTL_NAMESPACE;
|
||||
|
||||
#define STD_MTL_FUNC_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace mtl{namespace func{
|
||||
#define STD_MTL_FUNC_NAMESPACE_END }}}}
|
||||
|
||||
#define STD_MTL_FUNC NAMESPACE_USING using namespace hgl::graph::mtl::func;
|
||||
#define STD_MTL_FUNC_NAMESPACE hgl::graph::mtl::func
|
||||
#define STD_MTL_FUNC_NAMESPACE_USING using namespace STD_MTL_FUNC_NAMESPACE;
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
|
@ -42,10 +42,24 @@ constexpr const ShaderBufferSource SBS_CameraInfo=
|
||||
float znear,zfar;)"
|
||||
};
|
||||
|
||||
constexpr const char LocalToWorldStruct[]="LocalToWorld";
|
||||
constexpr const DescriptorSetType DST_LocalToWorld=DescriptorSetType::PerFrame;
|
||||
|
||||
constexpr const ShaderBufferSource SBS_LocalToWorld=
|
||||
{
|
||||
"LocalToWorldData",
|
||||
"l2w",
|
||||
|
||||
R"(
|
||||
mat4 mats[L2W_MAX_COUNT];
|
||||
)"
|
||||
};
|
||||
|
||||
// UBO必须严格指定数组的大小
|
||||
// SSBO则不需要,使用[]方式指定为动态大小数组
|
||||
|
||||
constexpr const char MaterialInstanceStruct[]="MaterialInstance";
|
||||
constexpr const DescriptorSetType DST_MaterialInstance=DescriptorSetType::PerMaterial;
|
||||
|
||||
constexpr const ShaderBufferSource SBS_MaterialInstance=
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include<hgl/shadergen/MaterialDescriptorInfo.h>
|
||||
#include<hgl/shadergen/ShaderCreateInfoVertex.h>
|
||||
@ -33,7 +33,9 @@ namespace hgl{namespace graph
|
||||
uint32_t mi_max_count;
|
||||
UBODescriptor *mi_ubo;
|
||||
|
||||
uint32_t l2w_max_count;
|
||||
uint32_t l2w_shader_stage;
|
||||
UBODescriptor *l2w_ubo;
|
||||
|
||||
ShaderCreateInfoMap shader_map; ///<着色器列表
|
||||
|
||||
|
@ -21,8 +21,7 @@ namespace hgl
|
||||
|
||||
int hasInput(const char *);
|
||||
|
||||
void AddLocalToWorld();
|
||||
void AddMaterialInstanceID();
|
||||
void AddAssign();
|
||||
|
||||
void AddJoint();
|
||||
};//class ShaderCreateInfoVertex:public ShaderCreateInfo
|
||||
|
@ -53,15 +53,7 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
|
||||
cmd_buf=nullptr;
|
||||
material=m;
|
||||
|
||||
if(l2w)
|
||||
l2w_buffer=new RenderL2WBuffer(device);
|
||||
else
|
||||
l2w_buffer=nullptr;
|
||||
|
||||
if(material->HasMI())
|
||||
mi_buffer=new RenderMIBuffer(device,material->GetMIDataBytes());
|
||||
else
|
||||
mi_buffer=nullptr;
|
||||
assign_buffer=new RenderAssignBuffer(device,material);
|
||||
|
||||
vbo_list=new VBOList(material->GetVertexInput()->GetCount());
|
||||
}
|
||||
@ -69,8 +61,7 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
|
||||
MaterialRenderList::~MaterialRenderList()
|
||||
{
|
||||
SAFE_CLEAR(vbo_list);
|
||||
SAFE_CLEAR(mi_buffer);
|
||||
SAFE_CLEAR(l2w_buffer);
|
||||
SAFE_CLEAR(assign_buffer);
|
||||
}
|
||||
|
||||
void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat)
|
||||
@ -94,16 +85,8 @@ void MaterialRenderList::End()
|
||||
|
||||
Stat();
|
||||
|
||||
if(l2w_buffer)
|
||||
{
|
||||
l2w_buffer->WriteNode(rn_list.GetData(),node_count);
|
||||
}
|
||||
|
||||
if(mi_buffer)
|
||||
{
|
||||
StatMI();
|
||||
mi_buffer->WriteNode(rn_list.GetData(),node_count,mi_set);
|
||||
}
|
||||
if(assign_buffer)
|
||||
assign_buffer->WriteNode(rn_list);
|
||||
}
|
||||
|
||||
void MaterialRenderList::RenderItem::Set(Renderable *ri)
|
||||
@ -113,19 +96,6 @@ void MaterialRenderList::RenderItem::Set(Renderable *ri)
|
||||
vid =ri->GetVertexInputData();
|
||||
}
|
||||
|
||||
void MaterialRenderList::StatMI()
|
||||
{
|
||||
mi_set.Clear();
|
||||
|
||||
for(RenderNode &rn:rn_list)
|
||||
mi_set.Add(rn.ri->GetMaterialInstance());
|
||||
|
||||
if(mi_set.GetCount()>material->GetMIMaxCount())
|
||||
{
|
||||
//超出最大数量了怎么办???
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialRenderList::Stat()
|
||||
{
|
||||
const uint count=rn_list.GetCount();
|
||||
@ -187,16 +157,8 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
|
||||
vbo_list->Add(vid->buffer_list,vid->buffer_offset,vid->binding_count);
|
||||
}
|
||||
|
||||
if(l2w_buffer)//LocalToWorld组,由RenderList合成
|
||||
{
|
||||
for(uint i=0;i<4;i++)
|
||||
l2w_buffer_size[i]=ri_index*16; //mat4每列都是rgba32f,自然是16字节
|
||||
|
||||
vbo_list->Add(l2w_buffer->GetVBO(),l2w_buffer_size,4);
|
||||
}
|
||||
|
||||
if(mi_buffer) //材质实例组
|
||||
vbo_list->Add(mi_buffer->GetVBO(),MI_VAB_STRIDE_BYTES*ri_index);
|
||||
if(assign_buffer) //L2W/MI分发组
|
||||
vbo_list->Add(assign_buffer->GetVAB(),ASSIGN_VAB_STRIDE_BYTES*ri_index);
|
||||
|
||||
//if(!vbo_list.IsFull()) //Joint组,暂未支持
|
||||
//{
|
||||
@ -282,8 +244,8 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb)
|
||||
last_pipeline =nullptr;
|
||||
last_vid =nullptr;
|
||||
|
||||
if(mi_buffer)
|
||||
mi_buffer->Bind(material);
|
||||
if(assign_buffer)
|
||||
assign_buffer->Bind(material);
|
||||
|
||||
cmd_buf->BindDescriptorSets(material);
|
||||
|
||||
|
@ -8,184 +8,186 @@
|
||||
#include<hgl/graph/mtl/UBOCommon.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
RenderL2WBuffer::RenderL2WBuffer(GPUDevice *dev)
|
||||
{
|
||||
hgl_zero(*this);
|
||||
|
||||
device=dev;
|
||||
}
|
||||
|
||||
void RenderL2WBuffer::Clear()
|
||||
{
|
||||
SAFE_CLEAR(l2w_vbo[0])
|
||||
SAFE_CLEAR(l2w_vbo[1])
|
||||
SAFE_CLEAR(l2w_vbo[2])
|
||||
SAFE_CLEAR(l2w_vbo[3])
|
||||
|
||||
node_count=0;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
namespace
|
||||
{
|
||||
constexpr const char *l2w_buffer_name[]=
|
||||
{
|
||||
"VAB:Buffer:LocalToWorld:0",
|
||||
"VAB:Buffer:LocalToWorld:1",
|
||||
"VAB:Buffer:LocalToWorld:2",
|
||||
"VAB:Buffer:LocalToWorld:3"
|
||||
};
|
||||
|
||||
constexpr const char *l2w_memory_name[]=
|
||||
{
|
||||
"VAB:Memory:LocalToWorld:0",
|
||||
"VAB:Memory:LocalToWorld:1",
|
||||
"VAB:Memory:LocalToWorld:2",
|
||||
"VAB:Memory:LocalToWorld:3"
|
||||
};
|
||||
}
|
||||
#endif//_DEBUG
|
||||
|
||||
void RenderL2WBuffer::Alloc(const uint nc)
|
||||
{
|
||||
Clear();
|
||||
|
||||
{
|
||||
node_count=nc;
|
||||
|
||||
for(uint i=0;i<4;i++)
|
||||
{
|
||||
l2w_vbo[i]=device->CreateVAB(VF_V4F,node_count);
|
||||
l2w_buffer[i]=l2w_vbo[i]->GetBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
DebugUtils *du=device->GetDebugUtils();
|
||||
|
||||
if(du)
|
||||
{
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
du->SetBuffer(l2w_buffer[i],l2w_buffer_name[i]);
|
||||
du->SetDeviceMemory(l2w_vbo[i]->GetVkMemory(),l2w_memory_name[i]);
|
||||
}
|
||||
}
|
||||
#endif//_DEBUG
|
||||
}
|
||||
|
||||
void RenderL2WBuffer::WriteNode(RenderNode *render_node,const uint count)
|
||||
{
|
||||
RenderNode *rn;
|
||||
|
||||
Alloc(count);
|
||||
|
||||
glm::vec4 *tp;
|
||||
|
||||
for(uint col=0;col<4;col++)
|
||||
{
|
||||
tp=(glm::vec4 *)(l2w_vbo[col]->DeviceBuffer::Map());
|
||||
|
||||
rn=render_node;
|
||||
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*tp=rn->local_to_world[col];
|
||||
++tp;
|
||||
++rn;
|
||||
}
|
||||
|
||||
l2w_vbo[col]->Unmap();
|
||||
}
|
||||
}
|
||||
VK_NAMESPACE_END
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
RenderMIBuffer::RenderMIBuffer(GPUDevice *dev,const uint mi_bytes)
|
||||
RenderAssignBuffer::RenderAssignBuffer(GPUDevice *dev,Material *mtl)
|
||||
{
|
||||
hgl_zero(*this);
|
||||
|
||||
device=dev;
|
||||
|
||||
mi_data_bytes=mi_bytes;
|
||||
material=mtl;
|
||||
|
||||
mi_data_bytes=mtl->GetMIDataBytes();
|
||||
|
||||
LW2_MAX_COUNT=dev->GetUBORange()/sizeof(Matrix4f);
|
||||
|
||||
l2w_buffer_max_count=0;
|
||||
l2w_buffer=nullptr;
|
||||
mi_buffer=nullptr;
|
||||
}
|
||||
|
||||
void RenderMIBuffer::Bind(Material *mtl)const
|
||||
void RenderAssignBuffer::Bind(Material *mtl)const
|
||||
{
|
||||
if(!mtl)return;
|
||||
|
||||
mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,mi_data_buffer);
|
||||
mtl->BindUBO(mtl::DST_LocalToWorld, mtl::SBS_LocalToWorld.name, l2w_buffer);
|
||||
mtl->BindUBO(mtl::DST_MaterialInstance, mtl::SBS_MaterialInstance.name, mi_buffer);
|
||||
}
|
||||
|
||||
void RenderMIBuffer::Clear()
|
||||
void RenderAssignBuffer::Clear()
|
||||
{
|
||||
SAFE_CLEAR(mi_data_buffer);
|
||||
SAFE_CLEAR(mi_vab);
|
||||
|
||||
mi_count=0;
|
||||
node_count=0;
|
||||
SAFE_CLEAR(l2w_buffer);
|
||||
SAFE_CLEAR(mi_buffer);
|
||||
SAFE_CLEAR(assign_vab);
|
||||
}
|
||||
|
||||
void RenderMIBuffer::Alloc(const uint nc,const uint mc)
|
||||
void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list)
|
||||
{
|
||||
Clear();
|
||||
|
||||
node_count=nc;
|
||||
|
||||
if(mi_data_bytes>0&&mc>0)
|
||||
if(!l2w_buffer)
|
||||
{
|
||||
mi_count=mc;
|
||||
|
||||
mi_data_buffer=device->CreateUBO(mi_data_bytes*mi_count);
|
||||
l2w_buffer_max_count=power_to_2(rn_list.GetCount());
|
||||
}
|
||||
else if(rn_list.GetCount()>l2w_buffer_max_count)
|
||||
{
|
||||
l2w_buffer_max_count=power_to_2(rn_list.GetCount());
|
||||
SAFE_CLEAR(l2w_buffer);
|
||||
}
|
||||
|
||||
mi_vab=device->CreateVAB(MI_VAB_FMT,node_count);
|
||||
mi_buffer=mi_vab->GetBuffer();
|
||||
|
||||
if(!l2w_buffer)
|
||||
{
|
||||
l2w_buffer=device->CreateUBO(sizeof(Matrix4f)*l2w_buffer_max_count);
|
||||
|
||||
#ifdef _DEBUG
|
||||
DebugUtils *du=device->GetDebugUtils();
|
||||
|
||||
if(du)
|
||||
{
|
||||
du->SetBuffer(mi_data_buffer->GetBuffer(),"UBO:Buffer:MaterialInstance");
|
||||
du->SetDeviceMemory(mi_data_buffer->GetVkMemory(),"UBO:Memory:MaterialInstance");
|
||||
|
||||
du->SetBuffer(mi_vab->GetBuffer(),"VAB:Buffer:MaterialInstanceID");
|
||||
du->SetDeviceMemory(mi_vab->GetVkMemory(),"VAB:Memory:MaterialInstanceID");
|
||||
du->SetBuffer(l2w_buffer->GetBuffer(),"UBO:Buffer:LocalToWorld");
|
||||
du->SetDeviceMemory(l2w_buffer->GetVkMemory(),"UBO:Memory:LocalToWorld");
|
||||
}
|
||||
#endif//_DEBUG
|
||||
}
|
||||
|
||||
void RenderMIBuffer::WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
|
||||
{
|
||||
RenderNode *rn;
|
||||
|
||||
Alloc(count,mi_set.GetCount());
|
||||
|
||||
uint8 *mip=(uint8 *)(mi_data_buffer->Map());
|
||||
|
||||
for(MaterialInstance *mi:mi_set)
|
||||
{
|
||||
memcpy(mip,mi->GetMIData(),mi_data_bytes);
|
||||
mip+=mi_data_bytes;
|
||||
}
|
||||
|
||||
mi_data_buffer->Unmap();
|
||||
RenderNode *rn=rn_list.GetData();
|
||||
Matrix4f *l2wp=(Matrix4f *)(l2w_buffer->DeviceBuffer::Map());
|
||||
|
||||
uint16 *idp=(uint16 *)(mi_vab->DeviceBuffer::Map());
|
||||
for(uint i=0;i<rn_list.GetCount();i++)
|
||||
{
|
||||
*l2wp=rn->local_to_world;
|
||||
++l2wp;
|
||||
++rn;
|
||||
}
|
||||
|
||||
l2w_buffer->Unmap();
|
||||
}
|
||||
|
||||
void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list)
|
||||
{
|
||||
mi_set.Clear();
|
||||
|
||||
if(mi_data_bytes<=0) //没有材质实例数据
|
||||
return;
|
||||
|
||||
if(!mi_buffer)
|
||||
{
|
||||
mi_set.PreAlloc(power_to_2(rn_list.GetCount()));
|
||||
}
|
||||
else if(rn_list.GetCount()>mi_set.GetAllocCount())
|
||||
{
|
||||
mi_set.PreAlloc(power_to_2(rn_list.GetCount()));
|
||||
SAFE_CLEAR(mi_buffer);
|
||||
}
|
||||
|
||||
if(!mi_buffer)
|
||||
{
|
||||
mi_buffer=device->CreateUBO(mi_data_bytes*mi_set.GetAllocCount());
|
||||
|
||||
#ifdef _DEBUG
|
||||
DebugUtils *du=device->GetDebugUtils();
|
||||
|
||||
if(du)
|
||||
{
|
||||
du->SetBuffer(mi_buffer->GetBuffer(),"UBO:Buffer:MaterialInstanceData");
|
||||
du->SetDeviceMemory(mi_buffer->GetVkMemory(),"UBO:Memory:MaterialInstanceData");
|
||||
}
|
||||
#endif//_DEBUG
|
||||
}
|
||||
|
||||
mi_set.PreAlloc(rn_list.GetCount());
|
||||
|
||||
for(RenderNode &rn:rn_list)
|
||||
mi_set.Add(rn.ri->GetMaterialInstance());
|
||||
|
||||
if(mi_set.GetCount()>material->GetMIMaxCount())
|
||||
{
|
||||
//超出最大数量了怎么办???
|
||||
}
|
||||
|
||||
//合并材质实例数据
|
||||
{
|
||||
uint8 *mip=(uint8 *)(mi_buffer->Map());
|
||||
|
||||
for(MaterialInstance *mi:mi_set)
|
||||
{
|
||||
memcpy(mip,mi->GetMIData(),mi_data_bytes);
|
||||
mip+=mi_data_bytes;
|
||||
}
|
||||
|
||||
mi_buffer->Unmap();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderAssignBuffer::WriteNode(const RenderNodeList &rn_list)
|
||||
{
|
||||
if(rn_list.GetCount()<=0)
|
||||
return;
|
||||
|
||||
StatL2W(rn_list);
|
||||
StatMI(rn_list);
|
||||
|
||||
{
|
||||
rn=render_node;
|
||||
|
||||
for(uint i=0;i<count;i++)
|
||||
if(!assign_vab)
|
||||
{
|
||||
*idp=mi_set.Find(rn->ri->GetMaterialInstance());
|
||||
++idp;
|
||||
node_count=power_to_2(rn_list.GetCount());
|
||||
}
|
||||
else if(node_count<rn_list.GetCount())
|
||||
{
|
||||
node_count=power_to_2(rn_list.GetCount());
|
||||
SAFE_CLEAR(assign_vab);
|
||||
}
|
||||
|
||||
if(!assign_vab)
|
||||
{
|
||||
assign_vab=device->CreateVAB(ASSIGN_VAB_FMT,node_count);
|
||||
assign_buffer=assign_vab->GetBuffer();
|
||||
|
||||
#ifdef _DEBUG
|
||||
DebugUtils *du=device->GetDebugUtils();
|
||||
|
||||
if(du)
|
||||
{
|
||||
du->SetBuffer(assign_vab->GetBuffer(),"VAB:Buffer:AssignData");
|
||||
du->SetDeviceMemory(assign_vab->GetVkMemory(),"VAB:Memory:AssignData");
|
||||
}
|
||||
#endif//_DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
//生成材质实例ID列表
|
||||
{
|
||||
RenderNode *rn=rn_list.GetData();
|
||||
|
||||
AssignData *adp=(AssignData *)(assign_vab->DeviceBuffer::Map());
|
||||
|
||||
for(uint i=0;i<rn_list.GetCount();i++)
|
||||
{
|
||||
adp->l2w=i;
|
||||
adp->mi=mi_set.Find(rn->ri->GetMaterialInstance());
|
||||
++adp;
|
||||
|
||||
++rn;
|
||||
}
|
||||
}
|
||||
|
||||
mi_vab->Unmap();
|
||||
assign_vab->Unmap();
|
||||
}
|
||||
}
|
||||
VK_NAMESPACE_END
|
||||
|
@ -16,6 +16,7 @@ VK_NAMESPACE_BEGIN
|
||||
// 如果一定要使用超过16K/64K硬件限制的容量,有两种办法
|
||||
// 一、分多次渲染,使用UBO Offset偏移UBO数据区。
|
||||
// 二、使用SSBO,但这样会导致性能下降,所以不推荐使用。
|
||||
// 三、使用纹理保存材质实例数据,但这样会导致性能下降,所以不推荐使用。
|
||||
|
||||
// 但我们不解决这个问题
|
||||
// 我们天然要求将材质实例数据分为两个等级,同时要求一次渲染不能超过256种材质实例。
|
||||
@ -25,73 +26,71 @@ VK_NAMESPACE_BEGIN
|
||||
struct RenderNode;
|
||||
class MaterialInstance;
|
||||
|
||||
class RenderL2WBuffer
|
||||
{
|
||||
GPUDevice *device;
|
||||
|
||||
uint node_count; ///<渲染节点数量
|
||||
|
||||
VAB *l2w_vbo[4];
|
||||
VkBuffer l2w_buffer[4];
|
||||
|
||||
private:
|
||||
|
||||
void Alloc(const uint nc);
|
||||
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
|
||||
const VkBuffer *GetVBO()const{return l2w_buffer;}
|
||||
|
||||
public:
|
||||
|
||||
RenderL2WBuffer(GPUDevice *dev);
|
||||
~RenderL2WBuffer(){Clear();}
|
||||
|
||||
void WriteNode(RenderNode *render_node,const uint count);
|
||||
};//class RenderL2WBuffer
|
||||
|
||||
/*
|
||||
* 渲染节点额外提供的数据
|
||||
*/
|
||||
class RenderMIBuffer
|
||||
class RenderAssignBuffer
|
||||
{
|
||||
struct AssignData
|
||||
{
|
||||
uint16 l2w;
|
||||
uint16 mi;
|
||||
};
|
||||
|
||||
uint LW2_MAX_COUNT;
|
||||
|
||||
private:
|
||||
|
||||
GPUDevice *device;
|
||||
|
||||
uint node_count; ///<渲染节点数量
|
||||
Material *material;
|
||||
|
||||
uint32_t mi_data_bytes; ///<材质实例数据字节数
|
||||
uint32_t mi_count; ///<材质实例数量
|
||||
DeviceBuffer *mi_data_buffer; ///<材质实例数据(UBO/SSBO)
|
||||
private: //LocalToWorld矩阵数据
|
||||
|
||||
uint32 l2w_buffer_max_count; ///<LocalToWorld矩阵最大数量
|
||||
DeviceBuffer *l2w_buffer; ///<LocalToWorld矩阵数据(UBO/SSBO)
|
||||
|
||||
void StatL2W(const RenderNodeList &);
|
||||
|
||||
private: //材质实例数据
|
||||
|
||||
VAB *mi_vab; ///<材质实例ID(R16UI格式)
|
||||
VkBuffer mi_buffer;
|
||||
MaterialInstanceSets mi_set;
|
||||
|
||||
uint32_t mi_data_bytes; ///<单个材质实例数据字节数
|
||||
DeviceBuffer *mi_buffer; ///<材质实例数据(UBO/SSBO)
|
||||
|
||||
void StatMI(const RenderNodeList &);
|
||||
|
||||
private: //分发数据
|
||||
|
||||
uint32 node_count; ///<节点数量
|
||||
|
||||
VAB *assign_vab; ///<分发数据VAB(RG16UI格式,R存L2W ID,G存材质实例ID)
|
||||
VkBuffer assign_buffer; ///<分发数据Buffer
|
||||
|
||||
private:
|
||||
|
||||
void Alloc(const uint nc,const uint mc);
|
||||
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
|
||||
const VkBuffer GetVBO()const{return mi_buffer;}
|
||||
const VkBuffer GetVAB()const{return assign_buffer;}
|
||||
|
||||
void Bind(Material *)const;
|
||||
|
||||
public:
|
||||
|
||||
RenderMIBuffer(GPUDevice *dev,const uint32_t mi_bytes);
|
||||
~RenderMIBuffer(){Clear();}
|
||||
RenderAssignBuffer(GPUDevice *dev,Material *);
|
||||
~RenderAssignBuffer(){Clear();}
|
||||
|
||||
//下一代,将MaterialInstanceSets使用提前化,这样不用每一次绘制都重新写入MI DATA,可以提升效率。
|
||||
//虽然这样就不自动化了,但我们要的就是不自动化。
|
||||
//必须在外部全部准备好MaterialInstanceSets,然后一次性写入。
|
||||
//渲染时找不到就直接用0号材质实例
|
||||
|
||||
void WriteNode(RenderNode *render_node,const uint nc,const MaterialInstanceSets &mi_set);
|
||||
};//struct RenderMIBuffer
|
||||
//同样的LocalToWorld矩阵也可以提前化处理,这样对于静态物体,就只需要写入一次LocalToWorld矩阵了。
|
||||
|
||||
void WriteNode(const RenderNodeList &);
|
||||
|
||||
};//struct RenderAssignBuffer
|
||||
VK_NAMESPACE_END
|
||||
|
@ -39,7 +39,7 @@ void main()
|
||||
if(!Std2DMaterial::CustomVertexShader(vsc))
|
||||
return(false);
|
||||
|
||||
vsc->AddMaterialInstanceID();
|
||||
vsc->AddAssign();
|
||||
vsc->SetMain(vs_main);
|
||||
return(true);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include"Std2DMaterial.h"
|
||||
#include"Std2DMaterial.h"
|
||||
#include<hgl/shadergen/MaterialCreateInfo.h>
|
||||
#include<hgl/graph/mtl/Material2DCreateConfig.h>
|
||||
#include<hgl/graph/mtl/UBOCommon.h>
|
||||
@ -13,10 +13,18 @@ bool Std2DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
|
||||
vsc->AddInput(cfg->position_format,VAN::Position);
|
||||
|
||||
const bool is_rect=(cfg->prim==Prim::SolidRectangles||cfg->prim==Prim::WireRectangles);
|
||||
|
||||
if(cfg->local_to_world||cfg->material_instance)
|
||||
{
|
||||
mci->AddStruct(SBS_LocalToWorld);
|
||||
|
||||
mci->AddUBO(VK_SHADER_STAGE_ALL_GRAPHICS,DescriptorSetType::PerFrame,SBS_LocalToWorld);
|
||||
|
||||
vsc->AddAssign();
|
||||
}
|
||||
|
||||
if(cfg->local_to_world)
|
||||
{
|
||||
vsc->AddLocalToWorld();
|
||||
mci->SetLocalToWorld(VK_SHADER_STAGE_ALL_GRAPHICS);
|
||||
|
||||
if(is_rect)
|
||||
|
@ -16,7 +16,7 @@ namespace
|
||||
|
||||
public:
|
||||
|
||||
Std2DMaterialLoader(material_file::MaterialFileData *data,const Material2DCreateConfig *cfg):Std2DMaterial(cfg)
|
||||
Std2DMaterialLoader(material_file::MaterialFileData *data,const Material2DCreateConfig *c):Std2DMaterial(c)
|
||||
{
|
||||
mfd=data;
|
||||
}
|
||||
@ -76,9 +76,6 @@ namespace
|
||||
for(auto &ua:mfd->vi)
|
||||
vsc->AddInput(ua.vat,ua.name);
|
||||
|
||||
if(mfd->mi.mi_bytes>0)
|
||||
vsc->AddMaterialInstanceID();
|
||||
|
||||
if(!Std2DMaterial::CustomVertexShader(vsc))
|
||||
return(false);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include"Std3DMaterial.h"
|
||||
#include"Std3DMaterial.h"
|
||||
#include<hgl/shadergen/MaterialCreateInfo.h>
|
||||
#include<hgl/graph/mtl/Material3DCreateConfig.h>
|
||||
#include<hgl/graph/mtl/UBOCommon.h>
|
||||
@ -10,6 +10,15 @@ STD_MTL_NAMESPACE_BEGIN
|
||||
bool Std3DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
|
||||
{
|
||||
vsc->AddInput(cfg->position_format,VAN::Position);
|
||||
|
||||
if(cfg->camera||cfg->local_to_world||cfg->material_instance)
|
||||
{
|
||||
mci->AddStruct(SBS_LocalToWorld);
|
||||
|
||||
mci->AddUBO(VK_SHADER_STAGE_ALL_GRAPHICS,DescriptorSetType::PerFrame,SBS_LocalToWorld);
|
||||
|
||||
vsc->AddAssign();
|
||||
}
|
||||
|
||||
if(cfg->camera)
|
||||
{
|
||||
@ -24,7 +33,6 @@ bool Std3DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
|
||||
{
|
||||
mci->SetLocalToWorld(VK_SHADER_STAGE_ALL_GRAPHICS);
|
||||
|
||||
vsc->AddLocalToWorld();
|
||||
vsc->AddFunction(cfg->camera?func::GetPosition3DL2WCamera:func::GetPosition3DL2W);
|
||||
}
|
||||
else
|
||||
|
@ -16,8 +16,8 @@ namespace
|
||||
|
||||
public:
|
||||
|
||||
Std3DMaterialLoader(material_file::MaterialFileData *data,const Material3DCreateConfig *cfg)
|
||||
: Std3DMaterial(cfg)
|
||||
Std3DMaterialLoader(material_file::MaterialFileData *data,const Material3DCreateConfig *c)
|
||||
: Std3DMaterial(c)
|
||||
{
|
||||
mfd=data;
|
||||
}
|
||||
@ -77,9 +77,6 @@ namespace
|
||||
for(auto &ua:mfd->vi)
|
||||
vsc->AddInput(ua.vat,ua.name);
|
||||
|
||||
if(mfd->mi.mi_bytes>0)
|
||||
vsc->AddMaterialInstanceID();
|
||||
|
||||
if(!Std3DMaterial::CustomVertexShader(vsc))
|
||||
return (false);
|
||||
|
||||
|
@ -172,9 +172,9 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
|
||||
|
||||
mi_ubo=CreateUBODescriptor(SBS_MaterialInstance,shader_stage_flag_bits);
|
||||
|
||||
mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,mi_ubo);
|
||||
mdi.AddUBO(shader_stage_flag_bits,DST_MaterialInstance,mi_ubo);
|
||||
|
||||
const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count);
|
||||
const AnsiString MI_MAX_COUNT_STRING=AnsiString::numberOf(mi_max_count);
|
||||
|
||||
auto *it=shader_map.GetDataList();
|
||||
|
||||
@ -182,7 +182,7 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
|
||||
{
|
||||
if((*it)->key&shader_stage_flag_bits)
|
||||
{
|
||||
(*it)->value->AddDefine("MI_MAX_COUNT",MI_MAX_COUNT);
|
||||
(*it)->value->AddDefine("MI_MAX_COUNT",MI_MAX_COUNT_STRING);
|
||||
(*it)->value->SetMaterialInstance(mi_ubo,mi_codes);
|
||||
}
|
||||
|
||||
@ -198,6 +198,28 @@ bool MaterialCreateInfo::SetLocalToWorld(const uint32_t shader_stage_flag_bits)
|
||||
{
|
||||
if(shader_stage_flag_bits==0)return(false);
|
||||
|
||||
l2w_max_count=hgl_min<uint32_t>(ubo_range/sizeof(Matrix4f),HGL_U16_MAX);
|
||||
|
||||
mdi.AddStruct(SBS_LocalToWorld);
|
||||
|
||||
l2w_ubo=CreateUBODescriptor(SBS_LocalToWorld,shader_stage_flag_bits);
|
||||
|
||||
mdi.AddUBO(shader_stage_flag_bits,DST_LocalToWorld,l2w_ubo);
|
||||
|
||||
const AnsiString L2W_MAX_COUNT_STRING=AnsiString::numberOf(l2w_max_count);
|
||||
|
||||
auto *it=shader_map.GetDataList();
|
||||
|
||||
for(int i=0;i<shader_map.GetCount();i++)
|
||||
{
|
||||
if((*it)->key&shader_stage_flag_bits)
|
||||
{
|
||||
(*it)->value->AddDefine("L2W_MAX_COUNT",L2W_MAX_COUNT_STRING);
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
l2w_shader_stage=shader_stage_flag_bits;
|
||||
|
||||
return(true);
|
||||
|
@ -156,10 +156,11 @@ bool ShaderCreateInfo::ProcSubpassInput()
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char MF_GetMI_VS []="\nMaterialInstance GetMI(){return mtl.mi[MaterialInstanceID];}\n";
|
||||
constexpr const char MI_ID_OUTPUT[]="MaterialInstanceID";
|
||||
constexpr const char MF_GetMI_VS []="\nMaterialInstance GetMI(){return mtl.mi[Assign.y];}\n";
|
||||
constexpr const char MF_GetMI_Other []="\nMaterialInstance GetMI(){return mtl.mi[Input.MaterialInstanceID];}\n";
|
||||
|
||||
constexpr const char MF_HandoverMI_VS[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=MaterialInstanceID;}\n";
|
||||
constexpr const char MF_HandoverMI_VS[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=Assign.y;}\n";
|
||||
constexpr const char MF_HandoverMI_GS[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=Input[0].MaterialInstanceID;}\n";
|
||||
constexpr const char MF_HandoverMI_OTHER[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=Input.MaterialInstanceID;}\n";
|
||||
}//namespace
|
||||
@ -176,7 +177,7 @@ void ShaderCreateInfo::SetMaterialInstance(UBODescriptor *ubo,const AnsiString &
|
||||
|
||||
void ShaderCreateInfo::AddMaterialInstanceOutput()
|
||||
{
|
||||
AddOutput(VAT_UINT,mtl::func::MaterialInstanceID,Interpolation::Flat);
|
||||
AddOutput(VAT_UINT,MI_ID_OUTPUT,Interpolation::Flat);
|
||||
|
||||
if(shader_stage==VK_SHADER_STAGE_VERTEX_BIT) AddFunction(MF_HandoverMI_VS);else
|
||||
if(shader_stage==VK_SHADER_STAGE_GEOMETRY_BIT) AddFunction(MF_HandoverMI_GS);else
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include<hgl/shadergen/ShaderCreateInfoVertex.h>
|
||||
#include<hgl/shadergen/ShaderCreateInfoVertex.h>
|
||||
#include<hgl/shadergen/ShaderDescriptorInfo.h>
|
||||
#include<hgl/graph/VertexAttrib.h>
|
||||
#include<hgl/graph/VKShaderStage.h>
|
||||
@ -48,41 +48,14 @@ void ShaderCreateInfoVertex::AddJoint()
|
||||
AddInput(VAT_VEC4, VAN::JointWeight,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::JointWeight);
|
||||
}
|
||||
|
||||
namespace
|
||||
void ShaderCreateInfoVertex::AddAssign()
|
||||
{
|
||||
constexpr const char MF_GetLocalToWorld_ByID[]="\nmat4 GetLocalToWorld(){return l2w.mats[LocalToWorld_ID];}\n";
|
||||
|
||||
constexpr const char MF_GetLocalToWorld_by4VI[]=R"(
|
||||
mat4 GetLocalToWorld()
|
||||
{
|
||||
return mat4(LocalToWorld_0,
|
||||
LocalToWorld_1,
|
||||
LocalToWorld_2,
|
||||
LocalToWorld_3);
|
||||
}
|
||||
)";
|
||||
}
|
||||
|
||||
void ShaderCreateInfoVertex::AddLocalToWorld()
|
||||
{
|
||||
char name[]= "LocalToWorld_?";
|
||||
|
||||
for(uint i=0;i<4;i++)
|
||||
{
|
||||
name[sizeof(name)-2]='0'+i;
|
||||
|
||||
AddInput(VAT_VEC4,name,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::LocalToWorld);
|
||||
}
|
||||
|
||||
AddFunction(MF_GetLocalToWorld_by4VI);
|
||||
}
|
||||
|
||||
void ShaderCreateInfoVertex::AddMaterialInstanceID()
|
||||
{
|
||||
AddInput( MI_VAT_FMT,
|
||||
MI_VIS_NAME,
|
||||
AddInput( ASSIGN_VAT_FMT,
|
||||
ASSIGN_VIS_NAME,
|
||||
VK_VERTEX_INPUT_RATE_INSTANCE,
|
||||
VertexInputGroup::MaterialInstanceID);
|
||||
VertexInputGroup::Assign);
|
||||
|
||||
AddFunction(STD_MTL_FUNC_NAMESPACE::MF_GetLocalToWorld_ByAssign);
|
||||
}
|
||||
|
||||
bool ShaderCreateInfoVertex::ProcInput(ShaderCreateInfo *)
|
||||
|
@ -2,21 +2,11 @@
|
||||
|
||||
#include<hgl/graph/mtl/StdMaterial.h>
|
||||
|
||||
STD_MTL_NAMESPACE_BEGIN
|
||||
namespace func
|
||||
{
|
||||
STD_MTL_FUNC_NAMESPACE_BEGIN
|
||||
//C++端使用一个RG8UI或RGB16UI格式的顶点输入流来传递Assign数据,其中x为LocalToWorld ID,y为MaterialInstance ID
|
||||
|
||||
constexpr const char MF_GetLocalToWorld_ByAssign[]= "\nmat4 GetLocalToWorld(){return l2w.mats[Assign.x];}\n";
|
||||
|
||||
constexpr const char MaterialInstanceID[]="MaterialInstanceID";
|
||||
constexpr const char MF_GetMaterialInstance_ByAssign[]= "\nMaterialInstance GetMaterialInstance(){return mi_set[Assign.y];}\n";
|
||||
|
||||
constexpr const char GetLocalToWorld[]=R"(
|
||||
mat4 GetLocalToWorld()
|
||||
{
|
||||
return mat4(LocalToWorld_0,
|
||||
LocalToWorld_1,
|
||||
LocalToWorld_2,
|
||||
LocalToWorld_3);
|
||||
}
|
||||
)";
|
||||
}//namespace func
|
||||
STD_MTL_NAMESPACE_END
|
||||
STD_MTL_FUNC_NAMESPACE_END
|
||||
|
Loading…
x
Reference in New Issue
Block a user