Optimize shadows and depth rendering with instancing support for transparent shaders
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
Reference in New Issue
Block a user