From 7c3d9ecf9141ee48946ee6bb7ff57555e8558a54 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 9 May 2023 22:03:02 +0800 Subject: [PATCH] added MIData at Material --- CMSceneGraph | 2 +- inc/hgl/graph/VKMaterial.h | 28 +++++++- inc/hgl/graph/VKMaterialInstance.h | 77 +++++++++++++--------- inc/hgl/graph/mtl/StdMaterial.h | 20 ++++++ inc/hgl/shadergen/ShaderCreateInfoVertex.h | 14 ++-- src/SceneGraph/RenderNode.cpp | 40 +++++++++-- src/SceneGraph/Vulkan/VKDeviceMaterial.cpp | 13 ++++ src/SceneGraph/Vulkan/VKMaterial.cpp | 8 +++ 8 files changed, 153 insertions(+), 49 deletions(-) diff --git a/CMSceneGraph b/CMSceneGraph index 93a4792a..bc0f03e2 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 93a4792af52181fdf30f0573e2a5190f61c10b61 +Subproject commit bc0f03e2ba281ec30a331c3d0490e45797da8b17 diff --git a/inc/hgl/graph/VKMaterial.h b/inc/hgl/graph/VKMaterial.h index 354d95a6..8785dde6 100644 --- a/inc/hgl/graph/VKMaterial.h +++ b/inc/hgl/graph/VKMaterial.h @@ -27,6 +27,9 @@ struct MaterialData MaterialParameterArray mp_array; + uint8 *mi_data; ///<材质实例数据区 + uint32_t mi_size; ///<单个材质实例数据长度 + private: friend class Material; @@ -42,6 +45,8 @@ class Material { MaterialData *data; + uint32_t mi_count; ///<材质数量 + private: friend GPUDevice; @@ -50,8 +55,8 @@ private: public: - Material(MaterialData *md):data(md){} - ~Material(); + Material(MaterialData *); + virtual ~Material(); const UTF8String & GetName ()const{return data->name;} @@ -63,6 +68,25 @@ public: const VkPipelineLayout GetPipelineLayout ()const; const PipelineLayoutData * GetPipelineLayoutData ()const{return data->pipeline_layout_data;} +public: + + const uint32_t GetMICount ()const{return mi_count;} + const uint32_t GetMISize ()const{return mi_size;} + const void * GetMIData ()const{return data->mi_data;} + + template + T * GetMIData (const uint32_t index)const{return data->mi_data?(T *)(data->mi_data+index*mi_size):nullptr;} + + template + bool WriteMIData (const uint32_t index,const T *data) + { + if(!data->mi_data)return(false); + if(index>=mi_count)return(false); + + memcpy(mi_data+index*mi_size,data,mi_size); + return(true); + } + public: MaterialParameters * GetMP (const DescriptorSetType &type) diff --git a/inc/hgl/graph/VKMaterialInstance.h b/inc/hgl/graph/VKMaterialInstance.h index 156c6d90..4421870d 100644 --- a/inc/hgl/graph/VKMaterialInstance.h +++ b/inc/hgl/graph/VKMaterialInstance.h @@ -5,48 +5,53 @@ VK_NAMESPACE_BEGIN -/* - layout(location=0) in vec4 Position; - layout(location=1) in vec3 Normal; - - layout(location=?) in uint MaterialID - - #define MI_MAX_COUNT ??? //该值由引擎根据 UBORange/sizeof(MaterialInstance) 计算出来 - - struct MaterialInstance //这部分数据,即为材质实例的具体数据,每一个材质实例类负责提供具体数据。由RenderList合并成一整个UBO - { - vec4 BaseColor; - vec4 Emissive; - vec4 ARM; - }; - - layout(set=?,binding=?) uniform Material - { - MaterialInstance mi[MI_MAX_COUNT] - }mtl; - - void main() - { - MaterialInstance mi=mtl.mi[(MaterialID>=MI_MAX_COUNT)?:0:MaterialID]; //如果超出范围则使用0号材质实例数据 - - vec4 BaseColor =mi.BaseColor; - vec4 Emissive =mi.Emissive; - - float AO =mi.ARM.x; - float Roughness =mi.ARM.y; - float Metallic =mi.ARM.z; - +/** +* +* +* layout(location=?) in uint MaterialID +* +* #define MI_MAX_COUNT ??? //该值由引擎根据 UBORange/sizeof(MaterialInstance) 计算出来 +* +* struct MaterialInstance //这部分数据,即为材质实例的具体数据,每一个材质实例类负责提供具体数据。由RenderList合并成一整个UBO +* { //该类数据,由DescriptorSetType为PerMaterial的参数构成 +* vec4 BaseColor; +* vec4 Emissive; +* vec4 ARM; +* }; +* +* layout(set=?,binding=?) uniform Material +* { +* MaterialInstance mi[MI_MAX_COUNT] +* }mtl; +* +* void main() +* { +* MaterialInstance mi=mtl.mi[(MaterialID>=MI_MAX_COUNT)?:0:MaterialID]; //如果超出范围则使用0号材质实例数据 +* +* vec4 BaseColor =mi.BaseColor; +* vec4 Emissive =mi.Emissive; +* +* float AO =mi.ARM.x; +* float Roughness =mi.ARM.y; +* float Metallic =mi.ARM.z; +* +* */ /** -* 材质实例类 +* 材质实例类
+* 材质实例类本质只是提供一个数据区,供RenderList合并成一个大UBO。 */ class MaterialInstance { +protected: + Material *material; VIL *vil; + uint8 mi_id; //材质实例ID + private: friend class GPUDevice; @@ -59,6 +64,14 @@ public: Material *GetMaterial(){return material;} + const uint8_t GetID()const{return mi_id;} ///<获取材质实例ID + + template + T *GetData(){return material->GetMIData(mi_id);} ///<获取材质实例数据 + + template + bool WriteData(const T *data){return material->WriteMIData(mi_id,data);} ///<写入材质实例数据 + const VIL *GetVIL()const{return vil;} MaterialParameters *GetMP(const DescriptorSetType &type){return material->GetMP(type);} diff --git a/inc/hgl/graph/mtl/StdMaterial.h b/inc/hgl/graph/mtl/StdMaterial.h index 045135f7..64fcc48a 100644 --- a/inc/hgl/graph/mtl/StdMaterial.h +++ b/inc/hgl/graph/mtl/StdMaterial.h @@ -57,6 +57,16 @@ vec3 world_up; float znear,zfar;)" }; +constexpr const ShaderBufferSource SBS_BoneInfo= +{ + "BoneInfo", + "bone", + +R"( + mat4 bone_mats[]; +)" +}; + namespace func { constexpr const char GetLocalToWorld[]=R"( @@ -67,6 +77,16 @@ mat4 GetLocalToWorld() LocalToWorld_2, LocalToWorld_3); } +)"; + + constexpr const char GetBoneMatrix[]=R"( +mat4 GetBoneMatrix() +{ + return bone_mats[BoneID.x]*BoneWeight.x+ + bone_mats[BoneID.y]*BoneWeight.y+ + bone_mats[BoneID.z]*BoneWeight.z+ + bone_mats[BoneID.w]*BoneWeight.w; +} )"; }//namespace func STD_MTL_NAMESPACE_END diff --git a/inc/hgl/shadergen/ShaderCreateInfoVertex.h b/inc/hgl/shadergen/ShaderCreateInfoVertex.h index 872aa284..136b7ef2 100644 --- a/inc/hgl/shadergen/ShaderCreateInfoVertex.h +++ b/inc/hgl/shadergen/ShaderCreateInfoVertex.h @@ -21,23 +21,23 @@ namespace hgl void AddMaterialID() { - VAT vat{VertexAttribType::BaseType::UInt,1}; //使用uint16 + constexpr const VAT vat{VertexAttribType::BaseType::UInt,1}; //使用uint8 - AddInput(vat,VAN::MaterialID,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::Material); + AddInput(vat,VAN::MaterialID,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::MaterialID); } void AddBone() { - VAT id {VertexAttribType::BaseType::UInt,4}; //使用uint8[4] - VAT weight {VertexAttribType::BaseType::Float,4}; //使用uint8[4] + constexpr const VAT id {VertexAttribType::BaseType::UInt,4}; //使用uint8[4] + constexpr const VAT weight {VertexAttribType::BaseType::Float,4}; //使用uint8[4] - AddInput(id, VAN::BoneID, VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::Bone); - AddInput(weight,VAN::BoneWeight,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::Bone); + AddInput(id, VAN::BoneID, VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::BoneID); + AddInput(weight,VAN::BoneWeight,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::BoneWeight); } void AddLocalToWorld() { - VAT vat{VertexAttribType::BaseType::Float,4}; //使用float[4] + constexpr const VAT vat{VertexAttribType::BaseType::Float,4}; //使用float[4] char name[]= "LocalToWorld_?"; diff --git a/src/SceneGraph/RenderNode.cpp b/src/SceneGraph/RenderNode.cpp index b07bddd1..79d4bf54 100644 --- a/src/SceneGraph/RenderNode.cpp +++ b/src/SceneGraph/RenderNode.cpp @@ -65,6 +65,12 @@ namespace hgl { uint count; + VBO *mi_id; + VkBuffer *mi_id_buffer; + + VBO *bone_id,*bone_weight; + VkBuffer bone_id_buffer,bone_weight_buffer; + VBO *l2w_vbo[4]; VkBuffer l2w_buffer[4]; @@ -82,6 +88,11 @@ namespace hgl void Clear() { + SAFE_CLEAR(mi_id) + + SAFE_CLEAR(bone_id) + SAFE_CLEAR(bone_weight) + SAFE_CLEAR(l2w_vbo[0]) SAFE_CLEAR(l2w_vbo[1]) SAFE_CLEAR(l2w_vbo[2]) @@ -262,7 +273,7 @@ namespace hgl if(countGetCount(VertexInputGroup::Material); + const uint mtl_binding_count=vil->GetCount(VertexInputGroup::MaterialID); if(mtl_binding_count>0) { @@ -273,16 +284,31 @@ namespace hgl } } - if(countGetCount(VertexInputGroup::Bone); + const uint boneId_binding_count=vil->GetCount(VertexInputGroup::BoneID); - if(bone_binding_count>0) //有骨骼矩阵信息 + if(boneId_binding_count>0) //有骨骼矩阵信息 { - if(bone_binding_count!=2) //只有BoneID/BondWeight,,,不是2的话根本就不对 - return(false); + count+=boneId_binding_count; - count+=bone_binding_count; + if(countGetCount(VertexInputGroup::BoneWeight); + + if(boneWeight_binding_count!=1) + { + ++count; + } + else //BoneWieght不为1是个bug,除非未来支持8骨骼权重 + { + return(false); + } + } + else //有BoneID没有BoneWeight? 这是个BUG + { + return(false); + } } } diff --git a/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp b/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp index 1023a3da..f1aedfa3 100644 --- a/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp @@ -117,6 +117,19 @@ Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,ShaderModuleMap * else hgl_zero(data->mp_array); + const VkDeviceSize ubo_range=this->GetUBORange(); + + if(desc_manager->hasSet(DescriptorSetType::PerMaterial)) + { + data->mi_data=new uint8[ubo_range]; + data->mi_size + } + else + { + data->mi_data=nullptr; + data->mi_size=0; + } + return(new Material(data)); } VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMaterial.cpp b/src/SceneGraph/Vulkan/VKMaterial.cpp index 61100181..d86c9de1 100644 --- a/src/SceneGraph/Vulkan/VKMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKMaterial.cpp @@ -16,8 +16,16 @@ MaterialData::~MaterialData() delete vertex_input; } +Material::Material(MaterialData *md):data(md) +{ + mi_size=0; + mi_count=0; +} + Material::~Material() { + delete[] data->mi_data; + delete data->pipeline_layout_data; delete data; }