diff --git a/Source/Engine/Content/Assets/Material.cpp b/Source/Engine/Content/Assets/Material.cpp index 79fd79041..34cae5ea4 100644 --- a/Source/Engine/Content/Assets/Material.cpp +++ b/Source/Engine/Content/Assets/Material.cpp @@ -101,9 +101,9 @@ bool Material::CanUseLightmap() const return _materialShader && _materialShader->CanUseLightmap(); } -bool Material::CanUseInstancing(InstancingHandler& handler) const +bool Material::CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { - return _materialShader && _materialShader->CanUseInstancing(handler); + return _materialShader && _materialShader->CanUseInstancing(renderContext, handler); } void Material::Bind(BindParameters& params) diff --git a/Source/Engine/Content/Assets/Material.h b/Source/Engine/Content/Assets/Material.h index cd2ae8e97..fb89a1c86 100644 --- a/Source/Engine/Content/Assets/Material.h +++ b/Source/Engine/Content/Assets/Material.h @@ -48,7 +48,7 @@ public: bool IsReady() const override; DrawPass GetDrawModes() const override; bool CanUseLightmap() const override; - bool CanUseInstancing(InstancingHandler& handler) const override; + bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const override; void Bind(BindParameters& params) override; // [ShaderAssetBase] diff --git a/Source/Engine/Content/Assets/MaterialInstance.cpp b/Source/Engine/Content/Assets/MaterialInstance.cpp index 8d142626e..febcd02cf 100644 --- a/Source/Engine/Content/Assets/MaterialInstance.cpp +++ b/Source/Engine/Content/Assets/MaterialInstance.cpp @@ -168,9 +168,9 @@ bool MaterialInstance::CanUseLightmap() const return _baseMaterial && _baseMaterial->CanUseLightmap(); } -bool MaterialInstance::CanUseInstancing(InstancingHandler& handler) const +bool MaterialInstance::CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { - return _baseMaterial && _baseMaterial->CanUseInstancing(handler); + return _baseMaterial && _baseMaterial->CanUseInstancing(renderContext, handler); } void MaterialInstance::Bind(BindParameters& params) diff --git a/Source/Engine/Content/Assets/MaterialInstance.h b/Source/Engine/Content/Assets/MaterialInstance.h index 606e93a63..df4ff1866 100644 --- a/Source/Engine/Content/Assets/MaterialInstance.h +++ b/Source/Engine/Content/Assets/MaterialInstance.h @@ -53,7 +53,7 @@ public: bool IsReady() const override; DrawPass GetDrawModes() const override; bool CanUseLightmap() const override; - bool CanUseInstancing(InstancingHandler& handler) const override; + bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const override; void Bind(BindParameters& params) override; protected: diff --git a/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp b/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp index 7b31a606e..ea052aa84 100644 --- a/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/DeferredMaterialShader.cpp @@ -26,10 +26,10 @@ bool DeferredMaterialShader::CanUseLightmap() const return true; } -bool DeferredMaterialShader::CanUseInstancing(InstancingHandler& handler) const +bool DeferredMaterialShader::CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { handler = { SurfaceDrawCallHandler::GetHash, SurfaceDrawCallHandler::CanBatch, }; - return _instanced; + return _instanced || renderContext.View.Pass == DrawPass::Depth; } void DeferredMaterialShader::Bind(BindParameters& params) diff --git a/Source/Engine/Graphics/Materials/DeferredMaterialShader.h b/Source/Engine/Graphics/Materials/DeferredMaterialShader.h index ebfd54ecb..8d5dde16f 100644 --- a/Source/Engine/Graphics/Materials/DeferredMaterialShader.h +++ b/Source/Engine/Graphics/Materials/DeferredMaterialShader.h @@ -77,7 +77,7 @@ public: // [MaterialShader] DrawPass GetDrawModes() const override; bool CanUseLightmap() const override; - bool CanUseInstancing(InstancingHandler& handler) const override; + bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const override; void Bind(BindParameters& params) override; void Unload() override; diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index f3924f431..f5897fc46 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -22,10 +22,11 @@ DrawPass ForwardMaterialShader::GetDrawModes() const return _drawModes; } -bool ForwardMaterialShader::CanUseInstancing(InstancingHandler& handler) const +bool ForwardMaterialShader::CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { handler = { SurfaceDrawCallHandler::GetHash, SurfaceDrawCallHandler::CanBatch, }; - return false; // TODO: support instancing when using ForwardShadingFeature + // TODO: support instancing when using ForwardShadingFeature + return renderContext.View.Pass == DrawPass::Depth; } void ForwardMaterialShader::Bind(BindParameters& params) diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.h b/Source/Engine/Graphics/Materials/ForwardMaterialShader.h index 6c7b3ad7d..353b36fc6 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.h +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.h @@ -71,7 +71,7 @@ public: public: // [MaterialShader] DrawPass GetDrawModes() const override; - bool CanUseInstancing(InstancingHandler& handler) const override; + bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const override; void Bind(BindParameters& params) override; void Unload() override; diff --git a/Source/Engine/Graphics/Materials/IMaterial.h b/Source/Engine/Graphics/Materials/IMaterial.h index 40d197ddb..80fffbbfb 100644 --- a/Source/Engine/Graphics/Materials/IMaterial.h +++ b/Source/Engine/Graphics/Materials/IMaterial.h @@ -126,9 +126,10 @@ public: /// /// Returns true if material can use draw calls instancing. /// + /// The rendering context. /// The output data for the instancing handling used to hash, batch and write draw calls. Valid only when function returns true. /// True if can use instancing, otherwise false. - virtual bool CanUseInstancing(InstancingHandler& handler) const + virtual bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { #if BUILD_DEBUG handler = { nullptr, nullptr }; diff --git a/Source/Engine/Renderer/Editor/LODPreview.cpp b/Source/Engine/Renderer/Editor/LODPreview.cpp index 2578dfc76..9a754f69a 100644 --- a/Source/Engine/Renderer/Editor/LODPreview.cpp +++ b/Source/Engine/Renderer/Editor/LODPreview.cpp @@ -32,7 +32,7 @@ bool LODPreviewMaterialShader::IsReady() const return _material && _material->IsReady(); } -bool LODPreviewMaterialShader::CanUseInstancing(InstancingHandler& handler) const +bool LODPreviewMaterialShader::CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { return false; } diff --git a/Source/Engine/Renderer/Editor/LODPreview.h b/Source/Engine/Renderer/Editor/LODPreview.h index 05fe022d1..5e2450993 100644 --- a/Source/Engine/Renderer/Editor/LODPreview.h +++ b/Source/Engine/Renderer/Editor/LODPreview.h @@ -32,7 +32,7 @@ public: const MaterialInfo& GetInfo() const override; GPUShader* GetShader() const override; bool IsReady() const override; - bool CanUseInstancing(InstancingHandler& handler) const override; + bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const override; DrawPass GetDrawModes() const override; void Bind(BindParameters& params) override; }; diff --git a/Source/Engine/Renderer/Editor/MaterialComplexity.cpp b/Source/Engine/Renderer/Editor/MaterialComplexity.cpp index eb4afc26c..cc4e34431 100644 --- a/Source/Engine/Renderer/Editor/MaterialComplexity.cpp +++ b/Source/Engine/Renderer/Editor/MaterialComplexity.cpp @@ -36,9 +36,9 @@ bool MaterialComplexityMaterialShader::WrapperShader::IsReady() const return MaterialAsset && MaterialAsset->IsReady(); } -bool MaterialComplexityMaterialShader::WrapperShader::CanUseInstancing(InstancingHandler& handler) const +bool MaterialComplexityMaterialShader::WrapperShader::CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const { - return MaterialAsset && MaterialAsset->CanUseInstancing(handler); + return MaterialAsset && MaterialAsset->CanUseInstancing(renderContext, handler); } DrawPass MaterialComplexityMaterialShader::WrapperShader::GetDrawModes() const diff --git a/Source/Engine/Renderer/Editor/MaterialComplexity.h b/Source/Engine/Renderer/Editor/MaterialComplexity.h index 17c168d9b..7072620bc 100644 --- a/Source/Engine/Renderer/Editor/MaterialComplexity.h +++ b/Source/Engine/Renderer/Editor/MaterialComplexity.h @@ -30,7 +30,7 @@ private: const MaterialInfo& GetInfo() const override; GPUShader* GetShader() const override; bool IsReady() const override; - bool CanUseInstancing(InstancingHandler& handler) const override; + bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const override; DrawPass GetDrawModes() const override; void Bind(BindParameters& params) override; }; diff --git a/Source/Engine/Renderer/GBufferPass.cpp b/Source/Engine/Renderer/GBufferPass.cpp index fd0b7987f..785aa970d 100644 --- a/Source/Engine/Renderer/GBufferPass.cpp +++ b/Source/Engine/Renderer/GBufferPass.cpp @@ -121,7 +121,7 @@ void DebugOverrideDrawCallsMaterial(const RenderContext& renderContext, IMateria return; PROFILE_CPU(); IMaterial::InstancingHandler handler; - const bool canUseInstancing = material->CanUseInstancing(handler); + const bool canUseInstancing = material->CanUseInstancing(renderContext, handler); const auto drawModes = material->GetDrawModes(); if (EnumHasAnyFlags(drawModes, DrawPass::GBuffer)) { diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index 782587a42..520548767 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -658,7 +658,7 @@ FORCE_INLINE void CalculateSortKey(const RenderContext& renderContext, DrawCall& uint32 distanceKey = RenderTools::ComputeDistanceSortKey(distance); uint32 material = GetHash(drawCall.Material); IMaterial::InstancingHandler handler; - if (drawCall.Material->CanUseInstancing(handler)) + if (drawCall.Material->CanUseInstancing(renderContext, handler)) handler.GetHash(drawCall, material); material = (material * 397) ^ drawCall.StencilValue; uint32 geoKey = (uint32)(471 * drawCall.WorldDeterminant); @@ -890,14 +890,14 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD int32 batchSize = 1; int32 instanceCount = drawCall.InstanceCount; IMaterial::InstancingHandler drawCallHandler, otherHandler; - if (instanceCount != 0 && drawCall.Material->CanUseInstancing(drawCallHandler)) + if (instanceCount != 0 && drawCall.Material->CanUseInstancing(renderContext, drawCallHandler)) { // Check the following draw calls sequence to merge them for (int32 j = i + 1; j < listSize; j++) { const DrawCall& other = drawCallsData[listData[j]]; const bool canBatch = - other.Material->CanUseInstancing(otherHandler) && + other.Material->CanUseInstancing(renderContext, otherHandler) && other.InstanceCount != 0 && drawCallHandler.CanBatch == otherHandler.CanBatch && drawCallHandler.CanBatch(drawCall, other, pass) &&