Optimize shadows and depth rendering with instancing support for transparent shaders

This commit is contained in:
2026-05-04 15:12:40 +02:00
parent f7d8f36add
commit 6cc0edf0eb
15 changed files with 24 additions and 22 deletions
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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]
@@ -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)
@@ -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:
@@ -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)
@@ -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;
@@ -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)
@@ -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;
+2 -1
View File
@@ -126,9 +126,10 @@ public:
/// <summary>
/// Returns true if material can use draw calls instancing.
/// </summary>
/// <param name="renderContext">The rendering context.</param>
/// <param name="handler">The output data for the instancing handling used to hash, batch and write draw calls. Valid only when function returns true.</param>
/// <returns>True if can use instancing, otherwise false.</returns>
virtual bool CanUseInstancing(InstancingHandler& handler) const
virtual bool CanUseInstancing(const RenderContext& renderContext, InstancingHandler& handler) const
{
#if BUILD_DEBUG
handler = { nullptr, nullptr };
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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;
};
@@ -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
@@ -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;
};
+1 -1
View File
@@ -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))
{
+3 -3
View File
@@ -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) &&