From 8bb742f3f47b3dc2840e62e1c07844e0d21f2034 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 5 Sep 2023 20:19:53 +0800 Subject: [PATCH] OK???? 3rd_draw_triangle_use_RenderList run OK!. --- CMSceneGraph | 2 +- example/common/VulkanAppFramework.h | 2 +- inc/hgl/graph/MaterialRenderList.h | 5 +- inc/hgl/graph/VKCommandBuffer.h | 14 +- inc/hgl/graph/VKVBOList.h | 57 +++++++ inc/hgl/graph/mtl/UBOCommon.h | 14 +- inc/hgl/shadergen/MaterialCreateInfo.h | 16 +- inc/hgl/shadergen/ShaderCreateInfo.h | 1 + inc/hgl/shadergen/ShaderCreateInfoVertex.h | 3 +- src/SceneGraph/MaterialRenderList.cpp | 146 +++++++++--------- src/SceneGraph/RenderExtraBuffer.h | 55 ++++++- .../Vulkan/VKCommandBufferRender.cpp | 7 +- src/ShaderGen/2d/Std2DMaterial.cpp | 6 +- src/ShaderGen/MaterialCreateInfo.cpp | 91 ++++++++--- src/ShaderGen/ShaderCreateInfo.cpp | 11 +- src/ShaderGen/ShaderCreateInfoVertex.cpp | 16 +- src/ShaderGen/common/MFCommon.h | 55 ++++--- 17 files changed, 356 insertions(+), 145 deletions(-) create mode 100644 inc/hgl/graph/VKVBOList.h diff --git a/CMSceneGraph b/CMSceneGraph index 286f5f43..8b585e15 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 286f5f438733ac608b8a0892d5869620c06d7f86 +Subproject commit 8b585e15eb31c5f412f838a1ec78c529c1a5a2fd diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index d6c27314..e409eca4 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -204,7 +204,7 @@ public: cb->SetClearColor(0,clear_color); cb->BeginRenderPass(); cb->BindPipeline(ri->GetPipeline()); - cb->BindDescriptorSets(ri); + cb->BindDescriptorSets(ri->GetMaterial()); cb->BindVBO(ri); if (vid->index_buffer->buffer) diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index e4ce7bf3..1f4120d7 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -1,5 +1,6 @@ #pragma once #include +#include VK_NAMESPACE_BEGIN struct RenderExtraBuffer; @@ -42,9 +43,7 @@ private: protected: - uint32_t binding_count; - VkBuffer *buffer_list; - VkDeviceSize *buffer_offset; + VBOList * vbo_list; MaterialInstance * last_mi; Pipeline * last_pipeline; diff --git a/inc/hgl/graph/VKCommandBuffer.h b/inc/hgl/graph/VKCommandBuffer.h index 44d2b696..0216ed09 100644 --- a/inc/hgl/graph/VKCommandBuffer.h +++ b/inc/hgl/graph/VKCommandBuffer.h @@ -2,6 +2,7 @@ #define HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE #include +#include #include #include #include @@ -140,7 +141,7 @@ public: return(true); } - bool BindDescriptorSets(Renderable *ri); + bool BindDescriptorSets(Material *); bool PushDescriptorSet(VkPipelineLayout pipeline_layout,uint32_t set,uint32_t count,const VkWriteDescriptorSet *write_desc_set) { @@ -160,6 +161,17 @@ public: vkCmdBindVertexBuffers(cmd_buf,first,count,vbo,offsets); } + bool BindVBO(VBOList *vbo_list) + { + if(!vbo_list)return(false); + + if(!vbo_list->IsFull())return(false); + + vkCmdBindVertexBuffers(cmd_buf,0,vbo_list->binding_count,vbo_list->buffer_list,vbo_list->buffer_offset); + + return(true); + } + void BindIBO(const IndexBufferData *); bool BindVBO(Renderable *); diff --git a/inc/hgl/graph/VKVBOList.h b/inc/hgl/graph/VKVBOList.h new file mode 100644 index 00000000..6ffba531 --- /dev/null +++ b/inc/hgl/graph/VKVBOList.h @@ -0,0 +1,57 @@ +#pragma once + +VK_NAMESPACE_BEGIN +class VBOList +{ + uint32_t binding_count; + VkBuffer *buffer_list; + VkDeviceSize *buffer_offset; + + uint32_t write_count; + + friend class RenderCmdBuffer; + +public: + + VBOList(const uint32 bc) + { + binding_count=bc; + buffer_list=new VkBuffer[binding_count]; + buffer_offset=new VkDeviceSize[binding_count]; + + write_count=0; + } + + ~VBOList() + { + delete[] buffer_offset; + delete[] buffer_list; + } + + void Restart() + { + write_count=0; + } + + const bool IsFull()const + { + return write_count>=binding_count; + } + + void Add(const VkBuffer buf,const VkDeviceSize offset) + { + buffer_list[write_count]=buf; + buffer_offset[write_count]=offset; + + ++write_count; + } + + void Add(const VkBuffer *buf,const VkDeviceSize *offset,const uint32_t count) + { + hgl_cpy(buffer_list +write_count,buf, count); + hgl_cpy(buffer_offset+write_count,offset,count); + + write_count+=count; + } +};//class VBOList +VK_NAMESPACE_END diff --git a/inc/hgl/graph/mtl/UBOCommon.h b/inc/hgl/graph/mtl/UBOCommon.h index e22d3fb9..0dd30443 100644 --- a/inc/hgl/graph/mtl/UBOCommon.h +++ b/inc/hgl/graph/mtl/UBOCommon.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -42,6 +42,18 @@ constexpr const ShaderBufferSource SBS_CameraInfo= float znear,zfar;)" }; +// UBO必须严格指定数组的大小 +// SSBO则不需要,使用[]方式指定为动态大小数组 + +constexpr const ShaderBufferSource SBS_LocalToWorld= +{ + "LocalToWorldData", + "l2w", + + R"( + mat4 mats[L2W_MAX_COUNT];)" +}; + constexpr const char MaterialInstanceStruct[]="MaterialInstance"; constexpr const ShaderBufferSource SBS_MaterialInstanceData= diff --git a/inc/hgl/shadergen/MaterialCreateInfo.h b/inc/hgl/shadergen/MaterialCreateInfo.h index a09714d9..f8dbf411 100644 --- a/inc/hgl/shadergen/MaterialCreateInfo.h +++ b/inc/hgl/shadergen/MaterialCreateInfo.h @@ -13,6 +13,7 @@ namespace hgl{namespace graph { struct GPUDeviceAttribute; + struct UBODescriptor; namespace mtl { @@ -21,13 +22,20 @@ namespace hgl{namespace graph protected: const MaterialCreateConfig *config; + uint32_t ubo_range; + uint32_t ssbo_range; MaterialDescriptorInfo mdi; ///<材质描述符管理器 AnsiString mi_codes; ///GetVertexInput(); - - binding_count=vi->GetCount(); - buffer_list=new VkBuffer[binding_count]; - buffer_offset=new VkDeviceSize[binding_count]; + vbo_list=new VBOList(mtl->GetVertexInput()->GetCount()); } MaterialRenderList::~MaterialRenderList() { - delete[] buffer_offset; - delete[] buffer_list; - + SAFE_CLEAR(vbo_list); SAFE_CLEAR(extra_buffer) } @@ -180,6 +174,19 @@ void MaterialRenderList::Stat() void MaterialRenderList::Bind(MaterialInstance *mi) { + if(!mi)return; + + const VIL *vil=mi->GetVIL(); + + const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign); + + if(assign_binding_count>0) + { + mi->BindUBO(DescriptorSetType::PerFrame,"l2w",extra_buffer->assigns_l2w); +// mi->BindUBO(DescriptorSetType::PerFrame,"Assign",extra_buffer->assigns_mi); + } + + cmd_buf->BindDescriptorSets(mi->GetMaterial()); } bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index) @@ -191,83 +198,82 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index) if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count) return(false); //这里基本不太可能,因为CreateRenderable时就会检查值是否一样 - uint count=0; + vbo_list->Restart(); //Basic组,它所有的VBO信息均来自于Primitive,由vid参数传递进来 { - hgl_cpy(buffer_list,vid->buffer_list,vid->binding_count); - hgl_cpy(buffer_offset,vid->buffer_offset,vid->binding_count); - - count=vid->binding_count; + vbo_list->Add(vid->buffer_list,vid->buffer_offset,vid->binding_count); } - if(countGetCount(VertexInputGroup::MaterialInstanceID); + //if(!vbo_list.IsFull()) //Joint组,暂未支持 + //{ + // const uint joint_id_binding_count=vil->GetCount(VertexInputGroup::JointID); - if(mtl_binding_count>0) + // if(joint_id_binding_count>0) //有矩阵信息 + // { + // count+=joint_id_binding_count; + + // if(countGetCount(VertexInputGroup::JointWeight); + + // if(joing_weight_binding_count!=1) + // { + // ++count; + // } + // else //JointWieght不为1是个bug,除非未来支持8权重 + // { + // return(false); + // } + // } + // else //有JointID没有JointWeight? 这是个BUG + // { + // return(false); + // } + // } + //} + + //if(countGetCount(VertexInputGroup::LocalToWorld); + + // if(l2w_binding_count>0) //有变换矩阵信息 + // { + // if(l2w_binding_count!=4) + // return(false); + + // hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4); + + // for(uint i=0;i<4;i++) + // buffer_offset[count+i]=ri_index*16; //mat4每列都是rgba32f,自然是16字节 + + // count+=l2w_binding_count; + // } + //} + + if(!vbo_list->IsFull()) + { + const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign); + + if(assign_binding_count>0) { - if(mtl_binding_count!=1) //只有MaterialInstanceID + if(assign_binding_count!=1) return(false); - count+=mtl_binding_count; + vbo_list->Add(extra_buffer->assigns_vbo->GetBuffer(),extra_buffer->assigns_vbo_strip*ri_index); } } - if(countGetCount(VertexInputGroup::JointID); - if(joint_id_binding_count>0) //有矩阵信息 - { - count+=joint_id_binding_count; + //if(count!=binding_count) + //{ + // //还有没支持的绑定组???? - if(countGetCount(VertexInputGroup::JointWeight); + // return(false); + //} - if(joing_weight_binding_count!=1) - { - ++count; - } - else //JointWieght不为1是个bug,除非未来支持8权重 - { - return(false); - } - } - else //有JointID没有JointWeight? 这是个BUG - { - return(false); - } - } - } - - if(countGetCount(VertexInputGroup::LocalToWorld); - - if(l2w_binding_count>0) //有变换矩阵信息 - { - if(l2w_binding_count!=4) - return(false); - - hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4); - - for(uint i=0;i<4;i++) - buffer_offset[count+i]=ri_index*16; //mat4每列都是rgba32f,自然是16字节 - - count+=l2w_binding_count; - } - } - - if(count!=binding_count) - { - //还有没支持的绑定组???? - - return(false); - } - - cmd_buf->BindVBO(0,count,buffer_list,buffer_offset); + //cmd_buf->BindVBO(0,count,buffer_list,buffer_offset); + cmd_buf->BindVBO(vbo_list); return(true); } diff --git a/src/SceneGraph/RenderExtraBuffer.h b/src/SceneGraph/RenderExtraBuffer.h index 04e87793..c3e34460 100644 --- a/src/SceneGraph/RenderExtraBuffer.h +++ b/src/SceneGraph/RenderExtraBuffer.h @@ -41,6 +41,17 @@ struct RenderExtraBuffer VBO *l2w_vbo[4]; VkBuffer l2w_buffer[4]; +//------------------------------------------------------------ + + //Assign UBO + DeviceBuffer *assigns_l2w; + DeviceBuffer *assigns_mi; + + //Assign VBO + VBO *assigns_vbo; ///CreateVBO(VF_V4F,node_count); l2w_buffer[i]=l2w_vbo[i]->GetBuffer(); } + + assigns_l2w=dev->CreateUBO(node_count*sizeof(Matrix4f)); + //assigns_mi=dev->CreateUBO(node_count*sizeof(uint8)); + assigns_vbo=dev->CreateVBO(VF_V1U16,node_count); } //void MIAlloc(GPUDevice *dev,const uint c,const uint mis) @@ -108,22 +127,48 @@ public: void WriteLocalToWorld(RenderNode *render_node,const uint count) { RenderNode *rn; - glm::vec4 *tp; - for(uint col=0;col<4;col++) + //old l2w in vertex input stream { - tp=(glm::vec4 *)(l2w_vbo[col]->Map()); + glm::vec4 *tp; + + for(uint col=0;col<4;col++) + { + tp=(glm::vec4 *)(l2w_vbo[col]->Map()); + + rn=render_node; + + for(uint i=0;ilocal_to_world[col]; + ++tp; + ++rn; + } + + l2w_vbo[col]->Unmap(); + } + } + + //new l2w array in ubo + { + Matrix4f *tp=(hgl::Matrix4f *)(assigns_l2w->Map()); + uint16 *idp=(uint16 *)(assigns_vbo->Map()); rn=render_node; for(uint i=0;ilocal_to_world[col]; + *tp=rn->local_to_world; ++tp; + + *idp=i; + ++idp; + ++rn; } - l2w_vbo[col]->Unmap(); + assigns_vbo->Unmap(); + assigns_l2w->Unmap(); } } diff --git a/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp b/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp index 40019e0d..7b6c0aa1 100644 --- a/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp +++ b/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp @@ -101,15 +101,14 @@ bool RenderCmdBuffer::BeginRenderPass() return(true); } -bool RenderCmdBuffer::BindDescriptorSets(Renderable *ri) +bool RenderCmdBuffer::BindDescriptorSets(Material *mtl) { - if(!ri)return(false); + if(!mtl)return(false); { uint32_t count=0; MaterialParameters *mp; - Material *mtl=ri->GetMaterial(); VkDescriptorSet ds[DESCRIPTOR_SET_TYPE_COUNT]; ENUM_CLASS_FOR(DescriptorSetType,int,i) @@ -125,7 +124,7 @@ bool RenderCmdBuffer::BindDescriptorSets(Renderable *ri) if(count>0) { - pipeline_layout=ri->GetPipelineLayout(); + pipeline_layout=mtl->GetPipelineLayout(); vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,0,count,ds,0,0); } diff --git a/src/ShaderGen/2d/Std2DMaterial.cpp b/src/ShaderGen/2d/Std2DMaterial.cpp index da62a488..1831aa5f 100644 --- a/src/ShaderGen/2d/Std2DMaterial.cpp +++ b/src/ShaderGen/2d/Std2DMaterial.cpp @@ -20,7 +20,9 @@ bool Std2DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc) if(cfg->local_to_world) { - vsc->AddLocalToWorld(); + mci->SetLocalToWorld(VK_SHADER_STAGE_ALL_GRAPHICS); + + vsc->AddAssign(); vsc->AddFunction(func::GetPosition2DL2W[size_t(cfg->coordinate_system)]); } @@ -57,7 +59,7 @@ MaterialCreateInfo *Std2DMaterial::Create() if(!EndCustomShader()) return(false); - if(!mci->CreateShader(cfg->dev_attr)) + if(!mci->CreateShader()) return(nullptr); return(mci); diff --git a/src/ShaderGen/MaterialCreateInfo.cpp b/src/ShaderGen/MaterialCreateInfo.cpp index c25d2058..c19e4bc5 100644 --- a/src/ShaderGen/MaterialCreateInfo.cpp +++ b/src/ShaderGen/MaterialCreateInfo.cpp @@ -16,8 +16,25 @@ MaterialCreateInfo::MaterialCreateInfo(const MaterialCreateConfig *mc) if(hasGeometry ())shader_map.Add(geom=new ShaderCreateInfoGeometry(&mdi));else geom=nullptr; if(hasFragment ())shader_map.Add(frag=new ShaderCreateInfoFragment(&mdi));else frag=nullptr; - mi_data_bytes=0; - mi_shader_stage=0; + ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16k,nVidia和Mali-G系列除G71外为64k,Intel/PowerVR为128M,AMD无限制。 + ssbo_range=config->dev_attr->physical_device->GetSSBORange(); + + { + mi_data_bytes=0; + mi_shader_stage=0; + mi_max_count=0; + mi_ubo=nullptr; + } + + { + l2w_max_count=ubo_range/sizeof(Matrix4f); + + if(l2w_max_count>HGL_U16_MAX) + l2w_max_count=HGL_U16_MAX; + + l2w_shader_stage=0; + l2w_ubo=nullptr; + } } bool MaterialCreateInfo::AddStruct(const AnsiString &struct_name,const AnsiString &codes) @@ -141,25 +158,25 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const if(data_bytes>0) mi_codes=glsl_codes; - const uint32_t ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16k,nVidia和Mali-G系列除G71外为64k,Intel/PowerVR为128M,AMD无限制。 + { + mi_max_count=ubo_range/data_bytes; - mi_max_count=ubo_range/data_bytes; - - if(mi_max_count>256) //我们使用uint8传递材质实例ID,所以最大数量为256。未来如考虑使用更多,需综合考虑 - mi_max_count=256; - - const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count); + if(mi_max_count>HGL_U16_MAX) //我们使用uint16传递材质实例ID,所以最大数量为65535。未来如考虑使用更多,需综合考虑 + mi_max_count=HGL_U16_MAX; + } mdi.AddStruct(MaterialInstanceStruct,mi_codes); mdi.AddStruct(SBS_MaterialInstanceData); - UBODescriptor *ubo=new UBODescriptor(); + mi_ubo=new UBODescriptor(); - ubo->type=SBS_MaterialInstanceData.struct_name; - hgl::strcpy(ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstanceData.name); - ubo->stage_flag=shader_stage_flag_bits; + mi_ubo->type=SBS_MaterialInstanceData.struct_name; + hgl::strcpy(mi_ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstanceData.name); + mi_ubo->stage_flag=shader_stage_flag_bits; - mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,ubo); + mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,mi_ubo); + + const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count); auto *it=shader_map.GetDataList(); @@ -168,20 +185,52 @@ 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->SetMaterialInstance(ubo,mi_codes); + (*it)->value->SetMaterialInstance(mi_ubo,mi_codes); } ++it; } - vert->AddMaterialInstanceID(); //增加一个材质实例ID - mi_shader_stage=shader_stage_flag_bits; return(true); } -bool MaterialCreateInfo::CreateShader(const GPUDeviceAttribute *dev_attr) +bool MaterialCreateInfo::SetLocalToWorld(const uint32_t shader_stage_flag_bits) +{ + if(shader_stage_flag_bits==0)return(false); + + mdi.AddStruct(SBS_LocalToWorld); + + l2w_ubo=new UBODescriptor(); + + l2w_ubo->type=SBS_LocalToWorld.struct_name; + hgl::strcpy(l2w_ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_LocalToWorld.name); + l2w_ubo->stage_flag=shader_stage_flag_bits; + + mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerFrame,l2w_ubo); + + const AnsiString L2W_MAX_COUNT=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); + (*it)->value->SetLocalToWorld(l2w_ubo); + } + + ++it; + } + + l2w_shader_stage=shader_stage_flag_bits; + + return(true); +} + +bool MaterialCreateInfo::CreateShader() { if(shader_map.IsEmpty()) return(false); @@ -198,7 +247,11 @@ bool MaterialCreateInfo::CreateShader(const GPUDeviceAttribute *dev_attr) if(sc->GetShaderStage()AddOutput(VAT_UINT,VAN::MaterialInstanceID,Interpolation::Flat); - sc->AddFunction(mtl::func::HandoverMI); + + if(sc->GetShaderStage()==VK_SHADER_STAGE_VERTEX_BIT) + sc->AddFunction(mtl::func::HandoverMI_VS); + else + sc->AddFunction(mtl::func::HandoverMI); } sc->CreateShader(last); diff --git a/src/ShaderGen/ShaderCreateInfo.cpp b/src/ShaderGen/ShaderCreateInfo.cpp index 7067f807..2f05dc21 100644 --- a/src/ShaderGen/ShaderCreateInfo.cpp +++ b/src/ShaderGen/ShaderCreateInfo.cpp @@ -157,11 +157,20 @@ void ShaderCreateInfo::SetMaterialInstance(UBODescriptor *ubo,const AnsiString & { sdm->AddUBO(DescriptorSetType::PerMaterial,ubo); sdm->AddStruct(mtl::MaterialInstanceStruct); - AddFunction(mtl::func::GetMI); + + if(shader_stage==VK_SHADER_STAGE_VERTEX_BIT) + AddFunction(mtl::func::GetMI_VS); + else + AddFunction(mtl::func::GetMI); mi_codes=mi; } +void ShaderCreateInfo::SetLocalToWorld(UBODescriptor *ubo) +{ + sdm->AddUBO(DescriptorSetType::PerFrame,ubo); +} + bool ShaderCreateInfo::ProcInput(ShaderCreateInfo *last_sc) { if(!last_sc) diff --git a/src/ShaderGen/ShaderCreateInfoVertex.cpp b/src/ShaderGen/ShaderCreateInfoVertex.cpp index a5cdedff..c36f0d8a 100644 --- a/src/ShaderGen/ShaderCreateInfoVertex.cpp +++ b/src/ShaderGen/ShaderCreateInfoVertex.cpp @@ -31,27 +31,17 @@ int ShaderCreateInfoVertex::AddInput(const AnsiString &type,const AnsiString &na return AddInput(vat,name,input_rate,group); } -void ShaderCreateInfoVertex::AddMaterialInstanceID() -{ - AddInput(VAT_UINT, VAN::MaterialInstanceID,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::MaterialInstanceID); -} - void ShaderCreateInfoVertex::AddJoint() { AddInput(VAT_UVEC4, VAN::JointID, VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::JointID); AddInput(VAT_VEC4, VAN::JointWeight,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::JointWeight); } -void ShaderCreateInfoVertex::AddLocalToWorld() +void ShaderCreateInfoVertex::AddAssign() { - char name[]= "LocalToWorld_?"; + char name[]="Assign"; - for(uint i=0;i<4;i++) - { - name[sizeof(name)-2]='0'+i; - - AddInput(VAT_VEC4,name,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::LocalToWorld); - } + AddInput(VAT_UINT,name,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::Assign); AddFunction(mtl::func::GetLocalToWorld); } diff --git a/src/ShaderGen/common/MFCommon.h b/src/ShaderGen/common/MFCommon.h index d7afcc99..5026ff02 100644 --- a/src/ShaderGen/common/MFCommon.h +++ b/src/ShaderGen/common/MFCommon.h @@ -1,20 +1,51 @@ -#pragma once +#pragma once #include STD_MTL_NAMESPACE_BEGIN namespace func { +//C++端使用一个RG8UI或RGB16UI格式的顶点输入流来传递Assign数据,其中x为LocalToWorld ID,y为MaterialInstance ID + constexpr const char GetLocalToWorld[]=R"( mat4 GetLocalToWorld() { - return mat4(LocalToWorld_0, - LocalToWorld_1, - LocalToWorld_2, - LocalToWorld_3); + return l2w.mats[Assign.x]; } )"; + constexpr const char HandoverMI_VS[]=R"( +void HandoverMI() +{ + Output.MaterialInstanceID=Assign.y; +} +)"; + +constexpr const char HandoverMI[]=R"( +void HandoverMI() +{ + Output.MaterialInstanceID=Assign.y; +} +)"; + + constexpr const char GetMI_VS[]=R"( +MaterialInstance GetMI() +{ + return mtl.mi[Assign.y]; +} +)"; + +constexpr const char GetMI[]=R"( +MaterialInstance GetMI() +{ + return mtl.mi[Input.MaterialInstanceID]; +} +)"; + +// Joint数据分Joint ID和Joint Weight两部分 +// Joint ID是一个uvec4,在shader中为整数。在C++端可使用RGBA8UI或是RGBA16UI来传递。 +// Joint Weight是权重,在shader中为浮点。在C++端使用RGBA8或RGBA4来传递。 + constexpr const char GetJointMatrix[]=R"( mat4 GetJointMatrix() { @@ -23,20 +54,6 @@ mat4 GetJointMatrix() joint.mats[JointID.z]*JointWeight.z+ joint.mats[JointID.w]*JointWeight.w; } -)"; - - constexpr const char HandoverMI[]=R"( -void HandoverMI() -{ - Output.MaterialInstanceID=MaterialInstanceID; -} -)"; - - constexpr const char GetMI[]=R"( -MaterialInstance GetMI() -{ - return mtl.mi[Input.MaterialInstanceID]; -} )"; }//namespace func STD_MTL_NAMESPACE_END