From a5e76988c7064abe62e108fbeb573035d60565b6 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sat, 25 May 2024 17:58:39 +0800 Subject: [PATCH] resume Assign instead of local2world and materialinstanceId in VertexInputStream --- CMCore | 2 +- CMSceneGraph | 2 +- .../LightBasic/BlinnPhongDirectionLight.cpp | 4 +- inc/hgl/graph/MaterialRenderList.h | 9 +- inc/hgl/graph/mtl/Material2DCreateConfig.h | 2 +- inc/hgl/graph/mtl/Material3DCreateConfig.h | 2 +- inc/hgl/graph/mtl/MaterialConfig.h | 6 +- inc/hgl/graph/mtl/StdMaterial.h | 6 +- inc/hgl/graph/mtl/UBOCommon.h | 14 + inc/hgl/shadergen/MaterialCreateInfo.h | 4 +- inc/hgl/shadergen/ShaderCreateInfoVertex.h | 3 +- src/SceneGraph/MaterialRenderList.cpp | 54 +--- src/SceneGraph/RenderAssignBuffer.cpp | 288 +++++++++--------- src/SceneGraph/RenderAssignBuffer.h | 81 +++-- src/ShaderGen/2d/M_PureColor2D.cpp | 2 +- src/ShaderGen/2d/Std2DMaterial.cpp | 12 +- src/ShaderGen/2d/Std2DMaterialLoader.cpp | 5 +- src/ShaderGen/3d/Std3DMaterial.cpp | 12 +- src/ShaderGen/3d/Std3DMaterialLoader.cpp | 7 +- src/ShaderGen/MaterialCreateInfo.cpp | 28 +- src/ShaderGen/ShaderCreateInfo.cpp | 7 +- src/ShaderGen/ShaderCreateInfoVertex.cpp | 41 +-- src/ShaderGen/common/MFCommon.h | 20 +- 23 files changed, 293 insertions(+), 318 deletions(-) diff --git a/CMCore b/CMCore index 3d27b60c..d70d3128 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 3d27b60c13162ac2167cc84e9846088a18664312 +Subproject commit d70d31288f601061a69f93b4970af6692e53a34b diff --git a/CMSceneGraph b/CMSceneGraph index f220bd83..a6a36803 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit f220bd8370781f791b3c3a27bd7daa4dc96817e6 +Subproject commit a6a368031209ce23dc14e88acf45dd8298a19886 diff --git a/example/LightBasic/BlinnPhongDirectionLight.cpp b/example/LightBasic/BlinnPhongDirectionLight.cpp index f1b29cf0..a31cdc08 100644 --- a/example/LightBasic/BlinnPhongDirectionLight.cpp +++ b/example/LightBasic/BlinnPhongDirectionLight.cpp @@ -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; diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index 1534291a..a8fa0a0e 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -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 ri_array; uint ri_count; - VkDeviceSize l2w_buffer_size[4]; - - void StatMI(); void Stat(); protected: diff --git a/inc/hgl/graph/mtl/Material2DCreateConfig.h b/inc/hgl/graph/mtl/Material2DCreateConfig.h index eece84c8..bd2fd67a 100644 --- a/inc/hgl/graph/mtl/Material2DCreateConfig.h +++ b/inc/hgl/graph/mtl/Material2DCreateConfig.h @@ -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; //不输出深度 diff --git a/inc/hgl/graph/mtl/Material3DCreateConfig.h b/inc/hgl/graph/mtl/Material3DCreateConfig.h index b3fc6195..1e80129a 100644 --- a/inc/hgl/graph/mtl/Material3DCreateConfig.h +++ b/inc/hgl/graph/mtl/Material3DCreateConfig.h @@ -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; //不输出深度 diff --git a/inc/hgl/graph/mtl/MaterialConfig.h b/inc/hgl/graph/mtl/MaterialConfig.h index 18b0e837..78f6ed54 100644 --- a/inc/hgl/graph/mtl/MaterialConfig.h +++ b/inc/hgl/graph/mtl/MaterialConfig.h @@ -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; diff --git a/inc/hgl/graph/mtl/StdMaterial.h b/inc/hgl/graph/mtl/StdMaterial.h index 27abeda4..51d64813 100644 --- a/inc/hgl/graph/mtl/StdMaterial.h +++ b/inc/hgl/graph/mtl/StdMaterial.h @@ -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 { diff --git a/inc/hgl/graph/mtl/UBOCommon.h b/inc/hgl/graph/mtl/UBOCommon.h index 5438f712..0b835209 100644 --- a/inc/hgl/graph/mtl/UBOCommon.h +++ b/inc/hgl/graph/mtl/UBOCommon.h @@ -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= { diff --git a/inc/hgl/shadergen/MaterialCreateInfo.h b/inc/hgl/shadergen/MaterialCreateInfo.h index f0d7c746..cbcaa1ed 100644 --- a/inc/hgl/shadergen/MaterialCreateInfo.h +++ b/inc/hgl/shadergen/MaterialCreateInfo.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -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; ///<着色器列表 diff --git a/inc/hgl/shadergen/ShaderCreateInfoVertex.h b/inc/hgl/shadergen/ShaderCreateInfoVertex.h index 11152e2a..f73b47a7 100644 --- a/inc/hgl/shadergen/ShaderCreateInfoVertex.h +++ b/inc/hgl/shadergen/ShaderCreateInfoVertex.h @@ -21,8 +21,7 @@ namespace hgl int hasInput(const char *); - void AddLocalToWorld(); - void AddMaterialInstanceID(); + void AddAssign(); void AddJoint(); };//class ShaderCreateInfoVertex:public ShaderCreateInfo diff --git a/src/SceneGraph/MaterialRenderList.cpp b/src/SceneGraph/MaterialRenderList.cpp index 3642460b..027fa7e0 100644 --- a/src/SceneGraph/MaterialRenderList.cpp +++ b/src/SceneGraph/MaterialRenderList.cpp @@ -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); diff --git a/src/SceneGraph/RenderAssignBuffer.cpp b/src/SceneGraph/RenderAssignBuffer.cpp index 8c19caba..e24a0da0 100644 --- a/src/SceneGraph/RenderAssignBuffer.cpp +++ b/src/SceneGraph/RenderAssignBuffer.cpp @@ -8,184 +8,186 @@ #include 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;ilocal_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;ilocal_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;iri->GetMaterialInstance()); - ++idp; + node_count=power_to_2(rn_list.GetCount()); + } + else if(node_countCreateVAB(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;il2w=i; + adp->mi=mi_set.Find(rn->ri->GetMaterialInstance()); + ++adp; ++rn; } - } - mi_vab->Unmap(); + assign_vab->Unmap(); + } } VK_NAMESPACE_END diff --git a/src/SceneGraph/RenderAssignBuffer.h b/src/SceneGraph/RenderAssignBuffer.h index 731f068a..ad8e7a01 100644 --- a/src/SceneGraph/RenderAssignBuffer.h +++ b/src/SceneGraph/RenderAssignBuffer.h @@ -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; ///AddMaterialInstanceID(); + vsc->AddAssign(); vsc->SetMain(vs_main); return(true); } diff --git a/src/ShaderGen/2d/Std2DMaterial.cpp b/src/ShaderGen/2d/Std2DMaterial.cpp index 506c6522..a8f56656 100644 --- a/src/ShaderGen/2d/Std2DMaterial.cpp +++ b/src/ShaderGen/2d/Std2DMaterial.cpp @@ -1,4 +1,4 @@ -#include"Std2DMaterial.h" +#include"Std2DMaterial.h" #include #include #include @@ -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) diff --git a/src/ShaderGen/2d/Std2DMaterialLoader.cpp b/src/ShaderGen/2d/Std2DMaterialLoader.cpp index 27abd178..e538ffcb 100644 --- a/src/ShaderGen/2d/Std2DMaterialLoader.cpp +++ b/src/ShaderGen/2d/Std2DMaterialLoader.cpp @@ -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); diff --git a/src/ShaderGen/3d/Std3DMaterial.cpp b/src/ShaderGen/3d/Std3DMaterial.cpp index 1091d77a..a8d9d926 100644 --- a/src/ShaderGen/3d/Std3DMaterial.cpp +++ b/src/ShaderGen/3d/Std3DMaterial.cpp @@ -1,4 +1,4 @@ -#include"Std3DMaterial.h" +#include"Std3DMaterial.h" #include #include #include @@ -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 diff --git a/src/ShaderGen/3d/Std3DMaterialLoader.cpp b/src/ShaderGen/3d/Std3DMaterialLoader.cpp index a4f62dd4..f72008d0 100644 --- a/src/ShaderGen/3d/Std3DMaterialLoader.cpp +++ b/src/ShaderGen/3d/Std3DMaterialLoader.cpp @@ -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); diff --git a/src/ShaderGen/MaterialCreateInfo.cpp b/src/ShaderGen/MaterialCreateInfo.cpp index 77a3d0a4..0043732d 100644 --- a/src/ShaderGen/MaterialCreateInfo.cpp +++ b/src/ShaderGen/MaterialCreateInfo.cpp @@ -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(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;ikey&shader_stage_flag_bits) + { + (*it)->value->AddDefine("L2W_MAX_COUNT",L2W_MAX_COUNT_STRING); + } + + ++it; + } + l2w_shader_stage=shader_stage_flag_bits; return(true); diff --git a/src/ShaderGen/ShaderCreateInfo.cpp b/src/ShaderGen/ShaderCreateInfo.cpp index cae6809f..ba9f1bab 100644 --- a/src/ShaderGen/ShaderCreateInfo.cpp +++ b/src/ShaderGen/ShaderCreateInfo.cpp @@ -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 diff --git a/src/ShaderGen/ShaderCreateInfoVertex.cpp b/src/ShaderGen/ShaderCreateInfoVertex.cpp index a1fb5a06..c0cb614d 100644 --- a/src/ShaderGen/ShaderCreateInfoVertex.cpp +++ b/src/ShaderGen/ShaderCreateInfoVertex.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -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 *) diff --git a/src/ShaderGen/common/MFCommon.h b/src/ShaderGen/common/MFCommon.h index 1e97c5f7..dade7abc 100644 --- a/src/ShaderGen/common/MFCommon.h +++ b/src/ShaderGen/common/MFCommon.h @@ -2,21 +2,11 @@ #include -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