git.s-ol.nu ~forks/DiligentFX / 2ebdcae
GLTF PBR renderer: moved joint transforms into a separate buffer assiduous 10 months ago
6 changed file(s) with 78 addition(s) and 90 deletion(s). Raw diff Collapse all Expand all
9797
9898 /// Immutable sampler for emissive map texture.
9999 SamplerDesc EmissiveMapImmutableSampler = DefaultSampler;
100
101 /// Maximum number of joints
102 Uint32 MaxJointCount = 64;
100103 };
101104
102105 /// Initializes the renderer
179182 /// GLTF material
180183 const GLTF::Material* pMaterial = nullptr;
181184
182 /// GLTF node shader transforms
183 GLTFNodeShaderTransforms ShaderTransforms;
184
185 /// GLTF material shader information
186 GLTF::Material::ShaderAttribs MaterialShaderInfo;
185 /// GLTF node transforms
186 const GLTF::Mesh::TransformData* pTransformData = nullptr;
187187
188188 /// Index type for indexed primitives, or VT_UNDEFINED for non-indexed ones
189189 VALUE_TYPE IndexType = VT_UNDEFINED;
379379 RefCntAutoPtr<IBuffer> m_TransformsCB;
380380 RefCntAutoPtr<IBuffer> m_GLTFAttribsCB;
381381 RefCntAutoPtr<IBuffer> m_PrecomputeEnvMapAttribsCB;
382 RefCntAutoPtr<IBuffer> m_JointsBuffer;
382383
383384 struct GLTFNodeRenderer
384385 {
128128 CreateUniformBuffer(pDevice, sizeof(GLTFNodeShaderTransforms), "GLTF node transforms CB", &m_TransformsCB);
129129 CreateUniformBuffer(pDevice, sizeof(GLTFMaterialShaderInfo) + sizeof(GLTFRendererShaderParameters), "GLTF attribs CB", &m_GLTFAttribsCB);
130130
131 {
132 BufferDesc BuffDesc;
133 BuffDesc.Name = "GLTF joint tranforms";
134 BuffDesc.Usage = USAGE_DEFAULT;
135 BuffDesc.uiSizeInBytes = sizeof(float4x4) * m_Settings.MaxJointCount;
136 BuffDesc.BindFlags = BIND_SHADER_RESOURCE;
137 BuffDesc.Mode = BUFFER_MODE_STRUCTURED;
138 BuffDesc.ElementByteStride = sizeof(float4x4);
139 pDevice->CreateBuffer(BuffDesc, nullptr, &m_JointsBuffer);
140 }
141
131142 // clang-format off
132143 StateTransitionDesc Barriers[] =
133144 {
134145 {m_TransformsCB, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, true},
135 {m_GLTFAttribsCB, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, true}
146 {m_GLTFAttribsCB, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, true},
147 {m_JointsBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, true}
136148 };
137149 // clang-format on
138150 pCtx->TransitionResourceStates(_countof(Barriers), Barriers);
238250 ShaderCI.pShaderSourceStreamFactory = &DiligentFXShaderSourceStreamFactory::GetInstance();
239251
240252 ShaderMacroHelper Macros;
241 Macros.AddShaderMacro("MAX_NUM_JOINTS", Uint32{GLTF::Mesh::TransformData::MaxNumJoints});
242253 Macros.AddShaderMacro("ALLOW_DEBUG_VIEW", m_Settings.AllowDebugView);
243254 Macros.AddShaderMacro("TONE_MAPPING_MODE", "TONE_MAPPING_MODE_UNCHARTED2");
244255 Macros.AddShaderMacro("GLTF_PBR_USE_IBL", m_Settings.UseIBL);
286297 std::vector<ShaderResourceVariableDesc> Vars =
287298 {
288299 {SHADER_TYPE_VERTEX, "cbTransforms", SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
289 {SHADER_TYPE_PIXEL, "cbGLTFAttribs", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}
300 {SHADER_TYPE_PIXEL, "cbGLTFAttribs", SHADER_RESOURCE_VARIABLE_TYPE_STATIC},
301 {SHADER_TYPE_VERTEX, "g_Joints", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}
290302 };
291303 // clang-format on
292304
381393 // clang-format off
382394 PSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "cbTransforms")->Set(m_TransformsCB);
383395 PSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbGLTFAttribs")->Set(m_GLTFAttribsCB);
396 PSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "g_Joints")->Set(m_JointsBuffer->GetDefaultView(BUFFER_VIEW_SHADER_RESOURCE));
384397 // clang-format on
385398 }
386399 }
753766 if (primitive->material.AlphaMode != AlphaMode)
754767 continue;
755768
756 GLTFNodeRenderInfo NodeRI;
757
758 IShaderResourceBinding* pSRB = nullptr;
759
760769 const auto& material = primitive->material;
761770 if (RenderNodeCallback == nullptr)
762771 {
764773 VERIFY_EXPR(pPSO != nullptr);
765774 pCtx->SetPipelineState(pPSO);
766775
767 pSRB = Renderer.GetMaterialSRB(&material, SRBTypeId);
776 auto* pSRB = Renderer.GetMaterialSRB(&material, SRBTypeId);
768777 if (pSRB == nullptr)
769778 {
770779 LOG_ERROR_MESSAGE("Unable to find SRB for GLTF material. Please call GLTF_PBR_Renderer::InitializeResourceBindings()");
771780 continue;
772781 }
773782 pCtx->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
774 }
775 else
776 {
777 NodeRI.pMaterial = &material;
778 }
779
780 {
781 GLTFNodeShaderTransforms* pTransforms = nullptr;
782 if (RenderNodeCallback == nullptr)
783
784 size_t JointCount = Node._Mesh->Transforms.jointMatrices.size();
785 if (JointCount > Renderer.m_Settings.MaxJointCount)
783786 {
784 pCtx->MapBuffer(Renderer.m_TransformsCB, MAP_WRITE, MAP_FLAG_DISCARD, reinterpret_cast<PVoid&>(pTransforms));
787 LOG_WARNING_MESSAGE("The number of joints in the mesh (", JointCount, ") exceeds the maximum number (", Renderer.m_Settings.MaxJointCount,
788 ") reserved in the buffer. Increase MaxJointCount when initializing the renderer.");
789 JointCount = Renderer.m_Settings.MaxJointCount;
785790 }
786 else
791
787792 {
788 pTransforms = &NodeRI.ShaderTransforms;
793 MapHelper<GLTFNodeShaderTransforms> pTransforms{pCtx, Renderer.m_TransformsCB, MAP_WRITE, MAP_FLAG_DISCARD};
794 pTransforms->NodeMatrix = Node._Mesh->Transforms.matrix * RenderParams.ModelTransform;
795 pTransforms->JointCount = static_cast<int>(JointCount);
789796 }
790797
791 pTransforms->NodeMatrix = Node._Mesh->Transforms.matrix * RenderParams.ModelTransform;
792 pTransforms->JointCount = Node._Mesh->Transforms.jointcount;
793 if (Node._Mesh->Transforms.jointcount != 0)
798 if (JointCount != 0)
794799 {
795 static_assert(sizeof(pTransforms->JointMatrix) == sizeof(Node._Mesh->Transforms.jointMatrix), "Incosistent sizes");
796 memcpy(pTransforms->JointMatrix, Node._Mesh->Transforms.jointMatrix, sizeof(Node._Mesh->Transforms.jointMatrix));
800 // TODO: rework as dynamic buffer - need to map it every frame before the first use
801 pCtx->UpdateBuffer(Renderer.m_JointsBuffer, 0, static_cast<Uint32>(JointCount * sizeof(float4x4)), Node._Mesh->Transforms.jointMatrices.data(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
802 StateTransitionDesc Barrier{Renderer.m_JointsBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, true};
803 pCtx->TransitionResourceStates(1, &Barrier);
797804 }
798805
799 if (RenderNodeCallback == nullptr)
800 {
801 pCtx->UnmapBuffer(Renderer.m_TransformsCB, MAP_WRITE);
802 }
803 }
804
805 {
806 GLTF::Material::ShaderAttribs* pMaterialAttribs = nullptr;
807 if (RenderNodeCallback == nullptr)
808806 {
809807 struct GLTFAttribs
810808 {
816814 static_assert(sizeof(GLTFAttribs) <= 256, "Size of dynamic GLTFAttribs buffer exceeds 256 bytes. "
817815 "It may be worth trying to reduce the size or just live with it.");
818816
819 GLTFAttribs* pGLTFAttribs = nullptr;
820 pCtx->MapBuffer(Renderer.m_GLTFAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD, reinterpret_cast<PVoid&>(pGLTFAttribs));
821 pMaterialAttribs = &pGLTFAttribs->MaterialInfo;
817 MapHelper<GLTFAttribs> pGLTFAttribs{pCtx, Renderer.m_GLTFAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD};
818
819 pGLTFAttribs->MaterialInfo = material.Attribs;
822820
823821 auto& ShaderParams = pGLTFAttribs->RenderParameters;
824822
831829 ShaderParams.IBLScale = Renderer.m_RenderParams.IBLScale;
832830 ShaderParams.PrefilteredCubeMipLevels = Renderer.m_Settings.UseIBL ? static_cast<float>(Renderer.m_pPrefilteredEnvMapSRV->GetTexture()->GetDesc().MipLevels) : 0.f;
833831 }
834 else
832
833 if (primitive->hasIndices)
835834 {
836 pMaterialAttribs = &NodeRI.MaterialShaderInfo;
837 }
838
839 *pMaterialAttribs = material.Attribs;
840
841 if (RenderNodeCallback == nullptr)
842 {
843 pCtx->UnmapBuffer(Renderer.m_GLTFAttribsCB, MAP_WRITE);
844 }
845 }
846
847 if (primitive->hasIndices)
848 {
849 if (RenderNodeCallback == nullptr)
850 {
851 DrawIndexedAttribs drawAttrs(primitive->IndexCount, VT_UINT32, DRAW_FLAG_VERIFY_ALL);
835 DrawIndexedAttribs drawAttrs{primitive->IndexCount, VT_UINT32, DRAW_FLAG_VERIFY_ALL};
852836 drawAttrs.FirstIndexLocation = FirstIndexLocation + primitive->FirstIndex;
853837 drawAttrs.BaseVertex = BaseVertex;
854838 pCtx->DrawIndexed(drawAttrs);
855839 }
856840 else
857841 {
858 NodeRI.IndexType = VT_UINT32;
859 NodeRI.IndexCount = primitive->IndexCount;
860 NodeRI.FirstIndex = FirstIndexLocation + primitive->FirstIndex;
861 NodeRI.BaseVertex = BaseVertex;
862 RenderNodeCallback(NodeRI);
842 DrawAttribs drawAttrs{primitive->VertexCount, DRAW_FLAG_VERIFY_ALL};
843 drawAttrs.StartVertexLocation = BaseVertex;
844 pCtx->Draw(drawAttrs);
863845 }
864846 }
865847 else
866848 {
867 if (RenderNodeCallback == nullptr)
849 GLTFNodeRenderInfo NodeRI;
850 NodeRI.pMaterial = &material;
851 NodeRI.pTransformData = &Node._Mesh->Transforms;
852 NodeRI.IndexType = primitive->hasIndices ? VT_UINT32 : VT_UNDEFINED;
853 NodeRI.BaseVertex = BaseVertex;
854
855 if (primitive->hasIndices)
868856 {
869 DrawAttribs drawAttrs(primitive->VertexCount, DRAW_FLAG_VERIFY_ALL);
870 drawAttrs.StartVertexLocation = BaseVertex;
871 pCtx->Draw(drawAttrs);
857 NodeRI.IndexCount = primitive->IndexCount;
858 NodeRI.FirstIndex = FirstIndexLocation + primitive->FirstIndex;
872859 }
873860 else
874861 {
875 NodeRI.IndexType = VT_UNDEFINED;
876862 NodeRI.VertexCount = primitive->VertexCount;
877 NodeRI.FirstIndex = 0;
878 NodeRI.BaseVertex = BaseVertex;
879 RenderNodeCallback(NodeRI);
880863 }
864
865 RenderNodeCallback(NodeRI);
881866 }
882867 }
883868 }
1919 {
2020 GLTFNodeShaderTransforms g_Transforms;
2121 }
22
23 struct JointTransform
24 {
25 float4x4 Matrix;
26 };
27 StructuredBuffer<JointTransform> g_Joints;
2228
2329 void main(in GLTF_VS_Input VSIn,
2430 out float4 ClipPos : SV_Position,
3541 {
3642 // Mesh is skinned
3743 float4x4 SkinMat =
38 VSIn.Weight0.x * g_Transforms.JointMatrix[int(VSIn.Joint0.x)] +
39 VSIn.Weight0.y * g_Transforms.JointMatrix[int(VSIn.Joint0.y)] +
40 VSIn.Weight0.z * g_Transforms.JointMatrix[int(VSIn.Joint0.z)] +
41 VSIn.Weight0.w * g_Transforms.JointMatrix[int(VSIn.Joint0.w)];
44 VSIn.Weight0.x * g_Joints[int(VSIn.Joint0.x)].Matrix +
45 VSIn.Weight0.y * g_Joints[int(VSIn.Joint0.y)].Matrix +
46 VSIn.Weight0.z * g_Joints[int(VSIn.Joint0.z)].Matrix +
47 VSIn.Weight0.w * g_Joints[int(VSIn.Joint0.w)].Matrix;
4248 Transform = mul(Transform, SkinMat);
4349 }
4450
1111
1212 #endif
1313
14 #ifndef MAX_NUM_JOINTS
15 # define MAX_NUM_JOINTS 128u
16 #endif
17
1814 #ifndef PBR_WORKFLOW_METALLIC_ROUGHNESS
1915 # define PBR_WORKFLOW_METALLIC_ROUGHNESS 0
2016 #endif
2622 struct GLTFNodeShaderTransforms
2723 {
2824 float4x4 NodeMatrix;
29 float4x4 JointMatrix[MAX_NUM_JOINTS];
3025
3126 int JointCount;
3227 float Dummy0;
1111 "\n"
1212 "#endif\n"
1313 "\n"
14 "#ifndef MAX_NUM_JOINTS\n"
15 "# define MAX_NUM_JOINTS 128u\n"
16 "#endif\n"
17 "\n"
1814 "#ifndef PBR_WORKFLOW_METALLIC_ROUGHNESS\n"
1915 "# define PBR_WORKFLOW_METALLIC_ROUGHNESS 0\n"
2016 "#endif\n"
2622 "struct GLTFNodeShaderTransforms\n"
2723 "{\n"
2824 " float4x4 NodeMatrix;\n"
29 " float4x4 JointMatrix[MAX_NUM_JOINTS];\n"
3025 "\n"
3126 " int JointCount;\n"
3227 " float Dummy0;\n"
1919 "{\n"
2020 " GLTFNodeShaderTransforms g_Transforms;\n"
2121 "}\n"
22 "\n"
23 "struct JointTransform\n"
24 "{\n"
25 " float4x4 Matrix;\n"
26 "};\n"
27 "StructuredBuffer<JointTransform> g_Joints;\n"
2228 " \n"
2329 "void main(in GLTF_VS_Input VSIn,\n"
2430 " out float4 ClipPos : SV_Position,\n"
3541 " {\n"
3642 " // Mesh is skinned\n"
3743 " float4x4 SkinMat = \n"
38 " VSIn.Weight0.x * g_Transforms.JointMatrix[int(VSIn.Joint0.x)] +\n"
39 " VSIn.Weight0.y * g_Transforms.JointMatrix[int(VSIn.Joint0.y)] +\n"
40 " VSIn.Weight0.z * g_Transforms.JointMatrix[int(VSIn.Joint0.z)] +\n"
41 " VSIn.Weight0.w * g_Transforms.JointMatrix[int(VSIn.Joint0.w)];\n"
44 " VSIn.Weight0.x * g_Joints[int(VSIn.Joint0.x)].Matrix +\n"
45 " VSIn.Weight0.y * g_Joints[int(VSIn.Joint0.y)].Matrix +\n"
46 " VSIn.Weight0.z * g_Joints[int(VSIn.Joint0.z)].Matrix +\n"
47 " VSIn.Weight0.w * g_Joints[int(VSIn.Joint0.w)].Matrix;\n"
4248 " Transform = mul(Transform, SkinMat);\n"
4349 " }\n"
4450 "\n"