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) &&